Pedro Henrique Conrado commited on
Commit
c2d34b4
·
1 Parent(s): 6266ca4

first commit

Browse files
Files changed (3) hide show
  1. .gitignore.txt +7 -0
  2. app.py +121 -0
  3. requirements.txt +44 -0
.gitignore.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ flagged/
2
+ *.mp4
3
+ *.jpg
4
+ *.pt
5
+ *.png
6
+ *.mkv
7
+ gradio_cached_examples/
app.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ultralytics import YOLO
2
+ from dataclasses import dataclass
3
+ from yolox.tracker.byte_tracker import BYTETracker, STrack
4
+ from onemetric.cv.utils.iou import box_iou_batch
5
+ from dataclasses import dataclass
6
+ from supervision import Point
7
+ from supervision import Detections, BoxAnnotator
8
+ from supervision import draw_text
9
+ from supervision import Color
10
+ from supervision import VideoInfo
11
+ from supervision import get_video_frames_generator
12
+ from supervision import VideoSink
13
+ from typing import List
14
+ import numpy as np
15
+ import gradio as gr
16
+ from tqdm import tqdm
17
+
18
+ MODEL = "./best.pt"
19
+
20
+ SOURCE_VIDEO_PATH = "./examples"
21
+
22
+ TARGET_VIDEO_PATH = "test.mp4"
23
+
24
+ CLASS_ID = [0,1,2,3]
25
+
26
+ model = YOLO(MODEL)
27
+ model.fuse()
28
+
29
+ classes = CLASS_ID
30
+
31
+ @dataclass(frozen=True)
32
+ class BYTETrackerArgs:
33
+ track_thresh: float = 0.25
34
+ track_buffer: int = 30
35
+ match_thresh: float = 0.8
36
+ aspect_ratio_thresh: float = 3.0
37
+ min_box_area: float = 1.0
38
+ mot20: bool = False
39
+
40
+
41
+ # converts Detections into format that can be consumed by match_detections_with_tracks function
42
+ def detections2boxes(detections : Detections) -> np.ndarray:
43
+ return np.hstack((
44
+ detections.xyxy,
45
+ detections.confidence[:, np.newaxis]
46
+ ))
47
+
48
+
49
+ # converts List[STrack] into format that can be consumed by match_detections_with_tracks function
50
+ def tracks2boxes(tracks: List[STrack]) -> np.ndarray:
51
+ return np.array([
52
+ track.tlbr
53
+ for track
54
+ in tracks
55
+ ], dtype=float)
56
+
57
+
58
+ # matches our bounding boxes with predictions
59
+ def match_detections_with_tracks(
60
+ detections: Detections,
61
+ tracks: List[STrack],
62
+ ) -> Detections:
63
+ if not np.any(detections.xyxy) or len(tracks) == 0:
64
+ return np.empty((0,))
65
+
66
+ tracks_boxes = tracks2boxes(tracks=tracks)
67
+ iou = box_iou_batch(tracks_boxes, detections.xyxy)
68
+ track2detection = np.argmax(iou, axis=1)
69
+
70
+ tracker_ids = [None] * len(detections)
71
+
72
+ for tracker_index, detection_index in enumerate(track2detection):
73
+ if iou[tracker_index, detection_index] != 0:
74
+ tracker_ids[detection_index] = tracks[tracker_index].track_id
75
+
76
+ return tracker_ids
77
+
78
+ def ObjectDetection(video_path):
79
+ byte_tracker = BYTETracker(BYTETrackerArgs())
80
+ video_info = VideoInfo.from_video_path(video_path)
81
+ generator = get_video_frames_generator(video_path)
82
+ box_annotator = BoxAnnotator(thickness=5, text_thickness=5, text_scale=1)
83
+
84
+ with VideoSink(TARGET_VIDEO_PATH, video_info) as sink:
85
+ # loop over video frames
86
+ for frame in tqdm(generator, total=video_info.total_frames):
87
+ results = model(frame)
88
+ detections = Detections(
89
+ xyxy=results[0].boxes.xyxy.cpu().numpy(),
90
+ confidence=results[0].boxes.conf.cpu().numpy(),
91
+ class_id=results[0].boxes.cls.cpu().numpy().astype(int)
92
+ )
93
+ # filtering out detections with unwanted classes
94
+ detections = detections[np.isin(detections.class_id, [0,1,2,3])]
95
+ # tracking detections
96
+ tracks = byte_tracker.update(
97
+ output_results=detections2boxes(detections = detections),
98
+ img_info=frame.shape,
99
+ img_size=frame.shape
100
+ )
101
+ tracker_id = match_detections_with_tracks(detections=detections, tracks=tracks)
102
+ detections.tracker_id = np.array(tracker_id)
103
+ # filtering out detections without trackers
104
+ detections = detections[np.not_equal(detections.tracker_id, None)]
105
+ # format custom labels
106
+ labels = [
107
+ f"#{tracker_id} {classes[class_id]} {confidence:0.2f}"
108
+ for _, _, confidence, class_id, tracker_id
109
+ in detections
110
+ ]
111
+ t = np.unique(detections.class_id, return_counts =True)
112
+ for x in zip(t[0], t[1]):
113
+ frame = draw_text(background_color=Color.white(), scene=frame, text=' '.join((str(classes[x[0]]), ':', str(x[1]))), text_anchor=Point(x=50, y=300 + (50 * x[0])), text_scale = 2, text_thickness = 4, )
114
+ # annotate and display frame
115
+ frame = box_annotator.annotate(scene=frame, detections=detections, labels=labels)
116
+ sink.write_frame(frame)
117
+
118
+ return TARGET_VIDEO_PATH
119
+
120
+ demo = gr.Interface(fn=ObjectDetection, inputs=gr.Video(), outputs=gr.Video(), examples=SOURCE_VIDEO_PATH, cache_examples=False)
121
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Ultralytics requirements
2
+ # Usage: pip install -r requirements.txt
3
+
4
+ # Base ----------------------------------------
5
+ matplotlib>=3.2.2
6
+ opencv-python>=4.6.0
7
+ pillow>=7.1.2
8
+ pyyaml>=5.3.1
9
+ requests>=2.23.0
10
+ scipy>=1.4.1
11
+ torch>=1.7.0
12
+ torchvision>=0.8.1
13
+ tqdm>=4.64.0
14
+
15
+ # Logging -------------------------------------
16
+ # tensorboard>=2.13.0
17
+ # dvclive>=2.12.0
18
+ # clearml
19
+ # comet
20
+
21
+ # Plotting ------------------------------------
22
+ pandas>=1.1.4
23
+ seaborn>=0.11.0
24
+
25
+ # Export --------------------------------------
26
+ # coremltools>=6.0,<=6.2 # CoreML export
27
+ # onnx>=1.12.0 # ONNX export
28
+ # onnxsim>=0.4.1 # ONNX simplifier
29
+ # nvidia-pyindex # TensorRT export
30
+ # nvidia-tensorrt # TensorRT export
31
+ # scikit-learn==0.19.2 # CoreML quantization
32
+ # tensorflow>=2.4.1 # TF exports (-cpu, -aarch64, -macos)
33
+ # tflite-support
34
+ # tensorflowjs>=3.9.0 # TF.js export
35
+ # openvino-dev>=2023.0 # OpenVINO export
36
+
37
+ # Extras --------------------------------------
38
+ psutil # system utilization
39
+ py-cpuinfo # display CPU info
40
+ # thop>=0.1.1 # FLOPs computation
41
+ # ipython # interactive notebook
42
+ # albumentations>=1.0.3 # training augmentations
43
+ # pycocotools>=2.0.6 # COCO mAP
44
+ # roboflow