{"id":21802466,"url":"https://github.com/qengineering/bytetrack_with_labels","last_synced_at":"2025-04-13T18:41:56.135Z","repository":{"id":219924620,"uuid":"750282391","full_name":"Qengineering/ByteTrack_with_labels","owner":"Qengineering","description":"A thread safe implementation of ByteTrack with (COCO) labels.","archived":false,"fork":false,"pushed_at":"2024-02-26T10:49:23.000Z","size":9586,"stargazers_count":13,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T09:23:04.331Z","etag":null,"topics":["bytetrack","bytetracker","coco","labels","object-tracker","object-tracking","thread-safety","tracking"],"latest_commit_sha":null,"homepage":"https://qengineering.eu/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Qengineering.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-30T10:46:51.000Z","updated_at":"2025-02-25T14:53:15.000Z","dependencies_parsed_at":"2024-01-30T12:02:10.057Z","dependency_job_id":"a2a9491d-5c3a-42cd-acc6-5e31be40a182","html_url":"https://github.com/Qengineering/ByteTrack_with_labels","commit_stats":null,"previous_names":["qengineering/bytetrack_with_labels"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qengineering%2FByteTrack_with_labels","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qengineering%2FByteTrack_with_labels/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qengineering%2FByteTrack_with_labels/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qengineering%2FByteTrack_with_labels/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Qengineering","download_url":"https://codeload.github.com/Qengineering/ByteTrack_with_labels/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248764418,"owners_count":21158079,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bytetrack","bytetracker","coco","labels","object-tracker","object-tracking","thread-safety","tracking"],"created_at":"2024-11-27T11:28:53.412Z","updated_at":"2025-04-13T18:41:56.107Z","avatar_url":"https://github.com/Qengineering.png","language":"C++","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=CPZTM5BB3FCYL"],"categories":[],"sub_categories":[],"readme":"# ByteTrack with (COCO) labels\n\n![output image]( https://qengineering.eu/github/BYTEtrackGraph.jpg )\n\n## ByteTrack expanded with COCO or VOC labels. \u003cbr/\u003e\n[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\u003cbr/\u003e\u003cbr/\u003e\n\n------------\n\n## Introduction.\nByteTrack is one of the best tracker in the field. However, it has two shortcomings.\n\n#### Thread safety.\nThe C++ code uses function calls to static class routines.\u003cbr\u003e\nIt works well if you have one tracker running. With multiple instances of the trackers, you might face unpredictable situations.\u003cbr\u003e\nBecause every tracker, every thread, shares the same static variables, it can lead to rare conditions.\u003cbr\u003e\nIn this C++ implementation, we have removed all these potentially harmful calls.\u003cbr\u003e\n\n#### Lack of labels.\nByteTrack only works with the bounding boxes of the objects and their probability. It takes no notion of the object class.\u003cbr\u003e\nIn most cases, it is no problem. Often, you have only one class in which you are interested, like pedestrians or football players.\u003cbr\u003e\nHowever, on some occasions, the bounding boxes of different objects might coincide, as can be seen in the animation below.\u003cbr\u003e\u003cbr\u003e\n![](https://qengineering.eu/github/InTrack.gif)\u003cbr\u003e\nA person is being marked as a car just because, at some point, their bounding boxes are (almost) identical.\u003cbr\u003e\u003cbr\u003e\n\nWe add the object class `obj_id` as an additional variable to the STrack class.\u003cbr\u003e\n```cpp\n//---------------------------------------------------------------------------\nclass STrack\n{\npublic:\n\tSTrack(Ttlwh tlwh_, float score, int obj_id, BYTETracker* TrackInstance);\n\t~STrack();\n......\npublic:\n......\n\tint obj_id;\n\n\tTtlwh _tlwh;\n\tTtlwh tlwh;\n\tTtlbr tlbr;\n......\nprivate:\n    BYTETracker* myTrackInstance;               // Reference to BYTETracker instance\n\tbyte_kalman::KalmanFilter kalman_filter;\n};\n//---------------------------------------------------------------------------\n```\nDuring Update(), this integer is filled with the object label.\u003cbr\u003e\nIt doesn't matter which kind of set you use. COCO, VOC or another.\u003cbr\u003e\n```ccp\n//---------------------------------------------------------------------------\nvoid BYTETracker::update(vector\u003cbbox_t\u003e\u0026 objects)\n{\n\n\t////////////////// Step 1: Get detections //////////////////\n\tthis-\u003eframe_id++;\n......\n\tif (objects.size() \u003e 0)\n\t{\n\t\tfor(size_t i = 0; i \u003c objects.size(); i++){\n\t\t\tTtlwh a;\n\t\t\ta.t=objects[i].x;\n\t\t\ta.l=objects[i].y;\n\t\t\ta.w=objects[i].w;\n\t\t\ta.h=objects[i].h;\n\n\t\t\tfloat score = objects[i].prob;\n\t\t\tint obj_id  = objects[i].obj_id;\n\n\t\t\tSTrack strack(a, score, obj_id, this);\n\t\t\tif (score \u003e= track_thresh) detections.push_back(strack);\n\t\t\telse  \t\t\t   detections_low.push_back(strack);\n\t\t}\n\t}\n```\nThe distinction between object classes is done by giving a penalty in the IoU calculus when classes don't match.\u003cbr\u003e\n```cpp\nfor (size_t k = 0; k \u003c btlbrs.size(); k++){\n    vector\u003cfloat\u003e ious_tmp;\n    float box_area = (btlbrs[k].b - btlbrs[k].t + 1)*(btlbrs[k].r - btlbrs[k].l + 1);\n    for (size_t n = 0; n \u003c atlbrs.size(); n++){\n        float iw = min(atlbrs[n].b, btlbrs[k].b) - max(atlbrs[n].t, btlbrs[k].t) + 1;\n        if (iw \u003e 0){\n            float ih = min(atlbrs[n].r, btlbrs[k].r) - max(atlbrs[n].l, btlbrs[k].l) + 1;\n            if(ih \u003e 0){\n                float ua = (atlbrs[n].b - atlbrs[n].t + 1)*(atlbrs[n].r - atlbrs[n].l + 1) + box_area - iw * ih;\n                ious[n][k] = iw * ih / ua;\n\n                if(atlbrs[n].c!=btlbrs[k].c){    //not same object class? -\u003e penalty\n                    ious[n][k] *=0.5;\n                }\n            }\n            else ious[n][k] = 0.0;\n        }\n        else ious[n][k] = 0.0;\n    }\n}\n```\n\n![](https://qengineering.eu/github/OutTrack.gif)\u003cbr\u003e\n\n\n#### Final remarks.\n\nThe original code uses `std::vector\u003cfloat\u003e` to hold the bounding boxes.\u003cbr\u003e\nWe use a simple `struct` because of the fixed number of elements.\u003cbr\u003e\nA `std::vector` requires more overhead. And the code becomes more readable.\u003cbr\u003e\u003cbr\u003e\nWe only adapted the C++ implementation. Python isn't supported. If someone likes to port the code to Python, be our guest.\u003cbr\u003e\n\n```\nBYTETrack\n├── include\n│   ├── BYTETracker.h\n│   ├── dataType.h\n│   ├── kalmanFilter.h\n│   ├── lapjv.h\n│   └── STrack.h\n├── LICENSE\n├── README.md\n└── src\n    ├── BYTETracker.cpp\n    ├── kalmanFilter.cpp\n    ├── lapjv.cpp\n    ├── STrack.cpp\n    └── utils.cpp\n```\n\n\n------------\n\n[![paypal](https://qengineering.eu/images/TipJarSmall4.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=CPZTM5BB3FCYL) \n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqengineering%2Fbytetrack_with_labels","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqengineering%2Fbytetrack_with_labels","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqengineering%2Fbytetrack_with_labels/lists"}