ultralytics / ultralytics

Ultralytics YOLO11 🚀
https://docs.ultralytics.com
GNU Affero General Public License v3.0
30.02k stars 5.83k forks source link

Tracking ID Keep Changing! WHY? #4472

Closed dedoogong closed 1 year ago

dedoogong commented 1 year ago

Search before asking

YOLOv8 Component

Other

Bug

I tried the default yolo8n-seg track(bottrack) using webcam and I found the ids are keep changing whenever some new objects are added or detector or tracker failed to detect/track some existing objects. Basically, tracker must assign same ID to the same obejct for every frame in any situation. I've reviewed your code and I think you already implemented location based kalman filter and use kind of Hungarian algorithm to use appearance(feature like sparese optical flow) cost and location based cost for tracking. But I'm not sure why the id is keep changing even when there is no change in the view. For example, there are 2 same chairs in front of the webcam, ID 0- chair and ID 1-chair is keep switching between the chairs. Isn't it a bug??

Thank you!

Environment

Minimal Reproducible Example

from ultralytics import YOLO

# Load a model 
model = YOLO("yolov8n-seg.pt")  # load an official segmentation model 

# Track with the model
results = model.track(source=rgb, show=True, stream=True, persist=True, tracker="botsort.yaml") 
while 1: #,hhalf=True,imgsz=1920,save_txt=True,save_conf=True,save=True,conf=0.25,iou=0.5)
        for r in results:
             continue

Additional

No response

Are you willing to submit a PR?

github-actions[bot] commented 1 year ago

👋 Hello @dedoogong, thank you for your interest in YOLOv8 🚀! We recommend a visit to the YOLOv8 Docs for new users where you can find many Python and CLI usage examples and where many of the most common questions may already be answered.

If this is a 🐛 Bug Report, please provide a minimum reproducible example to help us debug it.

If this is a custom training ❓ Question, please provide as much information as possible, including dataset image examples and training logs, and verify you are following our Tips for Best Training Results.

Join the vibrant Ultralytics Discord 🎧 community for real-time conversations and collaborations. This platform offers a perfect space to inquire, showcase your work, and connect with fellow Ultralytics users.

Install

Pip install the ultralytics package including all requirements in a Python>=3.8 environment with PyTorch>=1.8.

pip install ultralytics

Environments

YOLOv8 may be run in any of the following up-to-date verified environments (with all dependencies including CUDA/CUDNN, Python and PyTorch preinstalled):

Status

Ultralytics CI

If this badge is green, all Ultralytics CI tests are currently passing. CI tests verify correct operation of all YOLOv8 Modes and Tasks on macOS, Windows, and Ubuntu every 24 hours and on every commit.

glenn-jocher commented 1 year ago

@dedoogong hello, thank you for reaching out and providing detailed information about the issue.

In multi-object tracking (MOT), assigning IDs to detected objects involves challenging decisions, especially when encountering occlusions or abrupt changes in object motion. The YOLOv8n-seg model utilizes a combination of appearance and location information in a Hungarian algorithm framework for object tracking. However, factors like repetitive or similar-looking objects, rapid scene changes, or temporary occlusions can sometimes cause the IDs of tracked objects to swap or change.

As for your situation with two identical chairs, the tracker might be having difficulties distinguishing between them, causing the ID swapping. The feature descriptors used here may not be sufficient to discern such identical objects. Remember, object tracking in cluttered or complex scenes is an active research area, and it is normal to encounter some challenges with robust ID assignment in certain cases.

That being said, we're always looking for ways to improve the framework and appreciate your feedback. Please know we are continually working to enhance the accuracy and stability of the tracker.

Regarding your willingness to submit a PR, any insights or improvements you can contribute are always welcome.

To sum up, it's not a bug but, rather, inherent to the complexities of multi-object tracking.

Your ongoing support and understanding is highly appreciated!

andyg2 commented 5 months ago

One method I've used for wandering IDs is a pair of 50% xy ofset square grids - approx large enough to hold half of one object as a rule of thumb. After calculating the centroid of the object determine which grid has the centroid furthest from its boundary lines (closest to the center of one of the grid squares which protects against centroids flip-flopping across into nearby grid boundaries). Then use the grid references as an index of the object IDs.

For none static objects I also permit an ID to move into any of the 8 neighboring grid references. You can use a variable grid for perspective as I do with fish eye cameras. This for me is enough to reduce wandering IDs by over 90% and the overhead is just code. Unfortunately I can't share the code as it's not mine but this description should be enough to get started.

I also use this for people going under bridges (occlusion), I just don't put any grids over the bridge part.

Oh I only allow moving objects 'into' the grid from the edges of that grid - just make sure the confidence is low enough to catch every object.

glenn-jocher commented 5 months ago

@andyg2, thanks for sharing your innovative method for reducing wandering IDs in object tracking! 🚀 It sounds like a practical solution that cleverly uses spatial relationships to enhance tracking stability, especially in dynamic scenarios. The idea of leveraging a grid system to determine object IDs based on their centroid positions and allowing for movement within adjacent grid references is insightful. Your approach to handling occlusions, as with people going under bridges, by omitting certain grid areas is also a clever workaround.

Although it's a bummer you can't share the code, your detailed description certainly sets a solid foundation for others to experiment with similar strategies. For those interested in implementing something based on this concept, a basic starting point in Python might look something like this:

# Pseudocode - adapt as needed
def assign_grid_id(centroid, grid):
    # Determine which grid centroid is closest to and assign/update ID based on grid logic
    pass

# Assuming `centroids` and `grids` are defined
for centroid in centroids:
    grid_id = assign_grid_id(centroid, grids)
    # Update tracking logic based on `grid_id`

This snippet doesn't cover all the intricacies of your method, but it might help others begin exploring this direction. The dynamic handling of object IDs through grid analysis sounds like a great alternative for tackling common tracking challenges.

Thanks for contributing your insights to the community! Your method indeed provides a creative way to tackle wandering IDs with an efficient coding approach. Looking forward to seeing more of such innovative solutions in the field! 🌟