Tracking id for ByteTracker not being able to reset
Closed this issue · 5 comments
Search before asking
- I have searched the Yolo Tracking issues and discussions and found no similar questions.
Yolo Tracking Component
Tracking
Bug
Search before asking
- I have searched the Yolo Tracking issues and found no similar bug report.
Question
I am using the bytetracker as follows
from boxmot import DeepOCSORT,BYTETracker,BoTSORT,HybridSORT
tracker = BYTETracker()
tracks = tracker.update(dets, og_frame)
for track in tracks:
track_id = track[4]
I want to reset the tracker id back to 1 again when a specific process being manually stopped and started. It is integrated to a PyQT app which runs the camera stream. So when the camera stream is turned off and started again, the track id needs to be reset to 1 again.
I tried doing the following
- Reset the tracker by reinitializing the tracker = BYTETracker()
- I tried initializing tracker.tracks = []
-
tracker.tracks=[] tracker.trackers = [] tracker._next_id = 1
- tracker.init()
(Pdb) tracker.__dict__
{'det_thresh': 0.45, 'max_age': 30, 'min_hits': 3, 'iou_threshold': 0.3, 'per_class_active_tracks': {}, 'frame_count': 55, 'active_tracks': [<boxmot.trackers.bytetrack.byte_tracker.STrack object at 0x76c12e0c3cd0>], 'lost_stracks': [<boxmot.trackers.bytetrack.byte_tracker.STrack object at 0x76c12e0c1450>], 'removed_stracks': [<boxmot.trackers.bytetrack.byte_tracker.STrack object at 0x76c12e0c3610>, <boxmot.trackers.bytetrack.byte_tracker.STrack object at 0x76c12e0c3f10>, <boxmot.trackers.bytetrack.byte_tracker.STrack object at 0x76c12e0c3e50>, <boxmot.trackers.bytetrack.byte_tracker.STrack object at 0x76c12e0c01f0>], 'frame_id': 0, 'track_buffer': 25, 'per_class': False, 'track_thresh': 0.45, 'match_thresh': 0.8, 'buffer_size': 25, 'max_time_lost': 25, 'kalman_filter': <boxmot.motion.kalman_filters.bytetrack_kf.KalmanFilter object at 0x76c22db53760>}
(Pdb) n
> /home/dt/Projects/Work/greenox/hwt/trackingfordelta/anycamyolov8_boxmotsort.py(487)<module>()
-> red_color = (0, 0, 255) # (B, G, R)
(Pdb) tracker.__dict__
{'det_thresh': 0.45, 'max_age': 30, 'min_hits': 3, 'iou_threshold': 0.3, 'per_class_active_tracks': {}, 'frame_count': 0, 'active_tracks': [], 'lost_stracks': [], 'removed_stracks': [], 'frame_id': 0, 'track_buffer': 25, 'per_class': False, 'track_thresh': 0.45, 'match_thresh': 0.8, 'buffer_size': 25, 'max_time_lost': 25, 'kalman_filter': <boxmot.motion.kalman_filters.bytetrack_kf.KalmanFilter object at 0x76c12e0c3610>}
the tracker seems to get initialized, but the track id allocated in the next update is still the next id and not 1
array([[ 155.93, 126.82, 235.94, 263.22, 7, 0.95278, 3, 0]])
But it seems to be storing the last tracker in cache or somewhere and it restarts from the last id before the camera stream was stopped.
Im trying to dbug and figure out where it retains the previous track_id etc, because after init all variables seemed to be getting repopulated from the BaseTracker class.
Ideally on reset or when a new track is started it should reset to 1 so that a new stream can be tracked anew. I have referenced this in issue
Any help would be appreciated! Thanks in advance!
Environment
boxmot - 10.0.52
torch - 2.3.0+cu118
Minimal Reproducible Example
import cv2, sys
import datetime
from time import sleep
from ultralytics import YOLO
from threading import Thread
#Boxmot Sort Code
from boxmot import DeepOCSORT,BYTETracker,BoTSORT,HybridSORT
import torch
import numpy as np
import time
from pathlib import Path
GREEN = (0, 255, 0)
tracker = BYTETracker(
)
sleeprate = 1.0
def callback_sleeprate(data):
global sleeprate
sleeprate = data.data
# YOLO Setup
model = YOLO("boxdatasetkit8m_jan1724.pt")
# vid_capture = cv2.VideoCapture(-1)
vid_capture = cv2.VideoCapture("output_video.mp4")
# Ros nodes
try:
print("Waiting for buffer Data to start robot activity")
while True:
exitnow = False
bufferdata = 1
firstDetect = True
if bufferdata == 1:
objsent = False
fps = vid_capture.get(5)
while not objsent:
validobjects = 0
start = datetime.datetime.now()
ret, frame = vid_capture.read()
# og_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
og_frame = frame.copy()
# Just Detection
detections = model(frame,conf=0.8)[0]
objs = {}
objcount = 0
boxes = detections.boxes
cls = boxes.cls.tolist()
xyxy = boxes.xyxy
conf = boxes.conf
pred_cls = np.array(cls)
conf = conf.detach().cpu().numpy()
bboxes_xyxy = xyxy.cpu().numpy()
# Prepare dets array for the tracker
dets = []
for i in range(len(bboxes_xyxy)):
x1, y1, x2, y2 = bboxes_xyxy[i].tolist()
clsval = cls[i]
confidence = conf[i]
if float(confidence) < 0.8:
continue
dets.append([x1, y1, x2, y2, confidence, clsval])
dets = np.array(dets)
if dets.shape[0] > 0:
# Update tracker
tracks = tracker.update(dets, og_frame)
for track in tracks:
track_id = track[4]
# if track_id >= 4 and track_id <= 12:
# import pdb;pdb.set_trace()
# tracker.__init__()
# tracker.tracks=[]
# tracker.trackers = []
# tracker._next_id = 1
# tracker = []
# from boxmot import BYTETracker
# tracker = BYTETracker()
# tracker.active_tracks=[]
# tracker.removed_stracks = []
# tracker.frame_count = 1
color_id = track_id % 3
if color_id == 0:
color = (0, 0, 255) # Red
elif color_id == 1:
color = (255, 0, 0) # Blue
else:
color = (0, 255, 0) # Green
text_color = (0, 0, 0) # Black
cv2.putText(og_frame, f"{track_id}", (int(track[0]) + 10, int(track[1]) - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, text_color, 1, cv2.LINE_AA)
for data in detections.boxes.data.tolist():
confidence = data[4]
class_val = int(data[5])
# if the confidence is greater than the minimum confidence,
# draw the bounding box on the frame
xmin, ymin, xmax, ymax = int(data[0]), int(data[1]), int(data[2]), int(data[3])
# Pixel to mm calculations
cpx=int(xmin+xmax)//2
cpy=int(ymin+ymax)//2
objarea = (xmax-xmin) * (ymax-ymin)
x,y = cpx,cpy
cv2.circle(og_frame,(320,240),10,(0,255,255),-1)
cv2.circle(og_frame,(cpx,cpy),10,(0,0,255),-1)
cv2.rectangle(og_frame, (xmin, ymin) , (xmax, ymax), GREEN, 2)
# end time to compute the fps
end = datetime.datetime.now()
# show the time it took to process 1 frame
total = (end - start).total_seconds()
# print(f"Time to process 1 frame: {total * 1000:.0f} milliseconds")
fps = f"FPS: {1 / total:.2f}"
cv2.putText(og_frame, fps, (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 8)
cv2.imshow("video", og_frame)
# Save images
current_time = time.time()
# Save images
if cv2.waitKey(1) == ord('q'):
exitnow = True
break
validobjects = 0
if exitnow:
break
# Buffer data is 0, execution going on, no coordinates will be sent
print("Rospy Has Shutdown")
except KeyboardInterrupt:
print("Exiting")
You can try this sample with any video and default yolov8 model.
Facing the same issue @mikel-brostrom .could you guide us ?
You should now be able to do:
bytetrack = BYTETracker()
bytetrack.BaseTrack.clear_count()
Hi thank you for your response!
Will it be part of the next release? Also the same needs to be done for botsort too, it also does'nt reset count.
For BoTSORT this would work the same
👋 Hello, this issue has been automatically marked as stale because it has not had recent activity. Please note it will be closed if no further activity occurs.
Feel free to inform us of any other issues you discover or feature requests that come to mind in the future. Pull Requests (PRs) are also always welcomed!