Spaces:
Runtime error
Runtime error
Commit
·
99acab0
1
Parent(s):
901dde3
models & requirements
Browse files- .gitignore +1 -0
- app.py +13 -3
- detector/__init__.py +0 -0
- detector/static/chars.pt +3 -0
- detector/static/plates.pt +3 -0
- detector/utils.py +104 -0
- requirements.txt +127 -0
.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
.idea
|
app.py
CHANGED
@@ -1,9 +1,19 @@
|
|
1 |
import gradio as gr
|
|
|
|
|
2 |
|
3 |
|
4 |
-
def
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
|
8 |
-
iface = gr.Interface(fn=
|
9 |
iface.launch()
|
|
|
1 |
import gradio as gr
|
2 |
+
import cv2
|
3 |
+
from detector.utils import detect_plates, detect_chars
|
4 |
|
5 |
|
6 |
+
def predict(img):
|
7 |
+
plates = detect_plates(img)
|
8 |
+
if len(plates) > 0:
|
9 |
+
for plate in plates:
|
10 |
+
p1, p2, crop = plate
|
11 |
+
if len(crop) > 0:
|
12 |
+
cv2.rectangle(img, p1, p2, (0, 0, 255), 2)
|
13 |
+
text, crop = detect_chars(crop)
|
14 |
+
cv2.putText(img, text, p1, cv2.FONT_HERSHEY_SIMPLEX, 4, (0, 255, 0), 5)
|
15 |
+
return img
|
16 |
|
17 |
|
18 |
+
iface = gr.Interface(fn=predict, inputs="image", outputs="image")
|
19 |
iface.launch()
|
detector/__init__.py
ADDED
File without changes
|
detector/static/chars.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:216d9926ea5ac6195b420b98b668fe8a404f180753e83032904bbcf90906b76d
|
3 |
+
size 14516597
|
detector/static/plates.pt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:34eb52d76e7dcf3e5a5d855ddb8ca95d88633c45bfa08f52e0985e2735e9754c
|
3 |
+
size 173134301
|
detector/utils.py
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
import numpy as np
|
3 |
+
import cv2
|
4 |
+
import os
|
5 |
+
|
6 |
+
BASE_DIR = os.path.abspath(os.getcwd())
|
7 |
+
|
8 |
+
model_plates = torch.hub.load('ultralytics/yolov5', 'custom',
|
9 |
+
path=os.path.join(BASE_DIR, 'detector', 'static', 'plates.pt'))
|
10 |
+
# model.conf = 0.60 # NMS confidence threshold
|
11 |
+
# model.iou = 0.60 # NMS IoU threshold
|
12 |
+
# model.agnostic = False # NMS class-agnostic
|
13 |
+
# model.multi_label = False # NMS multiple labels per box
|
14 |
+
# model.classes = None # (optional list) filter by class, i.e. = [0, 15, 16] for COCO persons, cats and dogs
|
15 |
+
# model.max_det = 1 # maximum number of detections per image
|
16 |
+
# model.amp = False # Automatic Mixed Precision (AMP) inference
|
17 |
+
|
18 |
+
model_chars = torch.hub.load('ultralytics/yolov5', 'custom',
|
19 |
+
path=os.path.join(BASE_DIR, 'detector', 'static', 'chars.pt'))
|
20 |
+
|
21 |
+
|
22 |
+
def pad_img_to_fit_bbox(img, x1, x2, y1, y2):
|
23 |
+
img = np.pad(img, ((np.abs(np.minimum(0, y1)), np.maximum(y2 - img.shape[0], 0)),
|
24 |
+
(np.abs(np.minimum(0, x1)), np.maximum(x2 - img.shape[1], 0)), (0, 0)), mode="constant")
|
25 |
+
y1 += np.abs(np.minimum(0, y1))
|
26 |
+
y2 += np.abs(np.minimum(0, y1))
|
27 |
+
x1 += np.abs(np.minimum(0, x1))
|
28 |
+
x2 += np.abs(np.minimum(0, x1))
|
29 |
+
return img, x1, x2, y1, y2
|
30 |
+
|
31 |
+
|
32 |
+
def imcrop(img, bbox):
|
33 |
+
x1, y1, x2, y2 = bbox
|
34 |
+
if x1 < 0 or y1 < 0 or x2 > img.shape[1] or y2 > img.shape[0]:
|
35 |
+
img, x1, x2, y1, y2 = pad_img_to_fit_bbox(img, x1, x2, y1, y2)
|
36 |
+
return img[y1:y2, x1:x2, :]
|
37 |
+
|
38 |
+
|
39 |
+
def detect_plates(img):
|
40 |
+
detect = model_plates(img)
|
41 |
+
records = detect.pandas().xyxy[0].to_dict(orient='records')
|
42 |
+
plates = []
|
43 |
+
if records:
|
44 |
+
for plate in records:
|
45 |
+
xi, yi, xf, yf = int(plate['xmin']), int(plate['ymin']), int(plate['xmax']), int(plate['ymax'])
|
46 |
+
crop = imcrop(img, (xi, yi, xf, yf))
|
47 |
+
plates.append(((xi, yi), (xf, yf), crop))
|
48 |
+
return plates
|
49 |
+
|
50 |
+
|
51 |
+
def detect_chars(img):
|
52 |
+
img = cv2.resize(img, (640, 480))
|
53 |
+
detect = model_chars(img)
|
54 |
+
records = detect.pandas().xyxy[0].to_dict(orient='records')
|
55 |
+
yolo = np.squeeze(detect.render())
|
56 |
+
text = ''
|
57 |
+
if records:
|
58 |
+
records = sorted(records, key=lambda d: d['xmin'])
|
59 |
+
text = ''.join([i.get('name') for i in records])
|
60 |
+
return text, img
|
61 |
+
|
62 |
+
|
63 |
+
def save_plates(img):
|
64 |
+
detect = model_plates(img)
|
65 |
+
detect.crop(save=True)
|
66 |
+
|
67 |
+
|
68 |
+
# def yolo_detections_to_norfair_detections(yolo_detections, track_points="centroid"):
|
69 |
+
# """convert detections_as_xywh to norfair detections"""
|
70 |
+
# norfair_detections = []
|
71 |
+
#
|
72 |
+
# if track_points == "centroid":
|
73 |
+
# detections_as_xywh = yolo_detections.xywh[0]
|
74 |
+
# for detection_as_xywh in detections_as_xywh:
|
75 |
+
# centroid = np.array(
|
76 |
+
# [detection_as_xywh[0].item(), detection_as_xywh[1].item()]
|
77 |
+
# )
|
78 |
+
# scores = np.array([detection_as_xywh[4].item()])
|
79 |
+
# norfair_detections.append(
|
80 |
+
# Detection(
|
81 |
+
# points=centroid,
|
82 |
+
# scores=scores,
|
83 |
+
# label=int(detection_as_xywh[-1].item()),
|
84 |
+
# )
|
85 |
+
# )
|
86 |
+
# elif track_points == "bbox":
|
87 |
+
# detections_as_xyxy = yolo_detections.xyxy[0]
|
88 |
+
# for detection_as_xyxy in detections_as_xyxy:
|
89 |
+
# bbox = np.array(
|
90 |
+
# [
|
91 |
+
# [detection_as_xyxy[0].item(), detection_as_xyxy[1].item()],
|
92 |
+
# [detection_as_xyxy[2].item(), detection_as_xyxy[3].item()],
|
93 |
+
# ]
|
94 |
+
# )
|
95 |
+
# scores = np.array(
|
96 |
+
# [detection_as_xyxy[4].item(), detection_as_xyxy[4].item()]
|
97 |
+
# )
|
98 |
+
# norfair_detections.append(
|
99 |
+
# Detection(
|
100 |
+
# points=bbox, scores=scores, label=int(detection_as_xyxy[-1].item())
|
101 |
+
# )
|
102 |
+
# )
|
103 |
+
#
|
104 |
+
# return norfair_detections
|
requirements.txt
ADDED
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
absl-py==1.3.0
|
2 |
+
aiohttp==3.8.3
|
3 |
+
aiosignal==1.3.1
|
4 |
+
anyio==3.6.2
|
5 |
+
appnope==0.1.3
|
6 |
+
asttokens==2.2.0
|
7 |
+
async-timeout==4.0.2
|
8 |
+
attrs==22.1.0
|
9 |
+
backcall==0.2.0
|
10 |
+
bcrypt==4.0.1
|
11 |
+
cachetools==5.2.0
|
12 |
+
certifi==2021.5.30
|
13 |
+
cffi==1.15.1
|
14 |
+
chardet==4.0.0
|
15 |
+
charset-normalizer==2.1.1
|
16 |
+
click==8.1.3
|
17 |
+
commonmark==0.9.1
|
18 |
+
contourpy==1.0.6
|
19 |
+
cryptography==38.0.4
|
20 |
+
cycler==0.11.0
|
21 |
+
decorator==5.1.1
|
22 |
+
easyocr==1.6.2
|
23 |
+
executing==1.2.0
|
24 |
+
fastapi==0.88.0
|
25 |
+
ffmpy==0.3.0
|
26 |
+
filterpy==1.4.5
|
27 |
+
fonttools==4.38.0
|
28 |
+
frozenlist==1.3.3
|
29 |
+
fsspec==2022.11.0
|
30 |
+
gitdb==4.0.10
|
31 |
+
GitPython==3.1.29
|
32 |
+
glob2==0.7
|
33 |
+
google-auth==2.15.0
|
34 |
+
google-auth-oauthlib==0.4.6
|
35 |
+
gradio==3.12.0
|
36 |
+
grpcio==1.51.1
|
37 |
+
h11==0.12.0
|
38 |
+
httpcore==0.15.0
|
39 |
+
httpx==0.23.1
|
40 |
+
idna==3.4
|
41 |
+
imageio==2.22.4
|
42 |
+
importlib-metadata==5.1.0
|
43 |
+
imutils==0.5.4
|
44 |
+
ipython==8.7.0
|
45 |
+
jedi==0.18.2
|
46 |
+
Jinja2==3.1.2
|
47 |
+
kiwisolver==1.4.4
|
48 |
+
linkify-it-py==1.0.3
|
49 |
+
Markdown==3.4.1
|
50 |
+
markdown-it-py==2.1.0
|
51 |
+
MarkupSafe==2.1.1
|
52 |
+
matplotlib==3.6.2
|
53 |
+
matplotlib-inline==0.1.6
|
54 |
+
mdit-py-plugins==0.3.3
|
55 |
+
mdurl==0.1.2
|
56 |
+
multidict==6.0.3
|
57 |
+
networkx==2.8.8
|
58 |
+
ninja==1.11.1
|
59 |
+
norfair==2.1.1
|
60 |
+
numpy==1.23.5
|
61 |
+
oauthlib==3.2.2
|
62 |
+
opencv-python==4.6.0.66
|
63 |
+
opencv-python-headless==4.5.4.60
|
64 |
+
orjson==3.8.3
|
65 |
+
packaging==21.3
|
66 |
+
pandas==1.5.2
|
67 |
+
paramiko==2.12.0
|
68 |
+
parso==0.8.3
|
69 |
+
pexpect==4.8.0
|
70 |
+
pickleshare==0.7.5
|
71 |
+
Pillow==9.3.0
|
72 |
+
prompt-toolkit==3.0.33
|
73 |
+
protobuf==3.20.3
|
74 |
+
psutil==5.9.4
|
75 |
+
ptyprocess==0.7.0
|
76 |
+
pure-eval==0.2.2
|
77 |
+
pyasn1==0.4.8
|
78 |
+
pyasn1-modules==0.2.8
|
79 |
+
pyclipper==1.3.0.post4
|
80 |
+
pycparser==2.21
|
81 |
+
pycryptodome==3.16.0
|
82 |
+
pydantic==1.10.2
|
83 |
+
pydub==0.25.1
|
84 |
+
Pygments==2.13.0
|
85 |
+
PyNaCl==1.5.0
|
86 |
+
pyparsing==3.0.9
|
87 |
+
python-bidi==0.4.2
|
88 |
+
python-dateutil==2.8.2
|
89 |
+
python-dotenv==0.21.0
|
90 |
+
python-multipart==0.0.5
|
91 |
+
pytz==2022.6
|
92 |
+
PyWavelets==1.4.1
|
93 |
+
PyYAML==6.0
|
94 |
+
requests==2.28.1
|
95 |
+
requests-oauthlib==1.3.1
|
96 |
+
requests-toolbelt==0.10.1
|
97 |
+
rfc3986==1.5.0
|
98 |
+
rich==12.6.0
|
99 |
+
rsa==4.9
|
100 |
+
scikit-image==0.19.3
|
101 |
+
scipy==1.9.3
|
102 |
+
seaborn==0.12.1
|
103 |
+
Shapely==1.8.5.post1
|
104 |
+
six==1.16.0
|
105 |
+
smmap==5.0.0
|
106 |
+
sniffio==1.3.0
|
107 |
+
stack-data==0.6.2
|
108 |
+
starlette==0.22.0
|
109 |
+
tensorboard==2.11.0
|
110 |
+
tensorboard-data-server==0.6.1
|
111 |
+
tensorboard-plugin-wit==1.8.1
|
112 |
+
thop==0.1.1.post2209072238
|
113 |
+
tifffile==2022.10.10
|
114 |
+
torch==1.13.0
|
115 |
+
torchvision==0.14.0
|
116 |
+
tqdm==4.64.1
|
117 |
+
traitlets==5.6.0
|
118 |
+
typing_extensions==4.4.0
|
119 |
+
uc-micro-py==1.0.1
|
120 |
+
urllib3==1.26.13
|
121 |
+
uvicorn==0.20.0
|
122 |
+
wcwidth==0.2.5
|
123 |
+
websockets==10.4
|
124 |
+
Werkzeug==2.2.2
|
125 |
+
wget==3.2
|
126 |
+
yarl==1.8.2
|
127 |
+
zipp==3.11.0
|