mikel-brostrom / boxmot

BoxMOT: pluggable SOTA tracking modules for segmentation, object detection and pose estimation models
GNU Affero General Public License v3.0
6.71k stars 1.71k forks source link

Duplicate Areas #1638

Closed m7mdhka closed 1 month ago

m7mdhka commented 1 month ago

Search before asking

Yolo Tracking Component

Tracking

Bug

Hi, I have a problem, and I don't know where it is from! When I detect a vehicle, it's still saving the oldest frames (I can see it in visualization process),

Example: image

Environment

Python 3.12.6 boxmot 10.0.81

Minimal Reproducible Example

This is my code:

def yolo_predictions_to_dets(predictions):
    dets_list = []

    for pred in predictions:
        bboxes = pred.boxes.xyxy.cpu().numpy()
        confs = pred.boxes.conf.cpu().numpy()
        clss = pred.boxes.cls.cpu().numpy()

        dets = np.hstack([bboxes, confs.reshape(-1, 1), clss.reshape(-1, 1)])
        dets_list.append(dets)

    return np.vstack(dets_list) if dets_list else np.empty((0, 6))

tracked_objects = self.tracker.update(yolo_predictions_to_dets(predictions), source)

model:

        elif self.model_type == ObjectDetectionModels.YOLOv10:
            return self.model.predict(
                source=source, 
                stream_buffer=False, 
                **kwargs
            )

I'm using StrongSORT

mikel-brostrom commented 1 month ago

Please provide the full script. Visualization code included

m7mdhka commented 1 month ago
    @staticmethod
    def create_strong_sort(
        config: Dict[str, Any], 
        weight_path: Path
    ) -> Any:
        from boxmot.trackers.strongsort.strong_sort import StrongSORT
        return StrongSORT(
            model_weights=weight_path,
            device=torch.device("cpu"),
            fp16=False,
            max_dist=config.STRONG_SORT.MAX_DIST,
            max_iou_dist=config.STRONG_SORT.MAX_IOU_DISTANCE,
            max_age=config.STRONG_SORT.MAX_AGE,
            n_init=config.STRONG_SORT.N_INIT,
            nn_budget=config.STRONG_SORT.NN_BUDGET,
            mc_lambda=config.STRONG_SORT.MC_LAMBDA,
            ema_alpha=config.STRONG_SORT.EMA_ALPHA,
        )
     def process_frame(self, frame):
        if not isinstance(frame, np.ndarray):
            raise TypeError(f"Expected frame to be a numpy.ndarray, got {type(frame)}")

        allowed_classes = SETTINGS.OBJECT_DETECTION.ALLOWED_CLASSES
        if not isinstance(allowed_classes, list):
            raise TypeError(f"Expected SETTINGS.ALLOWED_CLASSES to be a list, got {type(allowed_classes)}")

        detection_results = self.model.track(frame, classes=allowed_classes, verbose=False, max_det=SETTINGS.OBJECT_DETECTION.MAX_DETECTIONS)

        annotated_frame = frame.copy()

        if (detection_results is not None 
            and detection_results[0] is not None 
            and detection_results[0].boxes is not None 
            and detection_results[0].boxes.id is not None
        ):
            try:
                frame_detections = detection_results[0].cpu().numpy().boxes
            except:
                frame_detections = detection_results[0]

            if self.annotate_vehicles:
                try:
                    annotated_frame = detection_results[0].plot(conf=True, labels=True)
                except:
                    annotated_frame = annotated_frame

The track method you see above is a custom one:

     def track(self, source: np.ndarray, **kwargs: Any) -> Union[Any, List[Dict[str, torch.Tensor]]]:
        if (isinstance(self.tracker, str) and (self.tracker in YOLO_DEFAULT_TRACKERS or os.path.isfile(self.tracker))) or self.tracker is None:
            return self.track_with_built_in(source, **kwargs)
        else:
            predictions = self.predict(source=source, **kwargs)

            if isinstance(self.tracker, DeepSORT):
                detections, conf, oids = self._extract_detections(predictions)
                tracked_objects = self.tracker.update(detections, conf, oids, source)
            elif isinstance(self.tracker, (StrongSORT, BoTSORT)):
                tracked_objects = self.tracker.update(yolo_predictions_to_dets(predictions), source)
            elif isinstance(self.tracker, SMILEtrack):
                bboxs = predictions[0].boxes.data.cpu().numpy() if len(predictions) > 0 else np.empty((0, 4))
                tracked_objects = self.tracker.update(bboxs, source)

            return self._format_tracking_results(tracked_objects, source, self.tracker_type, self.model.names)

the return results I format it in this code:

    @staticmethod
    def _format_tracking_results(
        tracked_outputs, 
        frame, 
        tracker_type,
        model_names = None
    ) -> Results:
        boxes_list = []
        if tracker_type == 'DeepSORT':
            for x1, y1, x2, y2, track_id, object_class in tracked_outputs:
                boxes_list.append([int(x1), int(y1), int(x2), int(y2), track_id, 1.0, object_class])
        elif tracker_type in ['StrongSORT', 'BoTSORT']:
            for x1, y1, x2, y2, id, conf, cls, ind in tracked_outputs:
                boxes_list.append([int(x1), int(y1), int(x2), int(y2), id, conf, cls])
        elif tracker_type == 'SMILEtrack':
            for t in tracked_outputs:
                x, y, w, h = t.tlwh
                boxes_list.append([x, y, x + w, y + h, t.track_id, t.score, t.cls])

        boxes = torch.tensor(boxes_list, dtype=torch.float32) if boxes_list else None

        return [Results(
            orig_img=frame,
            path=None,
            names=model_names,
            boxes=boxes
        )]
m7mdhka commented 1 month ago

@mikel-brostrom I just take 1 frame using opencv, 'cv2.grab' and cv2.retrieve, so maybe you these circumstances are not handled?

github-actions[bot] commented 1 month ago

👋 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!

mikel-brostrom commented 1 month ago

Use this template: https://github.com/mikel-brostrom/boxmot/blob/master/examples/torchvision_det_boxmot.ipynb