The OpenMV Cam H7 transforms complex machine vision into accessible Python programming, making object tracking achievable for makers, students, and professionals alike. This comprehensive tutorial guides you through implementing robust object tracking using color blob detection, one of the most fundamental and practical computer vision techniques.
Object tracking with the OpenMV Cam H7 opens doors to applications ranging from robotic ball following and automated surveillance to industrial quality control and interactive installations.
Understanding OpenMV Cam H7 Capabilities
Hardware Overview
The OpenMV Cam H7 features an STM32H743VI ARM Cortex M7 processor running at 480MHz with 1MB of RAM and 2MB of flash memory. The integrated OV7725 camera sensor captures images at resolutions up to 640x480 pixels, providing sufficient detail for most tracking applications.
Key Features for Object Tracking:
-
Real-time image processing at 30+ FPS
-
Built-in machine vision algorithms optimized for microcontrollers
-
Python/MicroPython programming environment
-
Extensive I/O pins for controlling external devices
-
Native support for color blob detection and tracking
Machine Vision Capabilities
The OpenMV platform excels at color-based object tracking through its optimized find_blobs() function. You can detect up to 16 different colors simultaneously, with each color supporting multiple distinct blobs. The system provides position, size, centroid, and orientation data for each detected object.
Setting Up Your Development Environment
Installing OpenMV IDE
-
Download the IDE from openmv.io/pages/download
-
Install the software, accepting all default settings
-
Connect your OpenMV Cam H7 via USB cable
-
Launch OpenMV IDE and click the connect button
The IDE provides a live frame buffer view, integrated histogram display for color analysis, and real-time script execution capabilities.
Initial Configuration
When you first open OpenMV IDE, a basic "Hello World" script appears. This demonstrates the fundamental camera setup:
python
import sensor, image, time
sensor.reset() # Reset and initialize sensor
sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565
sensor.set_framesize(sensor.QVGA) # Set frame size to 320x240
sensor.skip_frames(time = 2000) # Wait for settings take effect
clock = time.clock() # Create a clock object
while(True):
clock.tick() # Update the FPS clock
img = sensor.snapshot() # Take a picture and return image
print(clock.fps()) # Print the FPS
Click the green run button to execute this script and verify your camera is working properly.
Color Threshold Determination
Using the Histogram Tool
Successful object tracking begins with accurate color threshold determination. The OpenMV IDE's histogram tool provides an interactive method for finding optimal color ranges.
Steps for Color Calibration:
-
Place your target object in the camera's field of view
-
Select the object area by clicking and dragging on the frame buffer
-
Observe the histogram showing color distribution in LAB color space
-
Note the L (lightness), A (green-red), and B (blue-yellow) values
-
Create threshold tuples based on observed ranges
LAB Color Space Advantages
LAB color space provides superior color tracking compared to RGB because it separates lightness from color information, making it more robust under varying lighting conditions.
A typical color threshold format: (L_min, L_max, A_min, A_max, B_min, B_max)
Example red threshold: (30, 100, 15, 127, 15, 127)
Automatic Threshold Generation
Use the OpenMV IDE's threshold editor tool:
-
Navigate to Tools → Machine Vision → Threshold Editor
-
Select your target object in the live view
-
Adjust threshold sliders for optimal detection
-
Copy the generated threshold values to your code
Basic Color Blob Tracking Implementation
Simple Tracking Script
Here's a fundamental color tracking implementation:
python
import sensor, image, time
# Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max)
red_threshold = (30, 100, 15, 127, 15, 127)
# Initialize camera
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # Disable auto gain for color tracking
sensor.set_auto_whitebal(False) # Disable auto white balance
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
# Find blobs matching our color threshold
blobs = img.find_blobs([red_threshold], pixels_threshold=200, area_threshold=200)
if blobs:
# Track the largest blob
largest_blob = max(blobs, key=lambda b: b.pixels())
# Draw bounding rectangle and center cross
img.draw_rectangle(largest_blob.rect())
img.draw_cross(largest_blob.cx(), largest_blob.cy())
# Print tracking information
print("Object at:", largest_blob.cx(), largest_blob.cy())
print("Size:", largest_blob.pixels())
print("FPS:", clock.fps())
Understanding Blob Properties
Each detected blob provides comprehensive tracking data:
-
Position: blob.x(), blob.y() - top-left corner coordinates
-
Center: blob.cx(), blob.cy() - centroid coordinates
-
Dimensions: blob.w(), blob.h() - width and height
-
Area: blob.pixels() - total pixel count
-
Rotation: blob.rotation() - object orientation in radians
Advanced Tracking Techniques
Multi-Object Tracking
Track multiple objects simultaneously using different color thresholds:
python
import sensor, image, time
# Define multiple color thresholds
red_threshold = (30, 100, 15, 127, 15, 127)
blue_threshold = (0, 30, -64, -8, -32, 32)
green_threshold = (30, 100, -64, -8, -32, 32)
thresholds = [red_threshold, blue_threshold, green_threshold]
colors = [(255, 0, 0), (0, 0, 255), (0, 255, 0)] # RGB colors for visualization
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
# Track each color separately
for i, threshold in enumerate(thresholds):
blobs = img.find_blobs([threshold], pixels_threshold=100, area_threshold=100)
for blob in blobs:
# Draw rectangle with color-specific visualization
img.draw_rectangle(blob.rect(), color=colors[i])
img.draw_cross(blob.cx(), blob.cy(), color=colors[i])
print(f"Color {i} at: ({blob.cx()}, {blob.cy()})")
print("FPS:", clock.fps())
Object Following with Servo Control
Implement active tracking using servo motors to follow detected objects:
python
import sensor, image, time, math
from pyb import Servo
# Initialize servos (pan and tilt)
pan_servo = Servo(1) # P7
tilt_servo = Servo(2) # P8
# Servo position variables
pan_angle = 90
tilt_angle = 90
# Color threshold
target_threshold = (30, 100, 15, 127, 15, 127)
# Camera setup
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
blobs = img.find_blobs([target_threshold], pixels_threshold=200, area_threshold=200)
if blobs:
largest_blob = max(blobs, key=lambda b: b.pixels())
# Calculate error from center
error_x = largest_blob.cx() - img.width() // 2
error_y = largest_blob.cy() - img.height() // 2
# Simple proportional control
pan_angle -= error_x * 0.1
tilt_angle += error_y * 0.1
# Limit servo angles
pan_angle = max(0, min(180, pan_angle))
tilt_angle = max(0, min(180, tilt_angle))
# Update servo positions
pan_servo.angle(pan_angle)
tilt_servo.angle(tilt_angle)
# Visualization
img.draw_rectangle(largest_blob.rect())
img.draw_cross(largest_blob.cx(), largest_blob.cy())
print(f"Tracking: ({largest_blob.cx()}, {largest_blob.cy()})")
print(f"Servo angles: Pan={pan_angle:.1f}, Tilt={tilt_angle:.1f}")
print("FPS:", clock.fps())
Optimizing Tracking Performance
Camera Settings for Optimal Tracking
Disable Auto Settings:
python
sensor.set_auto_gain(False) # Prevents gain fluctuations
sensor.set_auto_whitebal(False) # Maintains consistent colors
sensor.set_auto_exposure(False) # Optional: prevents exposure changes
Manual Fine-Tuning:
python
sensor.set_contrast(3) # Increase contrast for better separation
sensor.set_brightness(0) # Adjust brightness as needed
sensor.set_saturation(3) # Enhance color saturation
Frame Processing Optimization
Region of Interest (ROI): Limit processing to specific image areas for improved performance:
python
# Process only center portion of image
roi = (img.width()//4, img.height()//4, img.width()//2, img.height()//2)
blobs = img.find_blobs([threshold], roi=roi, pixels_threshold=100)
Filtering Parameters: Adjust blob detection parameters for optimal results:
python
blobs = img.find_blobs([threshold],
pixels_threshold=200, # Minimum blob size in pixels
area_threshold=200, # Minimum blob area
merge=True, # Merge overlapping blobs
margin=10) # Merge margin in pixels
Troubleshooting Common Issues
Poor Color Detection
Symptoms: Inconsistent blob detection, false positives Solutions:
-
Recalibrate color thresholds using histogram tool
-
Ensure consistent lighting conditions
-
Adjust contrast and saturation settings
-
Use tighter threshold ranges for specific colors
Tracking Jitter
Symptoms: Unstable tracking, rapid position changes Solutions:
-
Implement smoothing filters for position data
-
Increase minimum blob size requirements
-
Add temporal filtering to reject momentary false detections
-
Use larger area thresholds to ignore noise
Low Frame Rate
Symptoms: Sluggish tracking response, low FPS Solutions:
-
Reduce image resolution using sensor.set_framesize(sensor.QQVGA)
-
Limit processing to regions of interest
-
Optimize blob detection parameters
-
Remove unnecessary visualization code for production use
Practical Applications and Extensions
Security Camera with Motion Detection
Combine person detection with tracking for intelligent surveillance:
python
import sensor, image, time
from pyb import LED
# Load person detection model
net = None
try:
net = tf.load("person_detection.tflite", load_to_fb=True)
except:
print("Person detection model not found")
red_led = LED(1)
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((240, 240)) # Crop to square
sensor.skip_frames(time = 2000)
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
if net:
# Run person detection
for obj in net.classify(img, min_scale=1.0, scale_mul=0.8, x_overlap=0.5, y_overlap=0.5):
if obj.output()[1] > 0.7: # Person confidence threshold
red_led.on()
img.draw_rectangle(obj.rect())
print("Person detected!")
else:
red_led.off()
print("FPS:", clock.fps())
Robot Ball Following
Create a robot that autonomously follows a colored ball:
python
import sensor, image, time, math
from pyb import Pin, Timer
# Motor control pins
motor_left = Pin('P0', Pin.OUT_PP)
motor_right = Pin('P1', Pin.OUT_PP)
# Ball color threshold (adjust for your ball)
ball_threshold = (35, 100, 15, 127, 15, 127)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
blobs = img.find_blobs([ball_threshold], pixels_threshold=300, area_threshold=300)
if blobs:
largest_blob = max(blobs, key=lambda b: b.pixels())
# Calculate steering based on ball position
center_x = img.width() // 2
error = largest_blob.cx() - center_x
# Simple robot control logic
if abs(error) < 20: # Ball centered - move forward
motor_left.high()
motor_right.high()
elif error > 0: # Ball to the right - turn right
motor_left.high()
motor_right.low()
else: # Ball to the left - turn left
motor_left.low()
motor_right.high()
img.draw_rectangle(largest_blob.rect())
img.draw_cross(largest_blob.cx(), largest_blob.cy())
else:
# No ball detected - stop motors
motor_left.low()
motor_right.low()
print("FPS:", clock.fps())
Conclusion
The OpenMV Cam H7 provides an accessible entry point into computer vision and object tracking applications. Through color blob detection, you can create sophisticated tracking systems that respond to real-world objects in real-time.
The key to successful object tracking lies in proper color threshold calibration, understanding the blob detection parameters, and optimizing your code for the specific application requirements. Start with simple single-object tracking, then gradually add complexity as you become comfortable with the platform.
The combination of Python programming simplicity and powerful built-in computer vision functions makes the OpenMV Cam H7 ideal for educational projects, prototyping, and even production applications where traditional computer vision systems would be overkill.
Whether you're building a ball-following robot, creating an interactive art installation, or developing an industrial quality control system, the techniques covered in this tutorial provide the foundation for robust object tracking implementations.
Frequently Asked Questions
1. What's the maximum number of objects I can track simultaneously?
The OpenMV Cam H7 can theoretically track up to 16 different colors with multiple blobs per color. Practically, tracking 3-4 objects simultaneously provides optimal performance while maintaining real-time frame rates.
2. How do I improve tracking accuracy in varying lighting conditions?
Disable auto gain and auto white balance, use LAB color space thresholds, and consider implementing adaptive threshold adjustment based on ambient lighting. You can also use multiple threshold sets for different lighting scenarios.
3. Can I track objects other than colored blobs?
Yes, OpenMV supports template matching, face detection, feature point tracking, and TensorFlow Lite models for custom object detection. However, color blob tracking remains the fastest and most reliable method for real-time applications.
4. What frame rates can I expect for object tracking?
Typical frame rates range from 15-30 FPS depending on image resolution and processing complexity. QQVGA resolution (160x120) provides the highest frame rates, while VGA (640x480) offers more detail but lower speed.
5. How do I save tracking data or images to storage?
Add a microSD card to the OpenMV Cam H7 for expanded storage. You can save images using img.save("filename.jpg") and log tracking data to text files. The internal storage is limited to about 100KB and should only store your Python code.