Real-Time Object Counter

Real-Time Object Counter

Real-Time Object Counter

A guide to creating a program that counts the number of objects crossing a virtual line in a video feed.

Libraries and Tools Used

This project combines object detection and tracking libraries:

  • ultralytics: Provides the pre-trained YOLO model for object detection.
  • cv2 (OpenCV): For video processing and displaying the output.

1. Load Model and Define Counter

  • What the code does: It loads the YOLOv8 model for object detection and defines a simple `Counter` class. This class will keep track of detected objects and ensure they are only counted once.
  • Behind the scenes: The YOLO model detects objects, and the `Counter` class will use a simple form of object tracking to manage the state of objects (e.g., whether they have already been counted).
  • Abstraction: The `YOLO` class from `ultralytics` abstracts the entire deep learning model. The custom `Counter` class encapsulates the logic for managing object states.
# pip install ultralytics
import cv2
import numpy as np
from ultralytics import YOLO

# Load a pre-trained YOLO model
model = YOLO('yolov8n.pt')

# Define a simple class to track and count objects
class ObjectCounter:
    def __init__(self):
        self.counted_ids = set()
        self.count = 0
    
    def process_detections(self, detections, line_y):
        for box in detections.boxes:
            # Get object details
            x1, y1, x2, y2 = [int(i) for i in box.xyxy[0]]
            object_id = int(box.id.item())
            
            # Check if the object is crossing the line and hasn't been counted
            if y1 < line_y < y2 and object_id not in self.counted_ids:
                self.count += 1
                self.counted_ids.add(object_id)
        return self.count

counter = ObjectCounter()
print("Model and counter initialized.")

2. Process Video Stream

  • What the code does: This is the main loop where a video is processed frame by frame. It uses the YOLO model with a built-in tracker to get object detections and IDs.
  • Behind the scenes: The `model.track` method automatically handles both object detection and object tracking, assigning a unique ID to each object. This is a crucial step for accurately counting.
  • Abstraction: The `model.track` function is a powerful abstraction that combines the detection and tracking algorithms into a single, easy-to-use method.
# This is a conceptual loop. For a real app, you'd use a video file or webcam
video_path = 'path/to/your/video.mp4'
cap = cv2.VideoCapture(video_path)

# A virtual counting line
line_y = 500

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # Run object tracking on the frame
    results = model.track(frame, persist=True)

    # ... The rest of the logic from Step 3 would go here ...
    # This is where we'd draw the line and update the counter.

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

3. Visualize and Count

  • What the code does: It draws the virtual counting line on the frame and updates the object count. It also draws bounding boxes and displays the total count on the screen.
  • Behind the scenes: The `counter.process_detections` function is called with the current detections. It checks if an object's bounding box has crossed the `line_y` position and, if so, increments the count.
  • Abstraction: The `cv2` library simplifies the visualization with functions like `cv2.line` and `cv2.putText`, abstracting the process of drawing on the image frame.
# This code would be inside the video loop from Step 2
# We assume `results` and `frame` are available.

# Draw the counting line
cv2.line(frame, (0, line_y), (frame.shape[1], line_y), (0, 255, 0), 2)

# Get the detections from the results
detections = results[0]

# Update the counter
current_count = counter.process_detections(detections, line_y)

# Draw bounding boxes and IDs
annotated_frame = detections.plot()

# Display the current count on the frame
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(annotated_frame, f"Count: {current_count}", (10, 50), font, 1.5, (0, 0, 255), 2, cv2.LINE_AA)

# Display the annotated frame
# cv2.imshow("Object Counter", annotated_frame)

Comments

Popular posts from this blog

Simple Augmented Reality (AR) App

Image Captioning

Pose Estimation