Real-time colour-based object tracking and autonomous pillar counting for ROS2 Jazzy using OpenCV.
General-purpose colour tracking with depth estimation. Detects the largest object matching a configurable HSV range, computes its bounding box and centroid, and publishes the 3D position.
Autonomous coloured pillar counter. Detects green and blue pillars via HSV filtering, estimates their world position using depth + robot odometry, and counts unique pillars (avoids double-counting by tracking world positions).
Combined with ros2_slam_explorer, the robot autonomously explores an unknown environment while counting coloured pillars.
┌──────────────┐ ┌──────────────────┐
│ SLAM Explorer│──Nav2 goals───────▶│ Nav2 │──▶ Robot moves
└──────────────┘ └──────────────────┘
│
┌──────────────┐ /colour_image ┌──────▼──────────┐
│ Camera │───────────────────▶│ Pillar Counter │──▶ /pillar_counter/summary
│ + Depth │───────────────────▶│ │──▶ /pillar_counter/debug_image
└──────────────┘ /depth_image │ - HSV filtering │
│ - Depth lookup │
┌──────────────┐ /odom │ - World position│
│ Odometry │───────────────────▶│ - Unique count │
└──────────────┘ └─────────────────┘
- Multi-colour detection — Tracks green and blue pillars independently
- World position estimation — Depth + odometry to compute pillar locations
- Unique counting — Only counts a pillar once using distance-based deduplication
- Debug visualization — Annotated camera feed with bounding boxes, depth, and live count
- SLAM integration — Combined launch with autonomous frontier exploration
- Configurable — HSV ranges, minimum area, unique distance via ROS2 parameters
- ROS2 Jazzy
- OpenCV (
python3-opencv) - cv_bridge (
ros-jazzy-cv-bridge) - ros2_slam_explorer (for combined SLAM + counting)
- TurtleBot3 Gazebo (
ros-jazzy-turtlebot3-gazebo)
cd ~/ros2_ws/src
git clone https://github.com/manavsikkas/ros2_opencv_tracker.git
git clone https://github.com/manavsikkas/ros2_slam_explorer.git # for combined mode
cd ..
colcon build
source install/setup.bashColour tracker only:
export TURTLEBOT3_MODEL=waffle
ros2 launch ros2_opencv_tracker tracker.launch.pySLAM exploration + pillar counting:
export TURTLEBOT3_MODEL=waffle
ros2 launch ros2_opencv_tracker slam_counter.launch.pyView the live count and detections:
ros2 topic echo /pillar_counter/summary
ros2 run rqt_image_view rqt_image_view /pillar_counter/debug_image| Parameter | Default | Description |
|---|---|---|
min_area |
300 |
Minimum contour area (pixels) to consider a detection |
unique_distance |
1.0 |
Minimum distance (meters) between unique pillars |
Built-in colour ranges:
| Colour | Hue | Saturation | Value |
|---|---|---|---|
| Green | 35-85 | 100-255 | 50-255 |
| Blue | 100-130 | 150-255 | 50-255 |
| Topic | Type | Description |
|---|---|---|
/pillar_counter/summary |
String |
Live count: "Pillars — green: 3, blue: 2, total: 5" |
/pillar_counter/debug_image |
Image |
Annotated camera feed with detections |
/tracker/position |
PointStamped |
Tracked object 3D position (colour_tracker) |
/tracker/debug_image |
Image |
Annotated image (colour_tracker) |
MIT