Month 3 Box - AI Deep Dive

Lesson 3: Introduction to the Pi Camera Module & Live AI Detection

The Pi Camera Module and Live AI Detection

Today your Pi starts seeing. You will connect the Camera Module 2, confirm it works, and run object detection on a live video feed instead of saved files, so the Pi labels people, objects, and pets in real time. You will also measure frames per second with and without the AI HAT+ to see, concretely, why edge AI hardware matters.

Connecting the camera

The camera attaches to the Pi's CSI port with a ribbon cable. Power off first, lift the port latch, and insert the cable with the shiny contacts facing the correct way, usually toward the HDMI ports. The Pi 5 changed its connector size, so an adapter is included to fit the cable. Close the latch, power back on, and test with the command libcamera-hello, which pops up a five-second preview. If no preview appears, recheck the cable orientation and make sure the OS is updated.

From saved files to a live feed

The detection code is nearly identical to last lesson's, with one change: instead of reading an image or video file, you capture frames from the camera in a loop and run the model on each. The PiCamera2 library connects to the camera and OpenCV displays the annotated frames. You draw a box around each detected object with its label and confidence score, and you keep looping until you press a quit key. The AI work per frame is exactly what you already did; now the source is the real world.

Confidence scores

Each detection carries a confidence score, the model's estimate of how sure it is. A clear photo of a banana might come back 99 percent banana, while an odd cartoon banana with legs might only be 80 percent. Displaying the score next to each box tells you not just what the model saw but how certain it is, which helps you decide which detections to trust and where to set your threshold.

Frames per second, the edge metric that matters

The most important performance number here is frames per second: how many frames your program can actually analyze each second. A camera might deliver 30, 60, or 90 frames per second, but that means nothing if your model can only process a handful. For a security camera, a robot, or any real-time system, a low frame rate means missed events and laggy reactions. Many things affect it: the model you choose, the platform, even the language, and especially the frame size. A bigger frame gives higher quality but takes more work, so it lowers frames per second. Tuning this trade-off is a real engineering decision, not just a demo detail.

Why the AI HAT+ earns its place

Running the same detection with and without the AI HAT+ shows the difference plainly: the HAT+ pushes the frame rate far higher because the AI work runs on dedicated hardware rather than the general processor. This side-by-side is the whole argument for edge AI accelerators. A live feed at a usable frame rate, around 13 to 14 frames per second in the demo, is what turns a slideshow into something that feels real time.

Working through it

Attach the camera. Power off, open the CSI latch, insert the ribbon (with the adapter for the Pi 5) contacts facing the HDMI side, close the latch, and power on.

Test the hardware. Run libcamera-hello and confirm the five-second preview appears. If not, recheck the cable and update the OS.

Install dependencies and test in software. Run the provided setup script, then run the camera test script. Seeing the live window means PiCamera2 and its dependencies installed correctly. Press the quit key to stop.

Run live detection. Run the live-detection script, which reuses the TensorFlow Lite model from last lesson but captures from the camera. Move around and watch it label people, keyboards, and pets in real time.

Read the frame rate and tune it. Watch the FPS counter overlay, then change the frame size and observe how quality and frame rate trade off. Confirm the HAT+ is giving you the higher rate.

Test the camera feed with PiCamera2 and OpenCV

from picamera2 import Picamera2
import cv2

picam = Picamera2()
# frame size affects both quality and speed
picam.configure(picam.create_preview_configuration(main={"size": (640, 480)}))
picam.start()

while True:
    frame = picam.capture_array()          # grab one frame
    cv2.imshow("Camera", frame)            # show it
    if cv2.waitKey(1) & 0xFF == ord("q"):  # press q to quit
        break

cv2.destroyAllWindows()

This opens the camera at 640 by 480 and shows the live feed until you press q. If the window appears, your camera and its libraries are working, and you are ready to add detection to the loop.

Live detection with a frames-per-second counter