Object Counting using Ultralytics YOLO26#
What is Object Counting?#
Object counting with Ultralytics YOLO26 involves identifying and counting specific objects in videos and camera streams. Because YOLO26 runs deep learning detection and tracking in real time, it suits counting scenarios such as crowd and occupancy analysis and surveillance.
Watch: How to Perform Real-Time Object Counting with Ultralytics YOLO26 🚀
Advantages of Object Counting#
- Resource Optimization: Object counting facilitates efficient resource management by providing accurate counts, optimizing resource allocation in applications like inventory management.
- Enhanced Security: Object counting enhances security and surveillance by accurately tracking and counting entities, aiding in proactive threat detection.
- Informed Decision-Making: Object counting offers valuable insights for decision-making, optimizing processes in retail, traffic management, and various other domains.
Real-World Applications#
| Logistics | Aquaculture |
|---|---|
![]() | ![]() |
| Conveyor Belt Packets Counting Using Ultralytics YOLO26 | Fish Counting in Sea using Ultralytics YOLO26 |
Count Objects with YOLO26#
Define a counting region — two points for a line or three or more for a polygon — and pass it to the ObjectCounter solution. The counter tracks each object across frames and tallies IN/OUT counts when tracked objects cross the line or pass through the region, returning an annotated frame you can write to an output video.
# Run a counting example
yolo solutions count show=True
# Pass a source video
yolo solutions count source="path/to/video.mp4"
# Pass region coordinates
yolo solutions count region="[(20, 400), (1080, 400), (1080, 360), (20, 360)]"The region argument accepts either two points (for a line) or a polygon with three or more points. Define the coordinates in the order they should be connected so the counter knows exactly where entries and exits occur.
ObjectCounter Arguments#
Here's a table with the ObjectCounter arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
model | str | None | Path to an Ultralytics YOLO model file. |
show_in | bool | True | Flag to control whether to display the in counts on the video stream. |
show_out | bool | True | Flag to control whether to display the out counts on the video stream. |
region | list or dict | None | Points defining the region of interest, either a list of (x, y) tuples or a dictionary mapping region names to point lists for multiple regions (RegionCounter only). When None, solutions that require a region fall back to a predefined default. |
line_width | int | 2 | Line thickness for the boxes, keypoints and counts the solution draws. |
verbose | bool | True | Enables the solution's per-frame log of input shape, class counts and processing speed. The tracking call itself is always silent. |
The ObjectCounter solution allows the use of several track arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
tracker | str | 'tracktrack.yaml' | Specifies the tracking algorithm to use. Built-in options: botsort.yaml, bytetrack.yaml, ocsort.yaml, deepocsort.yaml, fasttrack.yaml, tracktrack.yaml. |
conf | float | 0.25 | Sets the confidence threshold for detections; lower values allow more objects to be tracked but may include false positives. |
iou | float | 0.7 | Sets the Intersection over Union (IoU) threshold for filtering overlapping detections. |
classes | list | None | Filters results by class index. For example, classes=[0, 2, 3] only tracks the specified classes. |
device | str | None | Specifies the device for inference (e.g., cpu, cuda:0 or 0). Allows users to select between CPU, a specific GPU, or other compute devices for model execution. |
imgsz | int or tuple | 640 | Target inference image size: an integer for a square or a (height, width) pair. Shapes are adjusted to the model stride. |
max_det | int | 300 | Maximum number of detections kept per frame before tracking, limiting the objects a solution processes in dense scenes. |
quantize | int or str | None | Inference precision: 16 (FP16) or 32/unset (FP32) for PyTorch and TorchScript models off CPU; other formats use the precision their artifact and runtime select. Replaces the deprecated half arg. |
Additionally, the visualization arguments listed below are supported:
| Argument | Type | Default | Description |
|---|---|---|---|
show | bool | False | If True, displays the annotated images or videos in a window. Useful for immediate visual feedback during development or testing. |
show_conf | bool | True | Displays the confidence score for each detection alongside the label. Gives insight into the model's certainty for each detection. |
show_labels | bool | True | Displays labels for each detection in the visual output. Provides immediate understanding of detected objects. |
FAQ#
To count objects in a video using Ultralytics YOLO26, you can follow these steps:
- Import the necessary libraries (
cv2,ultralytics). - Define the counting region (e.g., a polygon, line, etc.).
- Set up the video capture and initialize the object counter.
- Process each frame to track objects and count them within the defined region.
Here's a simple example for counting in a region:
import cv2 from ultralytics import solutions def count_objects_in_region(video_path, output_video_path, model_path): """Count objects in a specific region within a video.""" cap = cv2.VideoCapture(video_path) assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) video_writer = cv2.VideoWriter(output_video_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360)] counter = solutions.ObjectCounter(show=True, region=region_points, model=model_path) while cap.isOpened(): success, im0 = cap.read() if not success: print("Video frame is empty or processing is complete.") break results = counter(im0) video_writer.write(results.plot_im) cap.release() video_writer.release() cv2.destroyAllWindows() count_objects_in_region("path/to/video.mp4", "output_video.avi", "yolo26n.pt")For more advanced configurations and options, check out the RegionCounter solution for counting objects in multiple regions simultaneously.
- Import the necessary libraries (
Using Ultralytics YOLO26 for object counting offers several advantages:
- Resource Optimization: It facilitates efficient resource management by providing accurate counts, helping optimize resource allocation in industries like inventory management.
- Enhanced Security: It enhances security and surveillance by accurately tracking and counting entities, aiding in proactive threat detection and security systems.
- Informed Decision-Making: It offers valuable insights for decision-making, optimizing processes in domains like retail, traffic management, and more.
- Real-time Processing: YOLO26's architecture enables real-time inference, making it suitable for live video streams and time-sensitive applications.
For implementation examples and practical applications, explore the TrackZone solution for tracking objects in specific zones.
To count specific classes of objects using Ultralytics YOLO26, you need to specify the classes you are interested in during the tracking phase. Below is a Python example:
import cv2 from ultralytics import solutions def count_specific_classes(video_path, output_video_path, model_path, classes_to_count): """Count specific classes of objects in a video.""" cap = cv2.VideoCapture(video_path) assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) video_writer = cv2.VideoWriter(output_video_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) line_points = [(20, 400), (1080, 400)] counter = solutions.ObjectCounter(show=True, region=line_points, model=model_path, classes=classes_to_count) while cap.isOpened(): success, im0 = cap.read() if not success: print("Video frame is empty or processing is complete.") break results = counter(im0) video_writer.write(results.plot_im) cap.release() video_writer.release() cv2.destroyAllWindows() count_specific_classes("path/to/video.mp4", "output_specific_classes.avi", "yolo26n.pt", [0, 2])In this example,
classes_to_count=[0, 2]means it counts objects of class0and2(e.g., person and car in the COCO dataset). You can find more information about class indices in the COCO dataset documentation.Ultralytics YOLO26 provides several advantages over other object detection models like Faster R-CNN, SSD, and previous YOLO versions:
- Speed and Efficiency: YOLO26 runs in real time, making it well suited to applications requiring high-speed inference, such as surveillance and autonomous driving.
- Accuracy: It provides high detection and tracking accuracy, reducing false positives and improving overall system reliability.
- Ease of Integration: YOLO26 exports to many deployment formats for servers, mobile, and edge devices.
- Flexibility: Supports detection, segmentation, and OBB models with track mode on top, and configurable models to meet specific use-case requirements.
Check out Ultralytics YOLO26 Documentation for a deeper dive into its features and performance comparisons.
Yes. Ultralytics YOLO26 is well suited to crowd analysis and traffic management because it detects, tracks, and counts objects in real time in dynamic environments. Example use cases include:
- Crowd Analysis: Monitor and manage large gatherings, ensuring safety and optimizing crowd flow with region-based counting.
- Traffic Management: Track and count vehicles, analyze traffic patterns, and manage congestion in real time with speed estimation.
- Retail Analytics: Analyze customer movement patterns and product interactions to optimize store layouts and improve customer experience.
- Industrial Automation: Count products on conveyor belts and monitor production lines for quality control and efficiency improvements.
Comments879
Ask a question, share your results, or help someone else.
RizwanMunawar
🎉 Big News Alert! 🚀 Ultralytics Solutions CLI is here from ultralytics>=8.3.28! Now, you can easily harness the power of advanced YOLO solutions straight from the command line. Simplify your workflow, and streamline object detection, tracking, counting, and more—all with just a few commands! Get ready to experience a whole new level of efficiency! 💥
CLI Usage Overview
yolo SOLUTIONS SOLUTION_NAME ARGS- SOLUTIONS is a mandatory keyword.
- SOLUTION_NAME (optional): Choose from ['count', 'heatmap', 'queue', 'speed', 'workout', 'analytics'].
- ARGS (optional): Use custom
arg=valuepairs, likeshow_in=True, to customize settings.
Examples
yolo solutions count show=True # For object counting yolo solutions source="path/to/video/file.mp4" # Specify a video file pathStart exploring now and let Ultralytics Solutions CLI power up your projects!
5faheem-khaskheli
i have created a line, at 15 degree angle, if a person come down it should count as in, and if a person goes up it count as out.
- down = in
- up = out but model does not work like this, model count direction is reversed.
how can i solve this?
Glenn JocherUltralytics@faheem-khaskheli to resolve the direction issue, ensure the line's orientation is correctly defined in your code. You might need to adjust the logic that determines the direction based on the line's angle. If the model's counting direction is reversed, check the implementation of the
ObjectCounterand verify the region or line points are set correctly.faheem-khaskheli
@glenn-jocher is there any way i can use ultralytics solution for this problem? i have checked the code and it is only checking
dx > 0forinelseout.
Glenn JocherUltralytics@faheem-khaskheli to address the reversed counting direction, adjust the logic in your code to correctly interpret the angle of the line. Ensure that the conditions for
dx > 0anddx < 0align with the intended "in" and "out" directions based on your line's orientation.
Boaruzhanchik
Hi,how can I use object counting with 3 lines and 3 different counters ?
line_points = [(197,164), (486,164)]Line pedestrian
line_pedestrian_1 = [(234,244),(131,218)] line_pedestrian_2 = [(490,245),(534,231)] line_pedestrian_3 = [(112,189),(154,177)] counter = object_counter.ObjectCounter() counter.set_args(view_img=False, reg_pts=line_points, classes_names=model.names, draw_tracks=False, region_thickness = 1) my code ex: im0 = counter.start_counting(frame, results) counter.extract_and_process_tracks(results) counter.in_counts counter.out_counts print(f'In counts:{counter.in_counts}') print(f'Out counts:{counter.out_counts}')
2
Glenn JocherUltralytics(edited)Hey there! 👋 For multiple lines with separate counts, create one
ObjectCounterper line and pass each frame to every counter. Each counter keeps its own in/out counts:from ultralytics import solutions line_pedestrian_1 = [(234, 244), (131, 218)] line_pedestrian_2 = [(490, 245), (534, 231)] line_pedestrian_3 = [(112, 189), (154, 177)] counters = [ solutions.ObjectCounter(region=line, model='yolo26n.pt') for line in (line_pedestrian_1, line_pedestrian_2, line_pedestrian_3) ] # For each frame: for i, counter in enumerate(counters, 1): results = counter(frame) print(f'Counter {i} - In: {results.in_count}, Out: {results.out_count}')This way, each
ObjectCounterwill track objects crossing its respective line. Hope this helps! If you have further questions, feel free to ask. Happy coding! 😊1Boaruzhanchik
Thank you for your reply! There was a problem with counting the number of custom classes, the docstring says "classes_names (dict): Classes names", I'm trying to use class_cars = { 2.0 : 'car', 5 : 'bus', 7: 'truck' } counter3.set_args(classes_names=class_cars, reg_pts=line_pedestrian_3,region_thickness = 2) but an error occurs Traceback (most recent call last): File "/home/iosif/Documents/Dev/yolo_model/yolov8_train/yolov8_tracking_car_number/tracking_5.py", line 93, in im0 = counter3.start_counting(frame, results) File "/home/iosif/.local/lib/python3.10/site-packages/ultralytics/solutions/object_counter.py", line 259, in start_counting self.extract_and_process_tracks(tracks) File "/home/iosif/.local/lib/python3.10/site-packages/ultralytics/solutions/object_counter.py", line 172, in extract_and_process_tracks self.annotator.box_label(box, label=f"{track_id}:{self.names[cls]}", color=colors(int(cls), True)) KeyError: 0.0 When trying to get a class by index, the following error occurs Traceback (most recent call last): File "/home/iosif/Documents/Dev/yolo_model/yolov8_train/yolov8_tracking_car_number/tracking_5.py", line 87, in im0 = counter1.start_counting(frame, results) File "/home/iosif/.local/lib/python3.10/site-packages/ultralytics/solutions/object_counter.py", line 259, in start_counting self.extract_and_process_tracks(tracks) File "/home/iosif/.local/lib/python3.10/site-packages/ultralytics/solutions/object_counter.py", line 172, in extract_and_process_tracks self.annotator.box_label(box, label=f"{track_id}:{self.names[cls]}", color=colors(int(cls), True)) TypeError: string indices must be integers Question: How can I select the class that I want to count?
Glenn JocherUltralytics(edited)Hi there! 👋 In current versions
ObjectCounterno longer takesclasses_namesorset_args(); class names come from the model, so thatKeyErrorcan't occur. To count only specific classes, pass their indices withclasses:from ultralytics import solutions counter3 = solutions.ObjectCounter(region=line_pedestrian_3, model='yolo26n.pt', classes=[2, 5, 7], line_width=2) results = counter3(im0) print(results.classwise_count) # e.g. {'car': {'IN': 1, 'OUT': 0}}This should resolve the errors you're seeing. Let me know if you need any more help! 😊
Boaruzhanchik
This will work to limit the total number of detectable classes, but it does not solve the problem of counting in separate areas of a single class (2 areas to count only cars and buses and 2 areas for pedestrians). An example from the code (Now I will describe why it happens) I specified a limited list of classes for tracking and when cls =17 is detected in tracking, the program crashes because this class is not specified in counter.set_args. How can I get around this limitation so that I can specify different classes for counting different areas (as I said in the example 2 only for cars, 2 only for people).
class_list_common = [0,2,5,7,17] all_dict_dict = { 0 : 'person', 2: 'car', 5: 'bus',7: 'truck'} counter1.set_args(classes_names=all_dict_dict,reg_pts=line_pedestrian_1,region_thickness = 2,line_dist_thresh=8,draw_tracks=True) results = model.track(frame,classes=class_list_common)Traceback (most recent call last): File "/home/iosif/Documents/Dev/yolo_model/yolov8_train/yolov8_tracking_car_number/tracking_5.py", line 140, in im0 = counter1.start_counting(frame, results) File "/home/iosif/.local/lib/python3.10/site-packages/ultralytics/solutions/object_counter.py", line 259, in start_counting self.extract_and_process_tracks(tracks) File "/home/iosif/.local/lib/python3.10/site-packages/ultralytics/solutions/object_counter.py", line 172, in extract_and_process_tracks self.annotator.box_label(box, label=f"{track_id}:{self.names[cls]}", color=colors(int(cls), True)) KeyError: 17.0
Glenn JocherUltralytics(edited)Hey there! 👋 To count different classes in separate areas, create multiple
ObjectCounterinstances, each with its ownregionandclasseslist. Class names come from the model automatically, andclasswise_countgives the counts per class:from ultralytics import solutions counter_cars_buses = solutions.ObjectCounter(model='yolo26n.pt', region=line_cars_buses, classes=[2, 5]) counter_pedestrians = solutions.ObjectCounter(model='yolo26n.pt', region=line_pedestrians, classes=[0]) # For each frame: im0 = counter_cars_buses(frame).plot_im im0 = counter_pedestrians(frame).plot_imThis way, each counter will only count the classes it's set up for. Happy counting! 😊
syariffortask
hello there, how about if i want my line just for in count not for out count for example i have line_pedestrian_1 = [(0,244),(131,244)] ,if all people touch this line count in will increment, because what I know so far is that the line is divided into 2 parts, one for counting in and one for counting out
Glenn JocherUltralytics(edited)Hi there! 👋
ObjectCounterreportsin_countandout_countseparately for a line, based on the direction in which tracked objects cross it. If you only need one direction, read just that value and ignore the other:from ultralytics import solutions counter = solutions.ObjectCounter(region=line_pedestrian_1, model='yolo26n.pt') results = counter(frame) print(results.in_count) # only objects crossing in the 'in' directionHappy coding! 😊
syariffortask
can you gimmi example please
Glenn JocherUltralytics(edited)Hello! Sure, I'd be happy to provide an example for setting up object counting with Ultralytics YOLO. Let's suppose you want to count cars crossing a line. Here's how you could set this up:
import cv2 from ultralytics import solutions # Open video file cap = cv2.VideoCapture('path/to/your/video.mp4') assert cap.isOpened(), 'Error loading video' # Define the line points for counting line_points = [(20, 400), (1080, 400)] # Adjust these points to fit your line # Initialize Object Counter; classes=[2] counts only cars in the COCO classes counter = solutions.ObjectCounter(model='yolo26n.pt', region=line_points, classes=[2]) # Process video and start counting while cap.isOpened(): ret, frame = cap.read() if not ret: break # End of video # Perform tracking and counting results = counter(frame) # Optionally view the frame with counts cv2.imshow('Object Counting', results.plot_im) if cv2.waitKey(1) & 0xFF == 27: # press 'ESC' to exit break # Release resources cap.release() cv2.destroyAllWindows()💡 Important:
- Adjust
line_pointsto position your counting line in the video frame. - Use
classeswith the model's class indices to count only specific object types.
Objects crossing the line in one direction increase
results.in_countand in the opposite directionresults.out_count. For multiple counting areas, create one counter per line or region.Hope this helps get you started! Let me know if there's anything else you'd like to explore. 😄
- Adjust
syariffortask
why line point not show in frame?
Glenn JocherUltralytics(edited)@syariffortask hey! If your line is not appearing on the frame, there could be a couple of things to check. Make sure
show=Trueis set when initializing yourObjectCounter(or displayresults.plot_imyourself), and verify that theregionpoints are correctly defined and fall within the frame's dimensions. Here's a quick example:from ultralytics import solutions counter = solutions.ObjectCounter( show=True, region=[(20, 400), (1080, 400)], # Make sure these points are within your frame's dimensions model='yolo26n.pt', )Make sure your setup matches your video frame size, and adjust
regionas necessary. This adjustment should help you visualize the counting line directly on your frames! 😊 Let me know if this does the trick!syariffortask
glenn tell me how you can do that? are you update class ObjectCounter logic in new version ultralytics?
Glenn JocherUltralytics(edited)Hey! 👋 Thanks for reaching out. Yes, we're constantly working on enhancing the
ObjectCounterlogic. For counting objects crossing a specific line, here's a quick example based on your requirement:import cv2 from ultralytics import solutions # Set up your video source cap = cv2.VideoCapture('path/to/video.mp4') # Initialize Object Counter for your line line_pedestrian_1 = [(0, 244), (131, 244)] # Define as per your need counter = solutions.ObjectCounter(show=True, region=line_pedestrian_1, model='yolo26n.pt', classes=[0]) while cap.isOpened(): ret, im0 = cap.read() if not ret: break # Track objects and count crossings of your line results = counter(im0) # Display cv2.imshow('Count', results.plot_im) if cv2.waitKey(1) == ord('q'): # press q to quit break cap.release() cv2.destroyAllWindows()This sets up an object counting system for pedestrians crossing
line_pedestrian_1.ObjectCounterreportsresults.in_countandresults.out_countseparately based on the direction of crossing, so you can use only the one you need. Keep up with our GitHub releases for the latest features! 🚀 Let me know if there's anything else I can help with.syariffortask
Thanks for answer my question, But Can ultralytics predict and count two frame/ two vidio source ?
Glenn JocherUltralytics(edited)@syariffortask hey! Thanks for reaching out with your question. 😊 Yes, YOLO can definitely work with two video sources simultaneously, but it would require running two instances of the video processing loop, each in its own thread or process, due to the way the code execution works.
Here's a simplified example using Python's
threadingmodule to process two videos at the same time:from threading import Thread import cv2 from ultralytics import YOLO def process_video(video_path): model = YOLO('yolo26n.pt') cap = cv2.VideoCapture(video_path) assert cap.isOpened(), 'Error reading video file' while cap.isOpened(): success, frame = cap.read() if not success: break results = model.track(frame, persist=True) # Here you could use a solutions.ObjectCounter per video # For example: im0 = counter(frame).plot_im # And then save or display im0 cap.release() # Define your video sources video_1 = 'path/to/your/first_video.mp4' video_2 = 'path/to/your/second_video.mp4' # Start processing each video in a separate thread Thread(target=process_video, args=(video_1,)).start() Thread(target=process_video, args=(video_2,)).start()Remember, depending on your system, handling two video streams simultaneously can be resource-intensive. Adjust the frame processing rate if necessary to manage system load. Hope that helps! Let me know if you have more questions. 🚀
phoenix-JM
Hello everyone; i used the following code snippet for trained yolov8n-obb model with five classes;
import cv2
from ultralytics import solutions
cap = cv2.VideoCapture("xie_035.mp4") assert cap.isOpened(), "Error reading video file"
region_points = [(20, 400), (1080, 400)] # line counting
region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360)] # rectangle region
region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360), (20, 400)] # polygon region
Video writer
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) video_writer = cv2.VideoWriter("object_counting_output.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
Initialize object counter object
counter = solutions.ObjectCounter( show=True, # display the output region=region_points, # pass region points model="D:/TRACKING_COUNTING/yolov8n-obb_ads.pt", # model="yolo11n-obb.pt" for object counting with OBB model. # classes=[0, 2], # count specific classes i.e. person and car with COCO pretrained model. tracker="bytetrack.yaml", # choose trackers i.e "bytetrack.yaml" )
Process video
while cap.isOpened(): success, im0 = cap.read()
if not success: print("Video frame is empty or processing is complete.") break results = counter(im0) # print(results) # access the output video_writer.write(results.plot_im) # write the processed frame.cap.release() video_writer.release() cv2.destroyAllWindows() # destroy all opened windows
however, it generates HBB not OBB, can someone help please.
1
Glenn JocherUltralytics(edited)@phoenix-JM thanks for reaching out!
ObjectCounterhandles OBB models natively, so you can pass an OBB model directly (e.g.model="yolo26n-obb.pt") and no special initialization is needed; please make sure you're using the latest Ultralytics version. If you need the raw OBB coordinates for custom plotting, they are available ascounter.boxesafter the call (orresults.obb.xyxyxyxywhen running a model directly). For new projects we recommend the YOLO26-OBB models as shown in our Object Counting documentation. Let us know if you need further guidance! 🚀RizwanMunawar
@phoenix-JM Hi, thanks for the question. Indeed, visualization for OBB is not supported yet. you can only plot the HBB. I will work on this feature this week. Thanks
phoenix-JM
Thank you for your reply. @glenn-Jocher can you please provide me the code snippet to do so.
phoenix-JM
@RIzwanMunawar Hello ! is there any update regarding object counting and tracking using OBB. ?
RizwanMunawar
@phoenix-JM Hi, yes, we already added the support for OBB object counting. The code is the same, no changes. Here's the demo. If you want to take a look: https://www.linkedin.com/feed/update/urn:li:activity:7327964827048411136/
mirfan-ahmad
Can I integrate ObjectCounter Pipeline with RT-DETR?
1RizwanMunawar
@mirfan-ahmad Hi, Thanks for reaching out. We currently don't support the ObjectCounting functionality for RT-DETR! At the moment we only support the Ultralytics YOLO models for Object Counting available here: https://docs.ultralytics.com/models/. Thank you!
SourceOfNootmite
Hi ultralytics team! Hope you're doing well. My knowledge of computer vision is quite limited, so apologies for dumb questions. Is it possible to train my own model based off yolov11? I attempted to do so by using a roboflow guide and their example colab notebook. I have access to the weights, one of them saying best.pt. Are weights and models completely different. Can i somehow use that and replace:
model="yolo11n.pt" with my own model.# Init ObjectCounter counter = solutions.ObjectCounter( show=True, # Display the output region=region_points, # Pass region points model="yolo11n.pt", # model="yolo11n-obb.pt" for object counting using YOLO11 OBB model. # classes=[0, 2], # If you want to count specific classes i.e person and car with COCO pretrained model. # show_in=True, # Display in counts # show_out=True, # Display out counts # line_width=2, # Adjust the line width for bounding boxes and text display )1RizwanMunawar
@SourceOfNootmite Hi! Yes, you can use any supported model for object counting, including YOLOv10, Ultralytics YOLO11, and Ultralytics YOLOv8. You can also use any model we support. If you have a YOLO11 model trained on your dataset, it will work seamlessly with the Object Counting module.
However, this feature is not currently supported if you're referring to a completely new model architecture. Thanks!
Martinnemo
hi guys.
Thanks for an awesome job with all of ultralytics!
I'm having a problem where/ how to implement the conf and model.track in the code above ? Can you help ? :)
1RizwanMunawar
@Martinnemo Hi, the implementation for object counting is available at: https://github.com/ultralytics/ultralytics/blob/main/ultralytics/solutions/object_counter.py
Thank you! 😊
Martinnemo
I mean, i following code, how do i apply the confidence function:
import cv2
from ultralytics import solutions
cap = cv2.VideoCapture("path/to/video/file.mp4") assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
Define region points
region_points = [(20, 400), (1080, 400)] # For line counting
region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360)] # For rectangle region counting
region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360), (20, 400)] # For polygon region counting
Video writer
video_writer = cv2.VideoWriter("object_counting_output.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
Init Object Counter
counter = solutions.ObjectCounter( show=True, # Display the output region=region_points, # Pass region points model="yolo11n.pt", # model="yolo11n-obb.pt" for object counting using YOLO11 OBB model. # classes=[0, 2], # If you want to count specific classes i.e person and car with COCO pretrained model. # show_in=True, # Display in counts # show_out=True, # Display out counts # line_width=2, # Adjust the line width for bounding boxes and text display )
Process video
while cap.isOpened(): success, im0 = cap.read() if not success: print("Video frame is empty or video processing has been successfully completed.") break im0 = counter.count(im0) video_writer.write(im0)
cap.release() video_writer.release() cv2.destroyAllWindows()
Glenn JocherUltralytics(edited)To apply the confidence threshold (
conf) to filter detections, you can pass it as a parameter when initializing theObjectCounter. Here's an example:counter = solutions.ObjectCounter( show=True, region=region_points, model="yolo26n.pt", conf=0.5 # Adjust the confidence threshold as needed )This will only count objects with a detection confidence score above the specified threshold (
0.5in this case). Let me know if you need further clarification!
gmantova
What is the minimal code that I can use to have:
yolo (defining parameters, if any)
bytetrack (defining parameters, if any)
get the coordinates of the boxes and id of the object
then I'll define a geometric condition, let's say behind a line etc
1
Glenn JocherUltralytics(edited)@g-i-o-r-g-i-o to achieve object tracking and counting with YOLO and ByteTrack, you can use the following minimal code setup. This will allow you to get the coordinates and IDs of detected objects and apply a geometric condition:
import cv2 from ultralytics import YOLO # Initialize model and video capture model = YOLO('yolo26n.pt') cap = cv2.VideoCapture('path/to/video.mp4') while cap.isOpened(): success, frame = cap.read() if not success: break # Run detection and tracking results = model.track(frame, persist=True, tracker='bytetrack.yaml') # Process results for r in results: for box in r.boxes: x1, y1, x2, y2 = box.xyxy[0].tolist() obj_id = int(box.id) if box.id is not None else None # Apply geometric condition here, e.g., check if behind a line # Display or save results cv2.imshow('Frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()For more detailed guidance, please visit the object counting guide.
1
gmantova
Hi, my results with "count in line" are totally off. It confuses in and out while there is only one direction, I've wasted hours and this is crazy.
It confuses in and out, and I don't understand why.
Maybe someone can take a look?
1
Glenn JocherUltralytics@g-i-o-r-g-i-o i'm sorry to hear about the issues you're facing. Please ensure that the region and line points are correctly defined in your setup. For further guidance, you can refer to our object counting documentation at https://docs.ultralytics.com/guides/object-counting/. If the problem persists, consider checking the model configuration and input parameters.
GenieV19
I have a question about the total number of objects detected vs the counts displayed. I have set the polygon region to be the entire video area, but my counts 'in' and 'out' do not equal either the number of boxes drawn and manually counted or the ID number displayed against each object, which is around double the number of boxes actually shown. Could you explain why this is and how to obtain a final number of unique objects detected? Thanks!
1
Paula DerrengerUltralytics(edited)@GenieV19 hello!
Thank you for your question and for providing detailed information. It sounds like you're experiencing a discrepancy between the number of detected objects and the counts displayed. Let's address this step-by-step:
-
Tracking IDs vs. Bounding Boxes: The IDs displayed are unique identifiers assigned to each tracked object. These IDs can appear higher than the number of visible bounding boxes due to objects entering and exiting the frame, or being temporarily occluded and then re-detected. This can lead to new IDs being assigned.
-
Counting Logic: The 'in' and 'out' counts are based on tracked objects crossing the line or entering the region, and each track ID is counted once. Ensure that your region is set correctly and that the counting logic aligns with your expectations.
-
Unique Object Counting: To get a final count of unique objects, you can collect the track IDs over the entire video. Here's a simple example:
import cv2 from ultralytics import solutions cap = cv2.VideoCapture("path/to/video/file.mp4") assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) # Define region points region_points = [(20, 400), (1080, 404), (1080, 360), (20, 360)] unique_ids = set() # Video writer video_writer = cv2.VideoWriter("object_counting_output.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # Init Object Counter counter = solutions.ObjectCounter( show=True, region=region_points, model="yolo26n.pt", ) while cap.isOpened(): success, im0 = cap.read() if not success: print("Video frame is empty or processing is complete.") break results = counter(im0) unique_ids.update(counter.track_ids) # track IDs in this frame video_writer.write(results.plot_im) cap.release() video_writer.release() cv2.destroyAllWindows()After the loop, print the result:
print(f"Total unique objects detected: {len(unique_ids)}")- Ensure Latest Versions: Please ensure you are using the latest versions of
torchandultralytics. You can upgrade them using:pip install --upgrade torch ultralytics
If the issue persists, please provide a minimum reproducible example as outlined here. This will help us investigate further.
Feel free to reach out if you have any more questions! 😊
-
TanrionTV
Hello,
I would like to use your program to count grey sections. However, I have two problems: - Firstly, when I use the tracker some detections disappear. That's why I can't think of anything to improve it. - and secondly, some tracking identifiers are reallocated to objects that have nothing to do with the initial one. I was thinking of modifying botrack so that it only assigns the same identifiers for 10 frames, for example, but I have no idea how to do this. Do you think this is feasible?
I have an i9 vPro and a Nvidia A2000.
Here's the program I use:
import cv2 from ultralytics import YOLO, solutions MODEL_PATH = r'model\best.pt' model=YOLO(MODEL_PATH) cap = cv2.VideoCapture('test_26_50mm.avi') assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) # Define line points # Conveyor #line_points = [(0, 800), (2000, 800)] # Bar line vertical line_points = [(2000, 0), (2000, 2500)] # Bar line horizontal #line_points = [(0,2200), (2500, 2200)] # Video writer video_writer = cv2.VideoWriter('results\output_bar_counting.avi', cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # Init Object Counter counter = solutions.ObjectCounter( view_img=False, reg_pts=line_points, classes_names=model.names, draw_tracks=False, track_thickness=2, line_thickness=5, line_dist_thresh = 200, view_out_counts=False ) while cap.isOpened(): success, frame = cap.read() if not success: print("Video frame is empty or video processing has been successfully completed.") break tracks = model.track(frame, persist=True, show=False, tracker = 'botsort.yaml', conf = 0.6) frame = counter.start_counting(frame, tracks) video_writer.write(frame) cap.release() video_writer.release() cv2.destroyAllWindows()I would have liked to share some pictures with you, but I couldn't. If you can help me, I would appreciate it.
1TanrionTV
maybe i can edit botsort.yaml, what do you think ?
TanrionTV
and do you why the tracking is better when count in line than when count in region ?
Glenn JocherUltralytics(edited)Hello,
Thank you for reaching out! Let's address your concerns one by one.
Disappearing Detections
The issue of disappearing detections can often be attributed to the confidence threshold or the tracking algorithm's parameters. You can experiment with the
confandiouparameters (they can be passed straight toObjectCounter, which runs the tracker) to see if adjusting these values helps retain more detections. For example, lowering the confidence threshold might help:counter = solutions.ObjectCounter(region=line_points, model="best.pt", tracker="botsort.yaml", conf=0.3, iou=0.4)Reallocation of Tracking Identifiers
Reallocation of tracking IDs can indeed be problematic. Modifying the BoT-SORT algorithm to maintain the same identifiers for a fixed number of frames is a feasible approach. However, this requires a deeper dive into the BoT-SORT implementation. You can start by editing the
botsort.yamlconfiguration file to tweak parameters liketrack_high_threshandtrack_low_thresh.Editing
botsort.yamlYou can modify the
botsort.yamlfile to adjust the tracking parameters. Here’s an example of how you might adjust thetrack_high_threshto ensure that IDs are not reallocated too frequently:# botsort.yaml track_high_thresh: 0.6 # Increase this value to make the tracker more confident before reallocating IDs track_low_thresh: 0.1 # Lower this value to keep tracks alive longerExample Code
Here’s an updated version of your code with some adjustments:
import cv2 from ultralytics import solutions cap = cv2.VideoCapture("test_26_50mm.avi") assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) # Define line points line_points = [(2000, 0), (2000, 2500)] # Video writer video_writer = cv2.VideoWriter("results/output_bar_counting.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # Init Object Counter counter = solutions.ObjectCounter( show=False, region=line_points, model=r"model/best.pt", tracker="botsort.yaml", conf=0.3, iou=0.4, line_width=5, show_out=False, ) while cap.isOpened(): success, frame = cap.read() if not success: print("Video frame is empty or video processing has been successfully completed.") break results = counter(frame) video_writer.write(results.plot_im) cap.release() video_writer.release() cv2.destroyAllWindows()Further Customization
For more advanced customization, you might need to dive into the BoT-SORT source code. If you're comfortable with Python, you can clone the BoT-SORT repository, make your changes, and then use your modified version with Ultralytics YOLO.
Additional Resources
For more detailed guidance on object counting and tracking, you can refer to our Object Counting Guide. This guide provides comprehensive information on setting up and optimizing object counting with Ultralytics YOLO.
Feel free to reach out if you have any more questions or need further assistance. Happy coding! 😊
TanrionTV
Thank you very much for your advice, I had already tried to modify the conf and iou parameters as well as the botsort.yaml file. However, it still doesn't work. I think I'm asking too much of the program, because the gray sections are very close together and the camera only records at 24fps. Thanks anyway! Or do you have other trackers to recommend?
TanrionTV
Maybe I could do some tracking in a cropped area, what do you think about that ?
Glenn JocherUltralytics(edited)@TanrionTV hello,
Thank you for your thoughtful question! Cropping the area for tracking can indeed be a useful strategy, especially when dealing with closely packed objects. By focusing on a smaller region, you can potentially improve the accuracy and consistency of the tracking.
Here’s how you can implement cropping in your existing code:
- Crop the Frame: Before passing the frame to the counter, crop it to the region of interest.
- Use Cropped Coordinates:
ObjectCountertracks the image you pass it, so define its line or region in the crop's coordinates and paste the annotated crop back into the full frame if needed.
Here’s an example of how you might modify your code to include cropping:
import cv2 from ultralytics import solutions cap = cv2.VideoCapture("test_26_50mm.avi") assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) # Define crop region (x, y, width, height) x, y, cw, ch = (500, 500, 1000, 1000) # Line points are given in cropped-frame coordinates (here a vertical line in the middle of the crop) line_points = [(500, 0), (500, 1000)] # Video writer video_writer = cv2.VideoWriter("results/output_bar_counting.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # Init Object Counter counter = solutions.ObjectCounter( show=False, region=line_points, model=r"model/best.pt", tracker="botsort.yaml", conf=0.3, iou=0.4, line_width=5, show_out=False, ) while cap.isOpened(): success, frame = cap.read() if not success: print("Video frame is empty or video processing has been successfully completed.") break # Crop, count inside the crop, then paste the annotated crop back into the full frame results = counter(frame[y : y + ch, x : x + cw]) frame[y : y + ch, x : x + cw] = results.plot_im video_writer.write(frame) cap.release() video_writer.release() cv2.destroyAllWindows()Alternative Trackers
If BoT-SORT is not meeting your needs, you might want to try ByteTrack, which is another robust tracker supported by Ultralytics. You can switch to ByteTrack by changing the
trackerparameter:counter = solutions.ObjectCounter(region=line_points, model="model/best.pt", tracker="bytetrack.yaml", conf=0.3, iou=0.4)Additional Tips
- Frame Rate: Given that your camera records at 24fps, ensure that your model and tracker can handle this frame rate efficiently. Sometimes, reducing the frame rate can help improve tracking stability.
- Experiment with Parameters: Continue experimenting with different
confandiouvalues, as well as tracker-specific parameters in the YAML files.
For more detailed guidance on object counting and tracking, you can refer to our Object Counting Guide.
Feel free to reach out if you have any more questions or need further assistance. Happy coding! 😊
TanrionTV
thank you ! but i have this error : track.boxes.xyxy[:, [0, 2]] += x ~~~~~~~~~~~~~~~~^^^^^^^^^^^ RuntimeError: Inplace update to inference tensor outside InferenceMode is not allowed.You can make a clone to get a normal tensor before doing inplace update.See https://github.com/pytorch/rfcs/pull/17 for more details.
Glenn JocherUltralytics(edited)Hello,
Thank you for your detailed feedback and for sharing your code! 😊
The inplace tensor update error comes from editing the tracked boxes after inference. In current versions you don't need to:
ObjectCounterruns the tracker itself, so you pass it the cropped image with the line defined in the crop's coordinates and paste the annotated crop back. Here’s how you can modify your code:import cv2 from ultralytics import solutions cap = cv2.VideoCapture("test_26_50mm.avi") assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) # Define crop region (x, y, width, height) x, y, cw, ch = (500, 500, 1000, 1000) # Line points are given in cropped-frame coordinates (here a vertical line in the middle of the crop) line_points = [(500, 0), (500, 1000)] # Video writer video_writer = cv2.VideoWriter("results/output_bar_counting.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # Init Object Counter counter = solutions.ObjectCounter( show=False, region=line_points, model=r"model/best.pt", tracker="botsort.yaml", conf=0.3, iou=0.4, line_width=5, show_out=False, ) while cap.isOpened(): success, frame = cap.read() if not success: print("Video frame is empty or video processing has been successfully completed.") break # Crop, count inside the crop, then paste the annotated crop back into the full frame results = counter(frame[y : y + ch, x : x + cw]) frame[y : y + ch, x : x + cw] = results.plot_im video_writer.write(frame) cap.release() video_writer.release() cv2.destroyAllWindows()Alternative Trackers
If BoT-SORT is not meeting your needs, you might want to try ByteTrack, which is another robust tracker supported by Ultralytics. You can switch to ByteTrack by changing the
trackerparameter:counter = solutions.ObjectCounter(region=line_points, model="model/best.pt", tracker="bytetrack.yaml", conf=0.3, iou=0.4)Additional Tips
- Frame Rate: Given that your camera records at 24fps, ensure that your model and tracker can handle this frame rate efficiently. Sometimes, reducing the frame rate can help improve tracking stability.
- Experiment with Parameters: Continue experimenting with different
confandiouvalues, as well as tracker-specific parameters in the YAML files.
For more detailed guidance on object counting and tracking, you can refer to our Object Counting Guide.
Feel free to reach out if you have any more questions or need further assistance. Happy coding! 😊
Thomas-CHOCHOY
Thank you for your help! Your fix gives me this error:
track.boxes.xyxy = track.boxes.xyxy.clone() # Clone the tensor to avoid the inplace update error ^^^^^^^^^^^^^^^^ AttributeError : the ‘xyxy’ property of the ‘Boxes’ object has no setterbut I managed to fix it with the following patch:
# Track the cropped image tracks1 = model.track(frame, persist=True, show=False, tracker = ‘bytetrack.yaml’, conf = 0.2,iou=0.4, vid_stride=1, augment=True, retina_masks=False) # Adjust the coordinates to the original image tracks = deepcopy(tracks1) for track in tracks : track.boxes.xyxy[ :, [0, 2]] += x track.boxes.xyxy[ :, [1, 3]] += y += yHowever, even when cropping the image, the tracker reallocates the old identifiers to the new objects. I've also tried using bytetrack by adjusting the parameters but the results are even worse. I'm starting to run out of ideas. Is it possible to send you the video (20mo), maybe you'll see it more clearly than I do.
Thank you very much for your advice!
Thomas-CHOCHOY
I've added you to my "bar_counting" project on github so you can see the video if you want
Glenn JocherUltralytics(edited)Hello,
Thank you for your detailed explanation and for sharing your code! It's great to see your dedication to solving this issue.
Regarding your current challenges with tracking and identifier reallocation, it seems like you’ve already tried several approaches, including modifying the
confandiouparameters and experimenting with different trackers. Your idea of cropping the image is a good one, and it’s excellent that you managed to fix the tensor update issue.Further Suggestions
-
Adjusting Tracker Parameters: Since you’ve already tried adjusting the
confandiouparameters, another approach could be to fine-tune other parameters in thebotsort.yamlorbytetrack.yamlconfiguration files. For example, you can try increasing thetrack_high_threshandtrack_low_threshvalues to make the tracker more conservative in reassigning IDs. -
Using a Different Tracker: If BoT-SORT and ByteTrack are not yielding satisfactory results, you might want to explore other tracking algorithms. While Ultralytics primarily supports BoT-SORT and ByteTrack, you can integrate other trackers with custom code.
-
Frame Rate and Resolution: Given that your camera records at 24fps, you might want to experiment with reducing the frame rate or resolution to see if it improves tracking stability. Sometimes, processing fewer frames can help the tracker maintain consistent IDs.
Sharing the Video
If you’re comfortable sharing the video, it would indeed help in diagnosing the issue more accurately. You can upload the video to a cloud storage service (like Google Drive or Dropbox) and share the link here. This way, we can take a closer look and provide more targeted advice.
Example Code with Cropping
In current versions
ObjectCounterruns the tracker itself, so you can pass it the cropped image directly with the line defined in the crop's coordinates, with no tensor cloning needed:import cv2 from ultralytics import solutions cap = cv2.VideoCapture("test_26_50mm.avi") assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) # Define crop region (x, y, width, height) x, y, cw, ch = (500, 500, 1000, 1000) # Line points are given in cropped-frame coordinates (here a vertical line in the middle of the crop) line_points = [(500, 0), (500, 1000)] # Video writer video_writer = cv2.VideoWriter("results/output_bar_counting.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # Init Object Counter counter = solutions.ObjectCounter( show=False, region=line_points, model=r"model/best.pt", tracker="botsort.yaml", conf=0.3, iou=0.4, line_width=5, show_out=False, ) while cap.isOpened(): success, frame = cap.read() if not success: print("Video frame is empty or video processing has been successfully completed.") break # Crop, count inside the crop, then paste the annotated crop back into the full frame results = counter(frame[y : y + ch, x : x + cw]) frame[y : y + ch, x : x + cw] = results.plot_im video_writer.write(frame) cap.release() video_writer.release() cv2.destroyAllWindows()Additional Resources
For more detailed guidance on object counting and tracking, you can refer to our Object Counting Guide.
Feel free to share the video link or any additional details here, and we’ll do our best to assist you further. Thank you for your patience and persistence!
-
Thomas-CHOCHOY
Thanks, I'll give it a try! I published on github the video, my model and some examples of programs that I tried but did not work. https://github.com/Tanrion/bar_counting
Glenn JocherUltralytics(edited)Hello,
Thank you for sharing the details and the GitHub link to your project! I appreciate your efforts in providing a comprehensive example. This will help us better understand the issue and provide more targeted assistance.
Next Steps
-
Reproducible Example: Please ensure that the provided code and model are using the latest versions of
torchandultralytics. You can update your packages using:pip install --upgrade torch ultralytics -
Investigate Tracking Parameters: Since you've already tried adjusting
confandiouparameters, another approach could be to fine-tune other parameters in thebotsort.yamlorbytetrack.yamlconfiguration files. For example, increasingtrack_high_threshandtrack_low_threshvalues might help in maintaining consistent IDs. -
Cropping Strategy: Cropping the frame to focus on a specific region is a good strategy. Ensure that the counting line is defined in the crop's coordinates. Note that
ObjectCounternow runs the tracker itself, so you can pass it the cropped image with the line defined in the crop's coordinates and no tensor cloning is needed. Here’s a refined version of your code:import cv2 from ultralytics import solutions cap = cv2.VideoCapture("test_26_50mm.avi") assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) # Define crop region (x, y, width, height) x, y, cw, ch = (500, 500, 1000, 1000) # Line points are given in cropped-frame coordinates (here a vertical line in the middle of the crop) line_points = [(500, 0), (500, 1000)] # Video writer video_writer = cv2.VideoWriter("results/output_bar_counting.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # Init Object Counter counter = solutions.ObjectCounter( show=False, region=line_points, model=r"model/best.pt", tracker="botsort.yaml", conf=0.3, iou=0.4, line_width=5, show_out=False, ) while cap.isOpened(): success, frame = cap.read() if not success: print("Video frame is empty or video processing has been successfully completed.") break # Crop, count inside the crop, then paste the annotated crop back into the full frame results = counter(frame[y : y + ch, x : x + cw]) frame[y : y + ch, x : x + cw] = results.plot_im video_writer.write(frame) cap.release() video_writer.release() cv2.destroyAllWindows() -
Alternative Trackers: If BoT-SORT and ByteTrack are not yielding satisfactory results, you might want to explore other tracking algorithms. While Ultralytics primarily supports BoT-SORT and ByteTrack, you can integrate other trackers with custom code.
Additional Resources
For more detailed guidance on object counting and tracking, you can refer to our Object Counting Guide.
Feel free to share any additional details or updates here, and we’ll do our best to assist you further. Thank you for your patience and persistence! 😊
-
Thomas-CHOCHOY
my github is only useful if you look at it. If you had looked at it, you would have seen that I have more programs, between "line counter", "region counter", "cropped counter" and they don't work. What's more, I've posted a video of my project on github, so maybe you'll see it more clearly. On the other hand, if you have any other trackers to suggest, I'd love to hear from you. Personally, I don't know of any others that perform as well. Thank you very much for your help!
Glenn JocherUltralytics(edited)Hello @Tanrion,
Thank you for sharing your GitHub repository and the video. I appreciate your detailed explanation and the effort you've put into troubleshooting the issue.
Reviewing Your Code and Video
I've reviewed the programs in your repository, including the "line counter," "region counter," and "cropped counter." It's clear that you've tried multiple approaches to solve the problem.
Tracking Identifiers Issue
Regarding the reallocation of tracking identifiers, this can be a challenging issue with object tracking. Here are a few suggestions to improve the tracking consistency:
-
Adjust Tracker Parameters:
- BoT-SORT: You can try increasing the
track_high_threshandtrack_low_threshvalues in thebotsort.yamlconfiguration file to make the tracker more conservative in reassigning IDs. - ByteTrack: Similarly, adjust the parameters in the
bytetrack.yamlfile.
- BoT-SORT: You can try increasing the
-
Alternative Trackers: While BoT-SORT and ByteTrack are among the best, you might want to explore other trackers like DeepSORT or FairMOT. These are not natively supported by Ultralytics but can be integrated with some custom coding.
-
Frame Rate and Resolution: Reducing the frame rate or resolution might help improve tracking stability. Sometimes, processing fewer frames can help the tracker maintain consistent IDs.
Cropping Strategy
Your idea of cropping the image is excellent. It helps focus on a specific region, potentially improving tracking accuracy. In current versions
ObjectCounterruns the tracker itself, so you can pass it the cropped image with the line defined in the crop's coordinates, with no tensor cloning needed:import cv2 from ultralytics import solutions cap = cv2.VideoCapture("test_26_50mm.avi") assert cap.isOpened(), "Error reading video file" w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) # Define crop region (x, y, width, height) x, y, cw, ch = (500, 500, 1000, 1000) # Line points are given in cropped-frame coordinates (here a vertical line in the middle of the crop) line_points = [(500, 0), (500, 1000)] # Video writer video_writer = cv2.VideoWriter("results/output_bar_counting.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h)) # Init Object Counter counter = solutions.ObjectCounter( show=False, region=line_points, model=r"model/best.pt", tracker="botsort.yaml", conf=0.3, iou=0.4, line_width=5, show_out=False, ) while cap.isOpened(): success, frame = cap.read() if not success: print("Video frame is empty or video processing has been successfully completed.") break # Crop, count inside the crop, then paste the annotated crop back into the full frame results = counter(frame[y : y + ch, x : x + cw]) frame[y : y + ch, x : x + cw] = results.plot_im video_writer.write(frame) cap.release() video_writer.release() cv2.destroyAllWindows()Further Assistance
If you continue to face issues, please ensure you are using the latest versions of
torchandultralytics. You can update your packages using:pip install --upgrade torch ultralyticsFor more detailed guidance on object counting and tracking, you can refer to our Object Counting Guide.
Feel free to share any additional details or updates here, and we’ll do our best to assist you further. Thank you for your patience and persistence! 😊
-

