### Install deep-sort-realtime from source Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Install the deep-sort-realtime package by cloning the repository and installing it using pip. ```bash cd deep_sort_realtime && pip3 install . ``` -------------------------------- ### Install deep-sort-realtime Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Install the library using pip. Optional backends for appearance embedders can also be installed. ```bash pip install deep-sort-realtime ``` ```bash git clone https://github.com/levan92/deep_sort_realtime cd deep_sort_realtime && pip install . ``` ```bash pip install torch torchvision ``` ```bash pip install torchreid gdown tensorboard ``` ```bash pip install git+https://github.com/openai/CLIP.git ``` ```bash pip install tensorflow ``` -------------------------------- ### Install deep-sort-realtime via pip Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Install the deep-sort-realtime package from PyPI using pip. ```bash pip3 install deep-sort-realtime ``` ```bash python3 -m pip install deep-sort-realtime ``` -------------------------------- ### Initialize and Use Clip_Embedder with DeepSort Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Demonstrates initializing DeepSort with the CLIP-based embedder and updating tracks with detections. Ensure CLIP is installed via pip. ```python # pip install git+https://github.com/openai/CLIP.git from deep_sort_realtime.deepsort_tracker import DeepSort import numpy as np tracker = DeepSort( max_age=30, embedder="clip_ViT-B/32", # options: clip_RN50 | clip_RN101 | clip_RN50x4 | # clip_RN50x16 | clip_ViT-B/32 | clip_ViT-B/16 embedder_wts=None, # None → auto-download or look in embedder/weights/ embedder_gpu=False, bgr=True, ) frame = np.zeros((720, 1280, 3), dtype=np.uint8) dets = [([50, 50, 100, 150], 0.88, "cat"), ([300, 100, 80, 120], 0.79, "dog")] tracks = tracker.update_tracks(dets, frame=frame) for track in tracks: if track.is_confirmed(): print(f"Track {track.track_id} | class={track.get_det_class()} | feat_dim={track.get_feature().shape}") ``` -------------------------------- ### Initialize DeepSort with TorchReID Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Initializes the DeepSort tracker with the TorchReID embedder. Ensure TorchReID is installed and model weights are available. Defaults to 'osnet_ain_x1_0' model. ```python from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=5, embedder='torchreid') ``` -------------------------------- ### Get Today's Date for Track Naming Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Use this snippet to get the current date, which can be used for track naming and daily track ID resets to prevent overflow. ```python3 from datetime import datetime today = datetime.now().date() ``` -------------------------------- ### Retrieve Bounding Box Coordinates Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Access bounding box coordinates using `to_ltrb` or `to_ltwh`. By default, Kalman-predicted coordinates are returned. Use `orig=True` to get raw detection coordinates, and `orig_strict=True` to return `None` if no detection is associated. ```python for track in tracks: if not track.is_confirmed(): continue # Kalman-filter predicted position (always available) kf_ltrb = track.to_ltrb() # [l, t, r, b] kf_ltwh = track.to_ltwh() # [l, t, w, h] # Original detection bbox (only non-None when matched this frame) orig_ltrb = track.to_ltrb(orig=True) # falls back to KF if unmatched orig_ltwh = track.to_ltwh(orig=True) # Strict: returns None when track has no detection match this frame strict_ltrb = track.to_ltrb(orig=True, orig_strict=True) if strict_ltrb is not None: l, t, r, b = strict_ltrb print(f"Track {track.track_id} detection-only bbox: ({l},{t}) → ({r},{b})") else: print(f"Track {track.track_id} coasting (no detection this frame)") ``` -------------------------------- ### Run Unit Tests Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Execute the project's unit tests using this command to verify the integrity and functionality of the tracker. ```bash python3 -m unittest ``` -------------------------------- ### Run DeepSort Realtime Test Suite Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Execute the integrated test suite for the deep-sort-realtime library from the repository root. ```bash # From the repository root python3 -m unittest ``` -------------------------------- ### DeepSort.__init__ Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Instantiates the multi-target tracker with all hyperparameters and selects an appearance embedder. The embedder is loaded once at construction time and warmed up automatically. ```APIDOC ## DeepSort.__init__ ### Description Instantiates the multi-target tracker with all hyperparameters and selects an appearance embedder. The embedder is loaded once at construction time and warmed up automatically. ### Method ```python DeepSort( max_iou_distance=0.7, max_age=30, n_init=3, nms_max_overlap=1.0, max_cosine_distance=0.2, nn_budget=100, gating_only_position=False, override_track_class=None, embedder="mobilenet", half=True, bgr=True, embedder_gpu=True, embedder_model_name=None, embedder_wts=None, polygon=False, today=None ) ``` ### Parameters #### Optional Parameters - **max_iou_distance** (float) - IoU gating threshold; associations above this are ignored. Defaults to 0.7. - **max_age** (int) - Frames a track survives without a detection match. Defaults to 30. - **n_init** (int) - Consecutive hits needed to confirm a new track. Defaults to 3. - **nms_max_overlap** (float) - NMS threshold (1.0 = NMS disabled). Defaults to 1.0. - **max_cosine_distance** (float) - Cosine-distance threshold for appearance matching. Defaults to 0.2. - **nn_budget** (int or None) - Max stored appearance features per track (None = unlimited). Defaults to 100. - **gating_only_position** (bool) - True → gate only on (x,y); False → gate on (x,y,a,h). Defaults to False. - **override_track_class** (class or None) - Supply a Track subclass for custom per-track logic. Defaults to None. - **embedder** (str) - One of: `mobilenet`, `torchreid`, `clip_RN50`, `clip_RN101`, `clip_RN50x4`, `clip_RN50x16`, `clip_ViT-B/32`, `clip_ViT-B/16`. Defaults to "mobilenet". - **half** (bool) - FP16 inference (CUDA only, mobilenet embedder). Defaults to True. - **bgr** (bool) - True if frames are BGR (OpenCV default). Defaults to True. - **embedder_gpu** (bool) - Run embedder on GPU. Defaults to True. - **embedder_model_name** (str or None) - For torchreid: model name from model zoo. Defaults to None. - **embedder_wts** (str or None) - Explicit path to embedder weights file. Defaults to None. - **polygon** (bool) - True → detections are polygons, not axis-aligned BBs. Defaults to False. - **today** (date or None) - Supply date to enable daily track-ID resets. Defaults to None. ### Request Example ```python from deep_sort_realtime.deepsort_tracker import DeepSort # Minimal usage: default MobileNetV2 embedder tracker = DeepSort() # Full parameter control tracker = DeepSort( max_iou_distance=0.7, max_age=30, n_init=3, nms_max_overlap=1.0, max_cosine_distance=0.2, nn_budget=100, gating_only_position=False, override_track_class=None, embedder="mobilenet", half=True, bgr=True, embedder_gpu=True, embedder_model_name=None, embedder_wts=None, polygon=False, today=datetime.now().date() ) ``` ``` -------------------------------- ### Initialize DeepSort Tracker Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Instantiate the DeepSort tracker with default or custom hyperparameters. The embedder is loaded and warmed up during initialization. ```python from deep_sort_realtime.deepsort_tracker import DeepSort # --- Minimal usage: default MobileNetV2 embedder --- tracker = DeepSort(max_age=30) ``` ```python from datetime import datetime from deep_sort_realtime.deepsort_tracker import DeepSort # --- Full parameter control --- tracker = DeepSort( max_iou_distance=0.7, # IoU gating threshold; associations above this are ignored max_age=30, # frames a track survives without a detection match n_init=3, # consecutive hits needed to confirm a new track nms_max_overlap=1.0, # NMS threshold (1.0 = NMS disabled) max_cosine_distance=0.2, # cosine-distance threshold for appearance matching nn_budget=100, # max stored appearance features per track (None = unlimited) gating_only_position=False, # True → gate only on (x,y); False → gate on (x,y,a,h) override_track_class=None, # supply a Track subclass for custom per-track logic embedder="mobilenet", # one of: mobilenet | torchreid | clip_RN50 | clip_RN101 | # clip_RN50x4 | clip_RN50x16 | clip_ViT-B/32 | clip_ViT-B/16 half=True, # FP16 inference (CUDA only, mobilenet embedder) bgr=True, # True if frames are BGR (OpenCV default) embedder_gpu=True, # run embedder on GPU embedder_model_name=None, # torchreid: model name from model zoo embedder_wts=None, # explicit path to embedder weights file polygon=False, # True → detections are polygons, not axis-aligned BBs today=datetime.now().date() # supply date to enable daily track-ID resets ) ``` -------------------------------- ### Run tracker with polygon detections Source: https://context7.com/levan92/deep_sort_realtime/llms.txt When `polygon=True` is set at construction, detections are passed as a triplet of (polygons, classes, confidences). The polygon's bounding rectangle is used for tracking. ```python import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=10, polygon=True, embedder="mobilenet", embedder_gpu=False) frame = np.zeros((720, 1280, 3), dtype=np.uint8) # Polygon format: list of [x1,y1,x2,y2,...] flat arrays polygons = [[100, 100, 150, 80, 200, 120, 160, 180, 110, 170], # pentagon [300, 200, 360, 195, 370, 260, 295, 265]] # quadrilateral classes = ["person", "car"] confidences = [0.89, 0.76] # raw_detections for polygon mode: [polygons_list, classes_list, confidences_list] raw_detections = [polygons, classes, confidences] tracks = tracker.update_tracks(raw_detections, frame=frame) for track in tracks: if track.is_confirmed(): polygon_coords = track.get_det_supplementary() # original polygon stored here print(f"Track {track.track_id} | bbox {track.to_ltrb()} | polygon {polygon_coords}") ``` -------------------------------- ### Run tracker for one frame with raw detections Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Accepts raw detections and a frame image for built-in embedding. Returns a list of active `Track` objects. Ensure the frame is in BGR format. ```python import cv2 import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=5, embedder="mobilenet", embedder_gpu=False) cap = cv2.VideoCapture("video.mp4") while cap.isOpened(): ret, frame = cap.read() # BGR frame, shape (H, W, 3) if not ret: break # raw_detections: list of ([left, top, width, height], confidence, class_name) raw_detections = [ ([120, 80, 60, 120], 0.92, "person"), ([300, 150, 80, 160], 0.85, "person"), ([500, 200, 40, 80], 0.70, "car"), ] tracks = tracker.update_tracks(raw_detections, frame=frame) for track in tracks: if not track.is_confirmed(): continue # skip tentative tracks track_id = track.track_id # e.g. "1", "2", or "2024-01-15_1" with today= ltrb = track.to_ltrb() # [left, top, right, bottom] — Kalman predicted ltwh = track.to_ltwh() # [left, top, width, height] det_class = track.get_det_class() # "person" / "car" / None det_conf = track.get_det_conf() # float or None if no match this frame l, t, r, b = [int(v) for v in ltrb] cv2.rectangle(frame, (l, t), (r, b), (0, 255, 0), 2) cv2.putText(frame, f"ID:{track_id} {det_class}", (l, t - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cap.release() ``` -------------------------------- ### Basic Deep SORT Tracker Usage Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Initialize the DeepSort tracker and update it with bounding boxes from an object detector. Expected input for `bbs` is a list of tuples, each containing `([left, top, w, h], confidence, detection_class)`. The `frame` argument is optional. ```python from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=5) bbs = object_detector.detect(frame) tracks = tracker.update_tracks(bbs, frame=frame) # bbs expected to be a list of detections, each in tuples of ( [left,top,w,h], confidence, detection_class ) for track in tracks: if not track.is_confirmed(): continue track_id = track.track_id ltrb = track.to_ltrb() ``` -------------------------------- ### Update Tracks with Instance Masks Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Use instance masks to suppress background pixels before cropping, reducing background bias in detections. Ensure masks are boolean and match the frame's spatial dimensions. ```python import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=10, embedder="mobilenet", embedder_gpu=False) H, W = 720, 1280 frame = np.random.randint(0, 255, (H, W, 3), dtype=np.uint8) raw_detections = [([100, 50, 120, 200], 0.90, "person")] # Boolean mask — True where foreground (object pixels), False = background mask = np.zeros((H, W), dtype=bool) mask[50:250, 100:220] = True # roughly cover the bounding box tracks = tracker.update_tracks( raw_detections, frame=frame, instance_masks=[mask], ) for track in tracks: inst_mask = track.get_instance_mask() # stored mask (None if no match this frame) print(f"Track {track.track_id} | has_mask={inst_mask is not None}") ``` -------------------------------- ### Deep SORT Tracker with Custom Embedder Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Initialize the DeepSort tracker and update it with bounding boxes, confidence scores, and custom embeddings. This allows integration with your own object detection and embedding models. The `frame` argument is not needed if embeddings are provided. ```python from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=5) bbs = object_detector.detect(frame) # your own object detection object_chips = chipper(frame, bbs) # your own logic to crop frame based on bbox values embeds = embedder(object_chips) # your own embedder to take in the cropped object chips, and output feature vectors tracks = tracker.update_tracks(bbs, embeds=embeds) # bbs expected to be a list of detections, each in tuples of ( [left,top,w,h], confidence, detection_class ), also, no need to give frame as your chips has already been embedded for track in tracks: if not track.is_confirmed(): continue track_id = track.track_id ltrb = track.to_ltrb() ``` -------------------------------- ### Run tracker with supplementary detection data Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Arbitrary per-detection payloads are forwarded to the associated track and retrievable via `Track.get_det_supplementary()`. Ensure the `others` list matches the number of detections. ```python import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=10, embedder="mobilenet", embedder_gpu=False) frame = np.zeros((720, 1280, 3), dtype=np.uint8) raw_detections = [ ([50, 30, 80, 160], 0.91, "person"), ([200, 60, 70, 150], 0.78, "person"), ] # Supplementary info — one entry per detection (any Python object) others = [ {"reid_score": 0.95, "zone": "entry"}, {"reid_score": 0.80, "zone": "exit"}, ] tracks = tracker.update_tracks(raw_detections, frame=frame, others=others) for track in tracks: supp = track.get_det_supplementary() # None if no match this frame if supp is not None: print(f"Track {track.track_id} zone={supp['zone']}, reid={supp['reid_score']}") ``` -------------------------------- ### Access Track State and Metadata Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Retrieve lifecycle state, identity, timing information, and detection-associated data for each `Track` object. Detection-associated data is reset each predict step and repopulated upon a successful match. ```python from deep_sort_realtime.deepsort_tracker import DeepSort import numpy as np tracker = DeepSort(max_age=5, embedder="mobilenet", embedder_gpu=False) frame = np.zeros((480, 640, 3), dtype=np.uint8) dets = [([10, 10, 50, 80], 0.95, "person"), ([200, 100, 60, 90], 0.80, "bicycle")] tracks = tracker.update_tracks(dets, frame=frame) for t in tracks: # Lifecycle state print(t.is_tentative()) # True for new tracks not yet confirmed print(t.is_confirmed()) # True after n_init consecutive hits print(t.is_deleted()) # True when track is stale (never returned after deletion) # Identity & timing print(t.track_id) # unique str ID, e.g. "1" or "2024-06-01_3" print(t.hits) # total measurement updates print(t.age) # total frames since first occurrence print(t.time_since_update) # frames since last detection match (0 = matched this frame) # Detection-associated data (reset to None each predict step, repopulated on match) print(t.get_det_class()) # class name string or None print(t.get_det_conf()) # float confidence or None print(t.get_instance_mask()) # boolean mask array or None print(t.get_det_supplementary()) # custom payload or None print(t.get_feature()) # latest appearance feature vector (np.ndarray) ``` -------------------------------- ### Retrieve Original Detection Bounding Box Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Use the `orig=True` argument in `Track.to_*` methods to retrieve bounding box values from the original detection associated with the track in the current frame. If `orig_strict=True` and no original detection is associated, `None` will be returned. ```python # Example usage within the track iteration loop: # ltrb = track.to_ltrb(orig=True) # ltrb_strict = track.to_ltrb(orig=True, orig_strict=True) ``` -------------------------------- ### Process Confirmed Tracks Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Iterates through the updated tracks, filters for confirmed tracks, and retrieves their bounding box information. ```python for track in tracks: if not track.is_confirmed(): continue track_id = track.track_id ltrb = track.to_ltrb() ``` -------------------------------- ### Run tracker with pre-computed embeddings Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Pass feature vectors directly via `embeds` and omit `frame` when using an external ReID model. Set `embedder=None` to disable the built-in embedder. ```python import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort # embedder=None → library will not load any built-in embedder tracker = DeepSort(max_age=10, embedder=None) # Simulated inputs from your own detector + embedder frame = np.zeros((720, 1280, 3), dtype=np.uint8) raw_detections = [ ([50, 30, 80, 160], 0.91, "person"), ([200, 60, 70, 150], 0.88, "person"), ] # Your own embedder produces a 512-d (or any-d) feature per detection crop your_embeddings = [np.random.rand(512).astype(np.float32) for _ in raw_detections] tracks = tracker.update_tracks(raw_detections, embeds=your_embeddings) for track in tracks: if track.is_confirmed(): print(f"Track {track.track_id}: {track.to_ltrb()}") # Example output: # Track 1: [50. 30. 130. 190.] # Track 2: [200. 60. 270. 210.] ``` -------------------------------- ### DeepSort.update_tracks with polygon detections Source: https://context7.com/levan92/deep_sort_realtime/llms.txt When `polygon=True` is set during initialization, detections can be provided as polygons. The bounding rectangle is used for tracking, and the polygon masks the crop for embedding. ```APIDOC ## `DeepSort.update_tracks` with polygon detections ### Description When `polygon=True` is set at construction, detections are passed as a triplet of (polygons, classes, confidences). The polygon's bounding rectangle is used for tracking; if embedding is enabled the polygon area masks the crop so only foreground pixels feed the embedder. ### Method ```python tracker.update_tracks(raw_detections, frame=frame) ``` ### Parameters #### `raw_detections` - Type: list - Description: When `polygon=True`, this is a list containing three elements: `[polygons_list, classes_list, confidences_list]`. `polygons_list` is a list of flat arrays, where each array represents a polygon's vertices `[x1,y1,x2,y2,...]`. `classes_list` and `confidences_list` contain the corresponding class names and confidence scores. #### `frame` - Type: numpy.ndarray - Description: The input frame image in BGR format (shape (H, W, 3)). Used for feature extraction if an embedder is configured and `polygon=True`. ### Returns - Type: list[Track] - Description: A list of active `Track` objects. The original polygon coordinates can be retrieved using `Track.get_det_supplementary()`. ### Request Example ```python import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=10, polygon=True, embedder="mobilenet", embedder_gpu=False) frame = np.zeros((720, 1280, 3), dtype=np.uint8) # Polygon format: list of [x1,y1,x2,y2,...] flat arrays polygons = [[100, 100, 150, 80, 200, 120, 160, 180, 110, 170], # pentagon [300, 200, 360, 195, 370, 260, 295, 265]] # quadrilateral classes = ["person", "car"] confidences = [0.89, 0.76] # raw_detections for polygon mode: [polygons_list, classes_list, confidences_list] raw_detections = [polygons, classes, confidences] tracks = tracker.update_tracks(raw_detections, frame=frame) for track in tracks: if track.is_confirmed(): polygon_coords = track.get_det_supplementary() # original polygon stored here print(f"Track {track.track_id} | bbox {track.to_ltrb()} | polygon {polygon_coords}") ``` ``` -------------------------------- ### Daily Track ID Reset Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Enable date-prefixed track IDs and daily resets by passing a `datetime.date` object to the `DeepSort` constructor's `today` parameter. This prevents ID overflow in long-running applications. ```python from datetime import datetime from deep_sort_realtime.deepsort_tracker import DeepSort import numpy as np today = datetime.now().date() tracker = DeepSort(max_age=30, nn_budget=100, today=today, embedder_gpu=False) frame = np.zeros((1080, 1920, 3), dtype=np.uint8) dets = [([0, 0, 50, 50], 0.9, "person"), ([100, 100, 50, 50], 0.85, "person")] tracks = tracker.update_tracks(dets, frame=frame, today=datetime.now().date()) for track in tracks: print(track.track_id) # Example output: # 2024-06-01_1 # 2024-06-01_2 ``` -------------------------------- ### Update DeepSort Tracks with Detections Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Updates the tracker with new detections and the current frame. Detections should be in the format of ([left,top,w,h], confidence, detection_class). ```python bbs = object_detector.detect(frame) tracks = tracker.update_tracks(bbs, frame=frame) ``` -------------------------------- ### Person Re-identification with `TorchReID_Embedder` Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Configure the `DeepSort` tracker to use a person re-identification embedder from the `torchreid` library. Specify the model name and weights; `None` uses bundled weights for `osnet_ain_x1_0`. ```python # pip install torchreid gdown tensorboard from deep_sort_realtime.deepsort_tracker import DeepSort import numpy as np, cv2 tracker = DeepSort( max_age=30, embedder="torchreid", embedder_model_name="osnet_ain_x1_0", # default; see torchreid model zoo for others embedder_wts=None, # None → bundled osnet weights embedder_gpu=False, bgr=True, ) frame = cv2.imread("test/smallapple.jpg") dets = [([0, 0, frame.shape[1]//2, frame.shape[0]], 0.9, "person")] tracks = tracker.update_tracks(dets, frame=frame) for track in tracks: print(f"Track {track.track_id}: feature_dim={track.get_feature().shape}") # Track 1: feature_dim=(512,) ``` -------------------------------- ### Standalone Embedder with `MobileNetv2_Embedder.predict` Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Utilize the `MobileNetv2_Embedder` independently to generate 1280-dimensional feature vectors from image crops. This is useful for tasks outside of the main tracker, such as similarity comparisons. ```python import cv2 import numpy as np from deep_sort_realtime.embedder.embedder_pytorch import MobileNetv2_Embedder embedder = MobileNetv2_Embedder(half=False, max_batch_size=16, bgr=True, gpu=False) img1 = cv2.imread("test/smallapple.jpg") # BGR image img2 = cv2.imread("test/rock.jpg") features = embedder.predict([img1, img2]) # list of np.ndarray, shape (1280,) print(f"Feature dim: {features[0].shape}") # (1280,) # Cosine distance between two feature vectors from scipy.spatial.distance import cosine dist = cosine(features[0], features[1]) print(f"Cosine distance (apple vs rock): {dist:.4f}") # e.g. 0.4410 — dissimilar ``` -------------------------------- ### DeepSort.update_tracks with instance masks Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Updates the tracker with new detections and optionally provides instance masks to suppress background pixels before embedding. This helps reduce background bias in the appearance features. ```APIDOC ## `DeepSort.update_tracks` with instance masks (background masking) Boolean instance masks suppress background pixels before the crop reaches the embedder, reducing background bias. One mask per detection, same spatial size as the full frame. ```python import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=10, embedder="mobilenet", embedder_gpu=False) H, W = 720, 1280 frame = np.random.randint(0, 255, (H, W, 3), dtype=np.uint8) raw_detections = [([100, 50, 120, 200], 0.90, "person")] # Boolean mask — True where foreground (object pixels), False = background mask = np.zeros((H, W), dtype=bool) mask[50:250, 100:220] = True # roughly cover the bounding box tracks = tracker.update_tracks( raw_detections, frame=frame, instance_masks=[mask], ) for track in tracks: inst_mask = track.get_instance_mask() # stored mask (None if no match this frame) print(f"Track {track.track_id} | has_mask={inst_mask is not None}") ``` ``` -------------------------------- ### Track.to_ltrb / Track.to_ltwh - Bounding box retrieval Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Retrieves bounding box coordinates for a track. By default, it returns Kalman-predicted coordinates. Setting `orig=True` returns the coordinates of the raw detection associated with the current frame. ```APIDOC ## `Track.to_ltrb` / `Track.to_ltwh` — Bounding box retrieval Returns Kalman-predicted coordinates by default. Setting `orig=True` returns the coordinates of the raw detection associated this frame; `orig_strict=True` returns `None` instead of Kalman values when no detection is associated. ```python for track in tracks: if not track.is_confirmed(): continue # Kalman-filter predicted position (always available) kf_ltrb = track.to_ltrb() # [l, t, r, b] kf_ltwh = track.to_ltwh() # [l, t, w, h] # Original detection bbox (only non-None when matched this frame) orig_ltrb = track.to_ltrb(orig=True) # falls back to KF if unmatched orig_ltwh = track.to_ltwh(orig=True) # Strict: returns None when track has no detection match this frame strict_ltrb = track.to_ltrb(orig=True, orig_strict=True) if strict_ltrb is not None: l, t, r, b = strict_ltrb print(f"Track {track.track_id} detection-only bbox: ({l},{t}) → ({r},{b})") else: print(f"Track {track.track_id} coasting (no detection this frame)") ``` ``` -------------------------------- ### Store Supplementary Detection Info Source: https://github.com/levan92/deep_sort_realtime/blob/master/README.md Pass supplementary information (e.g., instance segmentation masks) with detections using the `others` argument in `DeepSort.update_tracks`. This data can be retrieved from the associated track using `Track.get_det_supplementary`. ```python # Example usage: # supplementary_data = [...] # list of supplementary data, same length as raw_detections # tracks = tracker.update_tracks(bbs, others=supplementary_data) ``` -------------------------------- ### Track state and metadata accessors Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Provides access to various read-only attributes and methods of a `Track` object, including its lifecycle state, identity, timing information, and associated detection data. ```APIDOC ## `Track` state and metadata accessors Full set of read-only attributes and methods exposed by every `Track` object returned from `update_tracks`. ```python from deep_sort_realtime.deepsort_tracker import DeepSort import numpy as np tracker = DeepSort(max_age=5, embedder="mobilenet", embedder_gpu=False) frame = np.zeros((480, 640, 3), dtype=np.uint8) dets = [([10, 10, 50, 80], 0.95, "person"), ([200, 100, 60, 90], 0.80, "bicycle")] tracks = tracker.update_tracks(dets, frame=frame) for t in tracks: # Lifecycle state print(t.is_tentative()) # True for new tracks not yet confirmed print(t.is_confirmed()) # True after n_init consecutive hits print(t.is_deleted()) # True when track is stale (never returned after deletion) # Identity & timing print(t.track_id) # unique str ID, e.g. "1" or "2024-06-01_3" print(t.hits) # total measurement updates print(t.age) # total frames since first occurrence print(t.time_since_update) # frames since last detection match (0 = matched this frame) # Detection-associated data (reset to None each predict step, repopulated on match) print(t.get_det_class()) # class name string or None print(t.get_det_conf()) # float confidence or None print(t.get_instance_mask()) # boolean mask array or None print(t.get_det_supplementary()) # custom payload or None print(t.get_feature()) # latest appearance feature vector (np.ndarray) ``` ``` -------------------------------- ### DeepSort.update_tracks — Run tracker for one frame Source: https://context7.com/levan92/deep_sort_realtime/llms.txt The primary API call. Accepts raw detections and a frame image for built-in embedding, then returns the current list of all active `Track` objects. ```APIDOC ## `DeepSort.update_tracks` — Run tracker for one frame ### Description Accepts raw detections and a frame image for built-in embedding, then returns the current list of all active `Track` objects. ### Method ```python tracker.update_tracks(raw_detections, frame=frame) ``` ### Parameters #### `raw_detections` - Type: list - Description: A list of detections, where each detection is a tuple `([left, top, width, height], confidence, class_name)`. #### `frame` - Type: numpy.ndarray - Description: The input frame image in BGR format (shape (H, W, 3)). Used for feature extraction if an embedder is configured. ### Returns - Type: list[Track] - Description: A list of active `Track` objects. Each `Track` object contains information like `track_id`, bounding box coordinates (`to_ltrb()`, `to_ltwh()`), detected class (`get_det_class()`), and detection confidence (`get_det_conf()`). ### Request Example ```python import cv2 import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=5, embedder="mobilenet", embedder_gpu=False) cap = cv2.VideoCapture("video.mp4") while cap.isOpened(): ret, frame = cap.read() # BGR frame, shape (H, W, 3) if not ret: break # raw_detections: list of ([left, top, width, height], confidence, class_name) raw_detections = [ ([120, 80, 60, 120], 0.92, "person"), ([300, 150, 80, 160], 0.85, "person"), ([500, 200, 40, 80], 0.70, "car"), ] tracks = tracker.update_tracks(raw_detections, frame=frame) for track in tracks: if not track.is_confirmed(): continue # skip tentative tracks track_id = track.track_id # e.g. "1", "2", or "2024-01-15_1" with today= ltrb = track.to_ltrb() # [left, top, right, bottom] — Kalman predicted ltwh = track.to_ltwh() # [left, top, width, height] det_class = track.get_det_class() # "person" / "car" / None det_conf = track.get_det_conf() # float or None if no match this frame l, t, r, b = [int(v) for v in ltrb] cv2.rectangle(frame, (l, t), (r, b), (0, 255, 0), 2) cv2.putText(frame, f"ID:{track_id} {det_class}", (l, t - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cap.release() ``` ``` -------------------------------- ### DeepSort.update_tracks with pre-computed embeddings Source: https://context7.com/levan92/deep_sort_realtime/llms.txt When using an external ReID model, pass feature vectors directly via the `embeds` argument and omit the `frame` argument. ```APIDOC ## `DeepSort.update_tracks` with pre-computed embeddings — External embedder ### Description When you have your own ReID model, pass feature vectors directly via `embeds` and omit `frame`. ### Method ```python tracker.update_tracks(raw_detections, embeds=your_embeddings) ``` ### Parameters #### `raw_detections` - Type: list - Description: A list of detections, where each detection is a tuple `([left, top, width, height], confidence, class_name)`. #### `embeds` - Type: list[numpy.ndarray] - Description: A list of feature vectors (embeddings), where each vector corresponds to a detection in `raw_detections`. The dimension of the feature vector can be arbitrary. ### Returns - Type: list[Track] - Description: A list of active `Track` objects. ### Request Example ```python import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort # embedder=None → library will not load any built-in embedder tracker = DeepSort(max_age=10, embedder=None) # Simulated inputs from your own detector + embedder frame = np.zeros((720, 1280, 3), dtype=np.uint8) raw_detections = [ ([50, 30, 80, 160], 0.91, "person"), ([200, 60, 70, 150], 0.88, "person"), ] # Your own embedder produces a 512-d (or any-d) feature per detection crop your_embeddings = [np.random.rand(512).astype(np.float32) for _ in raw_detections] tracks = tracker.update_tracks(raw_detections, embeds=your_embeddings) for track in tracks: if track.is_confirmed(): print(f"Track {track.track_id}: {track.to_ltrb()}") # Example output: # Track 1: [50. 30. 130. 190.] # Track 2: [200. 60. 270. 210.] ``` ``` -------------------------------- ### DeepSort.update_tracks with supplementary detection data Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Arbitrary per-detection payloads, such as segmentation masks or metadata dictionaries, can be passed via the `others` argument and will be forwarded to the associated track. ```APIDOC ## `DeepSort.update_tracks` with supplementary detection data ### Description Arbitrary per-detection payloads (e.g. segmentation masks, metadata dicts) are forwarded to the associated track and retrievable via `Track.get_det_supplementary()`. ### Method ```python tracker.update_tracks(raw_detections, frame=frame, others=others) ``` ### Parameters #### `raw_detections` - Type: list - Description: A list of detections, where each detection is a tuple `([left, top, width, height], confidence, class_name)`. #### `frame` - Type: numpy.ndarray - Description: The input frame image in BGR format (shape (H, W, 3)). Used for feature extraction if an embedder is configured. #### `others` - Type: list - Description: A list containing arbitrary Python objects, where each object corresponds to a detection in `raw_detections`. This data is stored as supplementary information for the track. ### Returns - Type: list[Track] - Description: A list of active `Track` objects. Supplementary data can be accessed using `Track.get_det_supplementary()`. ### Request Example ```python import numpy as np from deep_sort_realtime.deepsort_tracker import DeepSort tracker = DeepSort(max_age=10, embedder="mobilenet", embedder_gpu=False) frame = np.zeros((720, 1280, 3), dtype=np.uint8) raw_detections = [ ([50, 30, 80, 160], 0.91, "person"), ([200, 60, 70, 150], 0.78, "person"), ] # Supplementary info — one entry per detection (any Python object) others = [ {"reid_score": 0.95, "zone": "entry"}, {"reid_score": 0.80, "zone": "exit"}, ] tracks = tracker.update_tracks(raw_detections, frame=frame, others=others) for track in tracks: supp = track.get_det_supplementary() # None if no match this frame if supp is not None: print(f"Track {track.track_id} zone={supp['zone']}, reid={supp['reid_score']}") ``` ``` -------------------------------- ### Custom Track Class for ROI Dwell Time Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Subclass `Track` to add custom logic, such as counting frames spent within a region of interest (ROI). Ensure the custom class is passed to the `DeepSort` constructor via `override_track_class`. ```python from deep_sort_realtime.deep_sort.track import Track from deep_sort_realtime.deepsort_tracker import DeepSort import numpy as np class MyTrack(Track): """Extended track that counts how many frames it spent in a region of interest.""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.roi_frame_count = 0 def check_roi(self, roi_ltrb): """Call each frame after update_tracks to accumulate ROI dwell time.""" l, t, r, b = self.to_ltrb() rl, rt, rr, rb = roi_ltrb in_roi = l >= rl and t >= rt and r <= rr and b <= rb if in_roi: self.roi_frame_count += 1 return in_roi tracker = DeepSort(max_age=30, override_track_class=MyTrack, embedder_gpu=False) frame = np.zeros((720, 1280, 3), dtype=np.uint8) roi = (100, 100, 500, 400) # [left, top, right, bottom] for _ in range(10): # simulate 10 frames dets = [([150, 120, 80, 160], 0.92, "person")] tracks = tracker.update_tracks(dets, frame=frame) for track in tracks: if track.is_confirmed(): in_roi = track.check_roi(roi) print(f"Track {track.track_id}: ROI dwell={track.roi_frame_count} frames, in_roi={in_roi}") ``` -------------------------------- ### Resetting Tracker State with `delete_all_tracks` Source: https://context7.com/levan92/deep_sort_realtime/llms.txt Use `DeepSort.delete_all_tracks()` to clear all active tracks and reset the internal ID counter to 1. This is useful when switching between different scenes or video streams. ```python from deep_sort_realtime.deepsort_tracker import DeepSort import numpy as np tracker = DeepSort(max_age=10, embedder_gpu=False) frame = np.zeros((480, 640, 3), dtype=np.uint8) tracker.update_tracks([([10, 10, 50, 80], 0.9, "person")], frame=frame) print(f"Active tracks before reset: {len(tracker.tracker.tracks)}") # 1 tracker.delete_all_tracks() print(f"Active tracks after reset: {len(tracker.tracker.tracks)}") # 0 # IDs restart from 1 on the next update tracks = tracker.update_tracks([([10, 10, 50, 80], 0.9, "person")], frame=frame) print(tracks[0].track_id) # "1" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.