1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
| SOURCE_VIDEO_PATH = "<VIDEO_PATH>" TARGET_VIDEO_PATH = "<PATH>/vehicle-counting-result.mp4" import sys sys.path.append("<PATH>/ByteTrack")
import yolox from yolox.tracker.byte_tracker import BYTETracker, STrack from onemetric.cv.utils.iou import box_iou_batch from dataclasses import dataclass
@dataclass(frozen=True) class BYTETrackerArgs: track_thresh: float = 0.25 track_buffer: int = 30 match_thresh: float = 0.8 aspect_ratio_thresh: float = 3.0 min_box_area: float = 1.0 mot20: bool = False
import supervision from supervision.draw.color import ColorPalette from supervision.geometry.dataclasses import Point from supervision.video.dataclasses import VideoInfo from supervision.video.source import get_video_frames_generator from supervision.video.sink import VideoSink from supervision.notebook.utils import show_frame_in_notebook from supervision.tools.detections import Detections, BoxAnnotator from supervision.tools.line_counter import LineCounter, LineCounterAnnotator
from typing import List
import numpy as np
def detections2boxes(detections: Detections) -> np.ndarray: return np.hstack(( detections.xyxy, detections.confidence[:, np.newaxis] ))
def tracks2boxes(tracks: List[STrack]) -> np.ndarray: return np.array([ track.tlbr for track in tracks ], dtype=float)
def match_detections_with_tracks( detections: Detections, tracks: List[STrack] ) -> Detections: if not np.any(detections.xyxy) or len(tracks) == 0: return np.empty((0,))
tracks_boxes = tracks2boxes(tracks=tracks) iou = box_iou_batch(tracks_boxes, detections.xyxy) track2detection = np.argmax(iou, axis=1)
tracker_ids = [None] * len(detections)
for tracker_index, detection_index in enumerate(track2detection): if iou[tracker_index, detection_index] != 0: tracker_ids[detection_index] = tracks[tracker_index].track_id
return tracker_ids
MODEL = "yolov8x.pt" from ultralytics import YOLO
model = YOLO(MODEL) model.fuse()
CLASS_NAMES_DICT = model.model.names
CLASS_ID = [2, 3, 5, 7]
generator = get_video_frames_generator(SOURCE_VIDEO_PATH)
box_annotator = BoxAnnotator(color=ColorPalette(), thickness=4, text_thickness=4, text_scale=2)
iterator = iter(generator) frame = next(iterator)
results = model(frame) detections = Detections( xyxy=results[0].boxes.xyxy.cpu().numpy(), confidence=results[0].boxes.conf.cpu().numpy(), class_id=results[0].boxes.cls.cpu().numpy().astype(int) )
labels = [ f"{CLASS_NAMES_DICT[class_id]} {confidence:0.2f}" for _, confidence, class_id, tracker_id in detections ]
LINE_START = Point(50, 1500) LINE_END = Point(3840-50, 1500)
VideoInfo.from_video_path(SOURCE_VIDEO_PATH)
byte_tracker = BYTETracker(BYTETrackerArgs())
video_info = VideoInfo.from_video_path(SOURCE_VIDEO_PATH)
generator = get_video_frames_generator(SOURCE_VIDEO_PATH)
line_counter = LineCounter(start=LINE_START, end=LINE_END)
box_annotator = BoxAnnotator(color=ColorPalette(), thickness=4, text_thickness=4, text_scale=2) line_annotator = LineCounterAnnotator(thickness=4, text_thickness=4, text_scale=2)
with VideoSink(TARGET_VIDEO_PATH, video_info) as sink: for frame in generator: results = model(frame) detections = Detections( xyxy=results[0].boxes.xyxy.cpu().numpy(), confidence=results[0].boxes.conf.cpu().numpy(), class_id=results[0].boxes.cls.cpu().numpy().astype(int) ) mask = np.array([class_id in CLASS_ID for class_id in detections.class_id], dtype=bool) detections.filter(mask=mask, inplace=True) tracks = byte_tracker.update( output_results=detections2boxes(detections=detections), img_info=frame.shape, img_size=frame.shape ) tracker_id = match_detections_with_tracks(detections=detections, tracks=tracks) detections.tracker_id = np.array(tracker_id) mask = np.array([tracker_id is not None for tracker_id in detections.tracker_id], dtype=bool) detections.filter(mask=mask, inplace=True) labels = [ f"#{tracker_id} {CLASS_NAMES_DICT[class_id]} {confidence:0.2f}" for _, confidence, class_id, tracker_id in detections ] line_counter.update(detections=detections) frame = box_annotator.annotate(frame=frame, detections=detections, labels=labels) line_annotator.annotate(frame=frame, line_counter=line_counter) sink.write_frame(frame)
|