initial working version
This commit is contained in:
1 parent
7e8d44ac35
commit
d83547ec80
1 file changed
+75
-34
@@ -1,4 +1,5 @@
|
||||
import argparse
|
||||
from collections import defaultdict, deque
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
@@ -7,14 +8,40 @@ from ultralytics import YOLO
|
||||
import supervision as sv
|
||||
|
||||
COLOR = sv.Color.red()
|
||||
ZONE = np.array([
|
||||
|
||||
SOURCE = np.array([
|
||||
[1252, 787],
|
||||
[2298, 803],
|
||||
[5039, 2159],
|
||||
[-550, 2159]
|
||||
])
|
||||
|
||||
polygon_zone = sv.PolygonZone(polygon=ZONE, frame_resolution_wh=(3840, 2160))
|
||||
TARGET_WIDTH = 25
|
||||
TARGET_HEIGHT = 250
|
||||
|
||||
TARGET = np.array([
|
||||
[0, 0],
|
||||
[TARGET_WIDTH - 1, 0],
|
||||
[TARGET_WIDTH - 1, TARGET_HEIGHT - 1],
|
||||
[0, TARGET_HEIGHT - 1]
|
||||
])
|
||||
|
||||
|
||||
class ViewTransformer:
|
||||
|
||||
def __init__(self, m: np.ndarray) -> None:
|
||||
self.m = m
|
||||
|
||||
@classmethod
|
||||
def initialize(cls, source: np.ndarray, target: np.ndarray) -> 'ViewTransformer':
|
||||
source = source.astype(np.float32)
|
||||
target = target.astype(np.float32)
|
||||
return cls(m=cv2.getPerspectiveTransform(source, target))
|
||||
|
||||
def transform_points(self, points: np.ndarray) -> np.ndarray:
|
||||
reshaped_points = points.reshape(-1, 1, 2).astype(np.float32)
|
||||
transformed_points = cv2.perspectiveTransform(reshaped_points, self.m)
|
||||
return transformed_points.reshape(-1, 2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@@ -71,42 +98,56 @@ if __name__ == "__main__":
|
||||
text_scale=text_scale, text_thickness=thickness, color=COLOR,
|
||||
text_position=sv.Position.BOTTOM_CENTER)
|
||||
trace_annotator = sv.TraceAnnotator(
|
||||
thickness=thickness, color=COLOR, trace_length=video_info.fps * 2,
|
||||
thickness=thickness, color=COLOR, trace_length=video_info.fps,
|
||||
position=sv.Position.BOTTOM_CENTER)
|
||||
|
||||
frame_generator = sv.get_video_frames_generator(source_path=args.source_video_path)
|
||||
|
||||
for frame in frame_generator:
|
||||
result = model(frame)[0]
|
||||
detections = sv.Detections.from_ultralytics(result)
|
||||
detections = detections[detections.confidence > args.confidence_threshold]
|
||||
detections = detections[polygon_zone.trigger(detections)]
|
||||
detections = byte_track.update_with_detections(detections=detections)
|
||||
polygon_zone = sv.PolygonZone(
|
||||
polygon=SOURCE, frame_resolution_wh=video_info.resolution_wh)
|
||||
view_transformer = ViewTransformer.initialize(source=SOURCE, target=TARGET)
|
||||
|
||||
labels = [
|
||||
f"#{tracker_id}"
|
||||
for _, _, _, _, tracker_id
|
||||
in detections
|
||||
]
|
||||
position = defaultdict(lambda: deque(maxlen=video_info.fps))
|
||||
|
||||
annotated_frame = frame.copy()
|
||||
annotated_frame = sv.draw_polygon(
|
||||
scene=annotated_frame,
|
||||
polygon=ZONE,
|
||||
color=COLOR,
|
||||
thickness=thickness)
|
||||
annotated_frame = bounding_box_annotator.annotate(
|
||||
scene=annotated_frame,
|
||||
detections=detections)
|
||||
annotated_frame = trace_annotator.annotate(
|
||||
scene=annotated_frame,
|
||||
detections=detections)
|
||||
annotated_frame = label_annotator.annotate(
|
||||
scene=annotated_frame,
|
||||
detections=detections,
|
||||
labels=labels)
|
||||
with sv.VideoSink('data/result.mp4', video_info) as sink:
|
||||
for frame in frame_generator:
|
||||
result = model(frame)[0]
|
||||
detections = sv.Detections.from_ultralytics(result)
|
||||
detections = detections[detections.confidence > args.confidence_threshold]
|
||||
detections = detections[polygon_zone.trigger(detections)]
|
||||
detections = byte_track.update_with_detections(detections=detections)
|
||||
|
||||
cv2.imshow("frame", annotated_frame)
|
||||
if cv2.waitKey(1) & 0xFF == ord("q"):
|
||||
break
|
||||
cv2.destroyAllWindows()
|
||||
points = detections.get_anchors_coordinates(anchor=sv.Position.BOTTOM_CENTER)
|
||||
points = view_transformer.transform_points(points=points).astype(int)
|
||||
|
||||
labels = []
|
||||
for tracker_id, [_, y] in zip(detections.tracker_id, points):
|
||||
position[tracker_id].append(y)
|
||||
if len(position[tracker_id]) < video_info.fps / 2:
|
||||
labels.append(f"#{tracker_id}")
|
||||
else:
|
||||
speed = abs(position[tracker_id][-1] - position[tracker_id][0]) * video_info.fps / len(position[tracker_id]) * 3.6
|
||||
labels.append(f"#{tracker_id} {int(speed)} km/h")
|
||||
|
||||
annotated_frame = frame.copy()
|
||||
annotated_frame = sv.draw_polygon(
|
||||
scene=annotated_frame,
|
||||
polygon=SOURCE,
|
||||
color=COLOR,
|
||||
thickness=thickness)
|
||||
annotated_frame = bounding_box_annotator.annotate(
|
||||
scene=annotated_frame,
|
||||
detections=detections)
|
||||
annotated_frame = trace_annotator.annotate(
|
||||
scene=annotated_frame,
|
||||
detections=detections)
|
||||
annotated_frame = label_annotator.annotate(
|
||||
scene=annotated_frame,
|
||||
detections=detections,
|
||||
labels=labels)
|
||||
|
||||
sink.write_frame(annotated_frame)
|
||||
cv2.imshow("frame", annotated_frame)
|
||||
if cv2.waitKey(1) & 0xFF == ord("q"):
|
||||
break
|
||||
cv2.destroyAllWindows()
|
||||
Reference in new issue
Block a user