AI & Computer Vision, lesson 2 of 52

Python & OpenCV: Set Up Your Computer-Vision Workshop

beginner14 min read

Introduction

In lesson 1 you saw that a picture is just a grid of numbers. Today you get your hands on those numbers. You'll set up Python on your laptop, install OpenCV (the most widely used computer-vision library), and write a program that shows your webcam live, with a frame counter and a banner drawn on top.

Every project in this course starts from the code you write today, so take it slowly and make sure each step works before moving on.

By the end of this lesson you'll be able to:

  • make a virtual environment and install packages into it with pip
  • point VS Code at that environment
  • open your webcam from Python and show it in a window
  • draw text and shapes on every frame
  • measure how many frames per second (FPS) your camera gives you
  • close the camera properly when you quit

Each project has its own venv, so each keeps the version it needs. Your prompt shows (venv) when it's switched on.

Working principle

Virtual environments

A virtual environment (or venv) is a private copy of Python just for one project. Without one, every project shares the same packages, and sooner or later two projects need different versions of the same package. Those clashes are very hard to fix.

The rule for this course: one project, one virtual environment. When it's switched on, your terminal prompt starts with (venv).

WindowsmacOS and Linux
Createpython -m venv venvpython3 -m venv venv
Switch on.\venv\Scripts\activatesource venv/bin/activate
Switch offdeactivatedeactivate

pip

pip downloads Python packages from the internet (from PyPI, the Python Package Index). Only use it when (venv) is in your prompt, so packages land in your project and not in your whole computer.

pip install opencv-python numpy matplotlib   # the packages for this unit
pip freeze > requirements.txt                # write down what you installed
pip install -r requirements.txt              # rebuild the same set on another laptop

The webcam loop

A video is just pictures shown quickly, one after another. So every live computer-vision program is a loop: grab a frame, do something with it, show it, repeat.

import cv2
 
cap = cv2.VideoCapture(0)      # open webcam number 0 (try 1 or 2 if you have more than one)
 
while True:
    ret, frame = cap.read()    # ret: did it work?  frame: the picture, shape (height, width, 3)
    if not ret:
        break
 
    cv2.imshow("Webcam feed", frame)
 
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break                  # press Q to quit
 
cap.release()
cv2.destroyAllWindows()
LineWhat it does
cv2.VideoCapture(0)Opens the webcam. cap.isOpened() tells you if it worked.
cap.read()Grabs the next frame. If the camera disconnects, ret becomes False, so always check it.
cv2.imshow("title", frame)Shows the frame in a window with that title.
cv2.waitKey(1)Waits 1 millisecond for a key press. This is also what lets the window redraw, so the loop needs it.
cap.release()Gives the camera back to your computer. Without it, the camera stays locked.
cv2.destroyAllWindows()Closes the windows.

A video is pictures shown quickly. The loop goes round about 30 times a second. Here it's slowed right down.

Drawing on a frame

You draw straight onto the frame before you show it. Every label, box and alert in this course is drawn like this.

cv2.putText(
    frame,
    "Hello, CV!",
    (30, 50),                    # where: x, y in pixels from the top-left corner
    cv2.FONT_HERSHEY_SIMPLEX,    # the font
    1.2,                         # size
    (0, 255, 0),                 # colour: green
    2,                           # thickness
    cv2.LINE_AA,                 # smooth edges
)

Watch out: OpenCV colours are BGR, not RGB. Blue comes first and red comes last.

ColourBGR
Green(0, 255, 0)
Red(0, 0, 255)
Blue(255, 0, 0)
Yellow(0, 255, 255)
White(255, 255, 255)
Black(0, 0, 0)

What you'll need

  • A laptop with a webcam (Windows, macOS or Linux)
  • Python 3.10 or newer. On Windows, tick Add python.exe to PATH when you install it.
  • VS Code with the Python, Pylance and Jupyter extensions from Microsoft
  • An internet connection for the installs (the programs themselves run offline)

Set up step by step

Tick off each step before you go on to the next one.

  1. Open a terminal. Windows: press Win+R, type cmd, press Enter. macOS: Cmd+Space, type Terminal. Linux: Ctrl+Alt+T.
  2. Make a project folder. Type mkdir cv_course, then cd cv_course.
  3. Create the virtual environment. Windows: python -m venv venv. macOS and Linux: python3 -m venv venv. A folder called venv appears.
  4. Switch it on. Windows: .\venv\Scripts\activate. macOS and Linux: source venv/bin/activate. Check: your prompt now starts with (venv). If it doesn't, stop and fix this first.
  5. Install the packages. Type pip install opencv-python numpy matplotlib and wait for "Successfully installed".
  6. Open the folder in VS Code. Type code . (or open VS Code and use File → Open Folder).
  7. Choose the right Python. Press Ctrl+Shift+P, type Python: Select Interpreter, and pick the one inside venv. Check: the bar at the bottom of VS Code shows venv.
  8. Install Jupyter for the next lessons. Type pip install notebook. You'll use notebooks from lesson 3.

Build it

Make a new file called webcam_lab.py in your cv_course folder. Build it in four steps, and run it after each one.

Step 1: check the install

import cv2
import numpy as np
 
print(f"OpenCV version: {cv2.__version__}")
print(f"NumPy version:  {np.__version__}")

You should see two version numbers. OpenCV should be 4.5 or newer (if not, run pip install --upgrade opencv-python). If you get ModuleNotFoundError, your venv isn't switched on.

Step 2: open the webcam

Replace everything in the file with this:

import cv2
 
cap = cv2.VideoCapture(0)
 
if not cap.isOpened():
    print("ERROR: Cannot open webcam. Try camera 1 or 2.")
    raise SystemExit
 
print("Webcam opened. Press Q to quit.")
 
while True:
    ret, frame = cap.read()
    if not ret:
        print("ERROR: No frame received.")
        break
 
    cv2.imshow("My webcam", frame)
 
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
 
cap.release()
cv2.destroyAllWindows()

You should see yourself in a window. Click on the window and press Q to quit.

Step 3: add an FPS counter and a banner

Now draw on every frame. Notice two things: prev_time is set before the loop, and the navy banner has its biggest number first, because colours are BGR.

import time
import cv2
 
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("ERROR: Cannot open webcam. Try camera 1 or 2.")
    raise SystemExit
 
prev_time = time.time()
show_gray = False
 
print("Press Q to quit, G to switch black-and-white on and off.")
 
while True:
    ret, frame = cap.read()
    if not ret:
        print("ERROR: No frame received.")
        break
 
    # frames per second = 1 second divided by the time since the last frame
    now = time.time()
    fps = 1.0 / (now - prev_time + 1e-9)
    prev_time = now
 
    # read the keyboard once per loop
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break
    if key == ord("g"):
        show_gray = not show_gray
 
    if show_gray:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        frame = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)  # back to 3 channels so we can still draw in colour
 
    h, w = frame.shape[:2]
 
    cv2.rectangle(frame, (0, 0), (w, 40), (90, 30, 10), -1)   # navy banner (-1 = filled)
    cv2.putText(frame, f"FPS: {fps:.1f}", (10, 28),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2, cv2.LINE_AA)
    cv2.putText(frame, f"{w}x{h}", (w - 110, 28),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (200, 200, 200), 1, cv2.LINE_AA)
 
    cv2.imshow("My webcam", frame)
 
cap.release()
cv2.destroyAllWindows()

You should see a navy banner with a green FPS number and your camera's size, like 640x480. Press G and the picture turns black and white. Between 15 and 30 FPS is normal for a laptop webcam.

Step 4 (extra): a colour picker

Make a second file, sampler.py. Click anywhere on the video to print the colour of that pixel. You'll meet the second colour code, HSV, in lesson 4.

import cv2
 
clicked = None  # the last place you clicked
 
def on_mouse(event, x, y, flags, param):
    global clicked
    if event == cv2.EVENT_LBUTTONDOWN:
        clicked = (x, y)
 
cap = cv2.VideoCapture(0)
cv2.namedWindow("Sampler")
cv2.setMouseCallback("Sampler", on_mouse)
 
while True:
    ret, frame = cap.read()
    if not ret:
        break
 
    if clicked is not None:
        x, y = clicked
        b, g, r = frame[y, x]
        hsv = cv2.cvtColor(frame[y:y + 1, x:x + 1], cv2.COLOR_BGR2HSV)[0, 0]
        print(f"({x}, {y})  BGR = ({b}, {g}, {r})  HSV = {tuple(int(v) for v in hsv)}")
        cv2.circle(frame, (x, y), 6, (0, 255, 255), 2)
        clicked = None
 
    cv2.imshow("Sampler", frame)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
 
cap.release()
cv2.destroyAllWindows()

You should see a yellow circle where you clicked, and the colour numbers in the terminal. Try clicking your shirt, then the wall.

If it goes wrong

What you seeWhyFix
ModuleNotFoundError: No module named 'cv2'The venv isn't switched on, or OpenCV went somewhere elseCheck for (venv) in the prompt, then pip install opencv-python again
The window opens but it's blackAnother app is using the cameraClose the browser, Zoom, Teams or any other camera app, then try again
"Cannot open webcam"Wrong camera number, or no webcam foundTry cv2.VideoCapture(1) or (2)
The window freezeswaitKey is missing, or set to 0Put cv2.waitKey(1) inside the loop. 0 means "wait forever".
python is not recognisedPython isn't on your PATHTry python3. On Windows, reinstall Python and tick "Add to PATH".
FPS shows 0.0 or a giant numberprev_time is set inside the loopMove prev_time = time.time() above while True:
VS Code says the module is missing, but the terminal worksVS Code is using the wrong PythonCtrl+Shift+P, Python: Select Interpreter, pick the venv one
Your navy banner is redYou wrote the colour as RGBOpenCV is BGR. Navy is (90, 30, 10): blue first.

Try it

  • Add a frame counter to the banner: start frame_count = 0 before the loop and add 1 each time round.
  • Draw a box in the middle of the frame with cv2.rectangle(). Work out the corners from w and h.
  • Show the time on screen with time.strftime("%H:%M:%S").
  • Harder: make the S key save the current frame as a photo with cv2.imwrite("snap.jpg", frame). You'll use this idea for collecting data in Unit 3.

Check what you learnt

  1. What does cap.release() do?

  2. Why does the loop need cv2.waitKey(1)?

  3. You wanted red text but it came out blue. What went wrong?

  4. What is inside the venv folder?

  5. How can your program check that the webcam opened before it starts the loop?

Conclusion

You've built your computer-vision workshop: a virtual environment with OpenCV in it, VS Code pointed at the right Python, and a webcam loop that grabs, draws on and shows every frame. Almost every program in this course is this same loop with something new added in the middle.

What next?

Next: Python & NumPy crash course: an image is an array. The frame you just showed is a NumPy array. You'll learn to crop it, flip it and brighten it with a few lines of code.