Hardware: Raspberry Pi 4 / Raspberry Pi 5
AI type: Computer Vision – Object Detection + Tracking
Overview
Simple object counting detects how many objects appear in a frame, but it cannot distinguish between new and already seen objects.
This project extends basic AI detection by adding object tracking, allowing the Raspberry Pi to count each object only once.
The result is a more practical AI system suitable for real-world scenarios such as people flow monitoring or vehicle counting.
What you will build
AI-based object detection on Raspberry Pi
Object tracking across video frames
Unique object counting (count once per object)
Fully local and offline system
Required hardware
Software requirements
Project architecture
Camera captures video frames
AI model detects objects in each frame
Tracker assigns IDs to detected objects
Each object ID is counted only once
This avoids double counting and improves accuracy.
Installation steps
Update system
sudo apt update sudo apt upgrade
Install dependencies
sudo apt install python3-opencv python3-pip pip3 install ultralytics
Reboot the system
AI model and tracking method
This project uses a lightweight YOLO model for detection and a simple centroid-based tracking logic.
Each detected object is assigned an ID based on its position across frames.
This approach is computationally efficient and suitable for Raspberry Pi hardware.
Python code (copy-paste)
import cv2 from ultralytics import YOLO import math model = YOLO("yolov8n.pt") cap = cv2.VideoCapture(0) object_id = 0 objects = {} counted_ids = set() def distance(p1, p2): return math.hypot(p1[0] - p2[0], p1[1] - p2[1]) while True: ret, frame = cap.read() if not ret: break results = model(frame, verbose=False) boxes = results[0].boxes current_centroids = [] for box in boxes: x1, y1, x2, y2 = box.xyxy[0] cx = int((x1 + x2) / 2) cy = int((y1 + y2) / 2) current_centroids.append((cx, cy)) for centroid in current_centroids: matched = False for oid, prev in objects.items(): if distance(centroid, prev) < 50: objects[oid] = centroid matched = True break if not matched: objects[object_id] = centroid counted_ids.add(object_id) object_id += 1 for oid, (cx, cy) in objects.items(): cv2.circle(frame, (cx, cy), 5, (0, 255, 0), -1) cv2.putText(frame, f"ID {oid}", (cx + 5, cy + 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1) cv2.putText(frame, f"Unique count: {len(counted_ids)}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.imshow("AI Object Tracking", frame) if cv2.waitKey(1) & 0xFF == 27: break cap.release() cv2.destroyAllWindows()
How it works
Each detected object is represented by its centroid.
The system compares centroids between frames and assigns the same ID if the distance is below a threshold.
When a new object appears, it receives a new ID and is counted only once.
This simple tracking logic avoids the complexity of advanced trackers while remaining effective.
Performance notes
Works best with moderate object movement
High-speed motion may cause ID switching
Lower camera resolution improves stabilit
Practical application
Limitations
Simple tracker may lose objects during occlusion
Not suitable for dense crowds
Advanced tracking requires more compute
Despite this, the solution is ideal for low-cost AI systems.
Conclusion
By combining AI detection and lightweight tracking, Raspberry Pi becomes capable of unique object counting without GPUs or cloud services.
This project demonstrates how far affordable hardware can go with the right software architecture.
AI without millions is not a compromise — it is a design choice.
