Spaces:
Runtime error
Runtime error
Commit
·
c683b90
1
Parent(s):
a8274b9
add sorter and improve detections
Browse files- app.py +65 -11
- detector/utils.py +2 -16
app.py
CHANGED
@@ -1,6 +1,33 @@
|
|
1 |
import gradio as gr
|
|
|
2 |
import cv2
|
3 |
-
from
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
|
6 |
def fn_image(foto):
|
@@ -18,7 +45,10 @@ def fn_image(foto):
|
|
18 |
|
19 |
|
20 |
def fn_video(video, initial_time, duration):
|
21 |
-
|
|
|
|
|
|
|
22 |
cap = cv2.VideoCapture(video)
|
23 |
fps = cap.get(cv2.CAP_PROP_FPS)
|
24 |
image_size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
@@ -26,6 +56,7 @@ def fn_video(video, initial_time, duration):
|
|
26 |
num_frames = 0
|
27 |
min_frame = int(initial_time * fps)
|
28 |
max_frame = int((initial_time + duration) * fps)
|
|
|
29 |
while cap.isOpened():
|
30 |
try:
|
31 |
ret, frame = cap.read()
|
@@ -34,24 +65,47 @@ def fn_video(video, initial_time, duration):
|
|
34 |
except Exception as e:
|
35 |
print(e)
|
36 |
continue
|
|
|
|
|
|
|
37 |
if num_frames < min_frame:
|
38 |
num_frames += 1
|
39 |
continue
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
final_video.write(frame)
|
49 |
num_frames += 1
|
50 |
if num_frames == max_frame:
|
51 |
break
|
52 |
cap.release()
|
53 |
final_video.release()
|
54 |
-
return 'output.mp4',
|
55 |
|
56 |
|
57 |
image_interface = gr.Interface(
|
|
|
1 |
import gradio as gr
|
2 |
+
import numpy as np
|
3 |
import cv2
|
4 |
+
from norfair import Detection, Tracker, Video
|
5 |
+
from detector.utils import detect_plates, detect_chars, imcrop
|
6 |
+
|
7 |
+
DISTANCE_THRESHOLD_BBOX: float = 0.7
|
8 |
+
DISTANCE_THRESHOLD_CENTROID: int = 30
|
9 |
+
MAX_DISTANCE: int = 10000
|
10 |
+
|
11 |
+
|
12 |
+
def yolo_to_norfair(yolo_detections):
|
13 |
+
norfair_detections = []
|
14 |
+
detections_as_xyxy = yolo_detections.xyxy[0]
|
15 |
+
for detection_as_xyxy in detections_as_xyxy:
|
16 |
+
bbox = np.array(
|
17 |
+
[
|
18 |
+
[detection_as_xyxy[0].item(), detection_as_xyxy[1].item()],
|
19 |
+
[detection_as_xyxy[2].item(), detection_as_xyxy[3].item()],
|
20 |
+
]
|
21 |
+
)
|
22 |
+
scores = np.array(
|
23 |
+
[detection_as_xyxy[4].item(), detection_as_xyxy[4].item()]
|
24 |
+
)
|
25 |
+
norfair_detections.append(
|
26 |
+
Detection(
|
27 |
+
points=bbox, scores=scores, label=int(detection_as_xyxy[-1].item())
|
28 |
+
)
|
29 |
+
)
|
30 |
+
return norfair_detections
|
31 |
|
32 |
|
33 |
def fn_image(foto):
|
|
|
45 |
|
46 |
|
47 |
def fn_video(video, initial_time, duration):
|
48 |
+
tracker = Tracker(
|
49 |
+
distance_function="iou_opt",
|
50 |
+
distance_threshold=DISTANCE_THRESHOLD_BBOX,
|
51 |
+
)
|
52 |
cap = cv2.VideoCapture(video)
|
53 |
fps = cap.get(cv2.CAP_PROP_FPS)
|
54 |
image_size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
|
|
56 |
num_frames = 0
|
57 |
min_frame = int(initial_time * fps)
|
58 |
max_frame = int((initial_time + duration) * fps)
|
59 |
+
plates = {}
|
60 |
while cap.isOpened():
|
61 |
try:
|
62 |
ret, frame = cap.read()
|
|
|
65 |
except Exception as e:
|
66 |
print(e)
|
67 |
continue
|
68 |
+
# num_frames += 1
|
69 |
+
# if num_frames % 3 != 0:
|
70 |
+
# continue
|
71 |
if num_frames < min_frame:
|
72 |
num_frames += 1
|
73 |
continue
|
74 |
+
yolo_detections = detect_plates(frame)
|
75 |
+
detections = yolo_to_norfair(yolo_detections)
|
76 |
+
tracked_objects = tracker.update(detections=detections)
|
77 |
+
for obj in tracked_objects:
|
78 |
+
if obj.last_detection is not None:
|
79 |
+
bbox = obj.last_detection.points
|
80 |
+
bbox = int(bbox[0][0]), int(bbox[0][1]), int(bbox[1][0]), int(bbox[1][1])
|
81 |
+
if obj.id not in plates.keys():
|
82 |
+
crop = imcrop(frame, bbox)
|
83 |
+
text = detect_chars(crop)
|
84 |
+
plates[obj.id] = text
|
85 |
+
|
86 |
+
cv2.rectangle(
|
87 |
+
frame,
|
88 |
+
(bbox[0], bbox[1]),
|
89 |
+
(bbox[2], bbox[3]),
|
90 |
+
(0, 255, 0),
|
91 |
+
2,
|
92 |
+
)
|
93 |
+
cv2.putText(
|
94 |
+
frame,
|
95 |
+
plates[obj.id],
|
96 |
+
(bbox[0], bbox[1]),
|
97 |
+
cv2.FONT_HERSHEY_SIMPLEX,
|
98 |
+
1,
|
99 |
+
(0, 255, 0),
|
100 |
+
2,
|
101 |
+
)
|
102 |
final_video.write(frame)
|
103 |
num_frames += 1
|
104 |
if num_frames == max_frame:
|
105 |
break
|
106 |
cap.release()
|
107 |
final_video.release()
|
108 |
+
return 'output.mp4', [plates[k] for k in plates.keys()]
|
109 |
|
110 |
|
111 |
image_interface = gr.Interface(
|
detector/utils.py
CHANGED
@@ -30,29 +30,15 @@ def imcrop(img, bbox):
|
|
30 |
|
31 |
|
32 |
def detect_plates(img):
|
33 |
-
|
34 |
-
records = detect.pandas().xyxy[0].to_dict(orient='records')
|
35 |
-
plates = []
|
36 |
-
if records:
|
37 |
-
for plate in records:
|
38 |
-
xi, yi, xf, yf = int(plate['xmin']), int(plate['ymin']), int(plate['xmax']), int(plate['ymax'])
|
39 |
-
crop = imcrop(img, (xi, yi, xf, yf))
|
40 |
-
plates.append(((xi, yi), (xf, yf), crop))
|
41 |
-
return plates
|
42 |
|
43 |
|
44 |
def detect_chars(img):
|
45 |
img = cv2.resize(img, (640, 320))
|
46 |
detect = model_chars(img)
|
47 |
records = detect.pandas().xyxy[0].to_dict(orient='records')
|
48 |
-
yolo = np.squeeze(detect.render())
|
49 |
text = ''
|
50 |
if records:
|
51 |
records = sorted(records, key=lambda d: d['xmin'])
|
52 |
text = ''.join([i.get('name') for i in records])
|
53 |
-
return text
|
54 |
-
|
55 |
-
|
56 |
-
def save_plates(img):
|
57 |
-
detect = model_plates(img)
|
58 |
-
detect.crop(save=True)
|
|
|
30 |
|
31 |
|
32 |
def detect_plates(img):
|
33 |
+
return model_plates(img)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
|
36 |
def detect_chars(img):
|
37 |
img = cv2.resize(img, (640, 320))
|
38 |
detect = model_chars(img)
|
39 |
records = detect.pandas().xyxy[0].to_dict(orient='records')
|
|
|
40 |
text = ''
|
41 |
if records:
|
42 |
records = sorted(records, key=lambda d: d['xmin'])
|
43 |
text = ''.join([i.get('name') for i in records])
|
44 |
+
return text
|
|
|
|
|
|
|
|
|
|