Welcome back, everyone! This is Paul McWhorter from TopTechBoy.com, and welcome to Lesson 55 in our AI on the Edge tutorial series!
If you’ve been following along, grab yourself a nice, hot cup of black coffee, fire up your Raspberry Pi 5, and let’s get right into it!
What We Are Doing in Lesson 55
Up to this point in the series, we have spent a lot of time working with land-marking models—tracking human hands, pose points, and facial features. But today, we step into full-blown computer vision object detection!
In this lesson, we learn how to implement MediaPipe’s lightweight, standalone object detection task API (mediapipe.tasks.python.vision.ObjectDetector) running on the Raspberry Pi 5. Using the pre-trained COCO dataset model (efficientdet_lite0.tflite), our Pi 5 can instantly identify up to 80 different real-world objects—from people, cups, and bottles to chairs, laptops, and cell phones—and draw real-time bounding boxes around them on our video feed.
Key Takeaways & Concepts Covered
-
Setting Up the MediaPipe Object Detector Task API:
Unlike older
mp.solutionswrappers, the modern MediaPipe Tasks API requires configuringBaseOptionswith the explicit local path to your.tflitemodel asset (modelPath = "/home/pi/ai-lab-kit/mediapipe/efficientdet_lite0.tflite"). -
Configuring Detector Parameters:
-
score_threshold(0.35): Sets the minimum confidence score required to accept a detected object. Lowering this value captures weaker detections but risks false positives; raising it ensures high-confidence target lock. -
max_results(3): Limits the maximum number of bounding boxes predicted per frame to keep our processing loop lean and fast.
-
-
Decoding Detection Bounding Boxes:
MediaPipe returns detected objects with bounding box geometry relative to the frame origin (
origin_x,origin_y,width,height). We parse these dimensions directly into OpenCV integers(x, y, w, h)to draw bounding boxes withcv2.rectangle(). -
Category Labeling & Confidence Rendering:
We pull category names (
category_name) and classification scores (category.score) fromdetection.categories[0], format the confidence as a percentage, and render clean text labels anchored directly above each target box. -
Optimal Frame Alignment & FPS Monitoring:
We capture 60 FPS video directly from
picamera2inRGB888format, flip it properly to match our physical camera mounting, and track real-time frames-per-second using our low-pass smoothing formula.
What You Will Need
To follow along with this lesson, ensure you have your standard gear ready from the kit:
-
Raspberry Pi 5 (with Active Cooler/Heat Sink)
-
Raspberry Pi Camera Module 3 (or compatible Camera Module driven via
picamera2) -
SunFounder Fusion AI Lab Kit (with pre-downloaded MediaPipe
.tflitemodel weights)
Homework Assignment
Alright, class, you know I never let you off the hook without some homework!
Your assignment for this lesson is to take this foundational object detection script and upgrade its intelligence:
-
Target Filter: Modify the loop so that it only draws bounding boxes around a specific target object of your choice (for instance, only detect
"person"or only detect"bottle"), ignoring all other detected COCO classes. -
Target Tracking Dot: Calculate the exact center pixel coordinate $(x + \frac{w}{2}, y + \frac{h}{2})$ of your targeted object, and draw a solid red target circle (
cv2.circle) right on the object’s center point. -
Dynamic On-Screen Target Status: If your target object is visible in the frame, display a green text banner in the upper corner reading
"TARGET ACQUIRED". If it leaves the frame, change the status banner to a red"SEARCHING...".
Give it a shot, take your time, and write your solution from scratch without copying and pasting! Drop a comment on the YouTube video to let me know if you got it working or if you ran into any snags.
Until next time, get your coffee, keep coding, and I’ll see you guys in Lesson 56!
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# ==================================================================== # DISCLAIMER: # This code is provided as-is for educational and experimental # purposes only. The author makes no representations or warranties of # any kind concerning the safety, suitability, or accuracy of this # code. Use at your own risk. The author assumes no liability for any # damages, system failures, security breaches, or network issues # resulting from the use or implementation of this script. # ==================================================================== import cv2 import time from picamera2 import Picamera2 import mediapipe as mp from mediapipe.tasks import python from mediapipe.tasks.python import vision piCam = Picamera2(1) W=1280 H=720 tStart = time.time() fps = 0 RES = (W,H) piCam.preview_configuration.main.size = RES piCam.preview_configuration.main.format = "RGB888" piCam.preview_configuration.controls.FrameRate=60 piCam.preview_configuration.align() piCam.configure("preview") piCam.start() textLowerLeft = (int(W*.01),int(H*.05)) fontFace = cv2.FONT_HERSHEY_SIMPLEX fontThickness = int(W/425) fontScale = H*.0015 fontColor = (0,0,255) topBar = 65 windowPadding = 0 cv2.namedWindow('Camera', cv2.WINDOW_GUI_NORMAL) cv2.resizeWindow('Camera', W, H) tSettle = .1 time.sleep(tSettle) cv2.moveWindow('Camera', windowPadding, topBar) modelPath = "/home/pi/ai-lab-kit/mediapipe/efficientdet_lite0.tflite" scoreThreshold = .35 maxObj = 3 baseOptions = python.BaseOptions(model_asset_path = modelPath) options = vision.ObjectDetectorOptions(base_options = baseOptions, score_threshold=scoreThreshold, max_results=maxObj) myDetector = vision.ObjectDetector.create_from_options(options) while True: deltaT = time.time() - tStart tStart=time.time() fps = fps*.95 + (1/deltaT)*.05 frame= piCam.capture_array() frame=cv2.flip(frame,-1) myImage = mp.Image(image_format = mp.ImageFormat.SRGB, data=frame) myDetections = myDetector.detect(myImage) #print(myDetections.detections) for detection in myDetections.detections: box = detection.bounding_box x = box.origin_x y = box.origin_y w = box.width h = box.height cv2.rectangle(frame, (x,y), (x+w,y+h), (255,0,0), fontThickness) if detection.categories: category = detection.categories[0] myLabel = category.category_name labelText = myLabel+" "+ str(round(category.score*100))+"%" cv2.putText(frame,labelText, (x, max(y-10,25)),fontFace, fontScale*.8, (0,255,0), 2) myText = "FPS: "+str(round(fps,1)) cv2.putText(frame,myText,textLowerLeft,fontFace,fontScale,fontColor,fontThickness) cv2.imshow("Camera", frame) #cv2.moveWindow("Camera",0,60) if cv2.waitKey(1)==ord('q'): break myDetector.close() cv2.destroyAllWindows() print('Program Terminated') |