RoboticsEngineer

Robot That Chases a Colored Ball with OpenCV

The camera finds a bright ball by its color and the robot turns and drives toward it — your first real computer-vision robot.

LevelEngineer
Time2.5 h
Est. cost~$181
Steps5

Color tracking is the friendliest way into computer vision. OpenCV converts each frame to HSV, keeps only pixels of your ball's color and finds their center; the robot steers to keep that center in the middle.

⚠ SAFETY
Use protected 18650 cells and a proper holder; never short the battery terminals.

Mission steps

  1. Build the base

    Use the obstacle robot wiring for motors and power, and mount the camera low and facing forward.

  2. Install tools

    sudo apt install python3-opencv python3-picamera2 python3-gpiozero.

  3. Pick the color

    Use a solid, bright ball (orange or lime green) and adjust the HSV range until only the ball shows white in the mask.

  4. Steer to it

    If the ball is left of center, turn left; if centered, drive forward; if it fills much of the frame, stop.

  5. Improve

    Add a search mode that slowly spins when the ball is lost, and smooth the steering to avoid jerky moves.

Code

import cv2, numpy as np
from picamera2 import Picamera2
from gpiozero import Robot, Motor, OutputDevice

OutputDevice(25).on()   # TB6612 STBY
bot = Robot(left=Motor(5, 6, enable=12), right=Motor(13, 19, enable=26))
cam = Picamera2()
cam.configure(cam.create_preview_configuration(main={'format': 'RGB888', 'size': (320, 240)}))
cam.start()
LOW, HIGH = np.array([5, 120, 120]), np.array([20, 255, 255])   # orange

while True:
    hsv = cv2.cvtColor(cam.capture_array(), cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, LOW, HIGH)
    m = cv2.moments(mask)
    if m['m00'] < 50000:              # not enough pixels: search
        bot.right(0.3); continue
    x = m['m10'] / m['m00']
    area = m['m00'] / 255
    err = (x - 160) / 160             # -1 left ... +1 right
    if area > 15000:
        bot.stop()
    elif abs(err) > 0.25:
        bot.right(0.4) if err > 0 else bot.left(0.4)
    else:
        bot.forward(0.5)

Tip: test every script on the bench before installing it in a moving machine.

Questions

Why does it lose the ball in different light?

Color shifts with lighting. Re-tune the HSV range where you play, lock the camera's white balance, or pick a more saturated ball.