Hey everyone, Paul McWhorter here!
Welcome back to the AI on the Edge series! In today’s lesson, we’re going to have some fun and take our first real steps into computer vision animation.
We’re going to create a colorful box that bounces around the screen like an old-school screensaver, while displaying a live FPS counter so we can see how well our Raspberry Pi is handling the workload.
Even though it looks simple, this project teaches you several foundational skills you’ll use again and again in computer vision:
- Working with coordinates and drawing shapes in OpenCV
- Creating smooth real-time animation
- Detecting boundaries and reversing direction
- Calculating and displaying live FPS
These are the same techniques you’ll build on later when we start doing object tracking, collision detection, and more advanced AI vision projects.
What You Learned in This Lesson
- How to draw filled rectangles on a live video stream
- How to move objects smoothly frame by frame
- How to make objects “bounce” realistically off screen edges
- A clean method for calculating and displaying FPS
- Using variables to easily control size, position, speed, and color
This bouncing box may look basic, but once you understand how to do this, you can create all kinds of animated graphics that interact with what the camera sees.
Pro Tip: After you get it working, play around with the speed, box size, and colors. Try making multiple bouncing boxes with different speeds and directions — it’s a great way to experiment!
Ready for more? In the next lesson, we’re going to kick things up a notch and start working with multiple objects and more complex interactions.
Keep building, keep learning, and I’ll see you in the next video!
— Paul McWhorter
For your convenience, this is the code we developed in the video.
|
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 |
import cv2 import time from picamera2 import Picamera2 piCam = Picamera2() 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) x1 = int(.1*(W-1)) y1 = int(.25*(H-1)) upperLeft = (x1,y1) bW = int(W*.15) bH = int(H*.15) x2 = x1 + bW y2 = y1 + bH lowerRight = (x2, y2) xDelta = 1 yDelta = 1 boxColor = (0,255,255) boxThickness = -1 while True: deltaT = time.time() - tStart tStart=time.time() fps = fps*.95 + (1/deltaT)*.05 frame= piCam.capture_array() frame=cv2.flip(frame,-1) myText = "FPS: "+str(round(fps,1)) cv2.putText(frame,myText,textLowerLeft,fontFace,fontScale,fontColor,fontThickness) cv2.rectangle(frame,upperLeft,lowerRight,boxColor,boxThickness) x1=x1+xDelta y1=y1+yDelta x2 = x1 +bW y2 = y1 +bH upperLeft = (x1,y1) lowerRight = (x2,y2) if x1<=0 or x2>=(W-1): xDelta=xDelta*(-1) if y1<=0 or y2>=(H-1): yDelta=yDelta*(-1) cv2.imshow("Camera", frame) cv2.moveWindow("Camera",0,60) if cv2.waitKey(1)==ord('q'): break cv2.destroyAllWindows() print('Program Terminated') |
