Skip to content

Commit 824422b

Browse files
committed
ci: Add GitHub Actions workflow for build and release
1 parent adbf8e9 commit 824422b

File tree

2 files changed

+71
-9
lines changed

2 files changed

+71
-9
lines changed

python_src/plate_recognizer.py

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,26 @@
99
except Exception:
1010
LPD_YuNetORT = None
1111
ORT_AVAILABLE = False
12-
import easyocr
12+
try:
13+
import easyocr
14+
EASY_AVAILABLE = True
15+
except ImportError:
16+
easyocr = None
17+
EASY_AVAILABLE = False
1318

1419
try:
1520
from paddleocr import PaddleOCR
1621
PADDLE_AVAILABLE = True
1722
except ImportError:
1823
PADDLE_AVAILABLE = False
1924

25+
try:
26+
import pytesseract
27+
TESSERACT_AVAILABLE = True
28+
except ImportError:
29+
pytesseract = None
30+
TESSERACT_AVAILABLE = False
31+
2032
MODEL_PATH = os.path.join(os.path.dirname(__file__), 'license_plate_detection.onnx')
2133
CONF_THRESHOLD = 0.3
2234
NMS_THRESHOLD = 0.3
@@ -52,16 +64,65 @@ def enhance_plate_image(plate_img, scale_factor=3.0):
5264
except Exception:
5365
return plate_img
5466

67+
ALLOWED_CHARS = 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
68+
69+
70+
def normalize_text(text):
71+
if not text:
72+
return ""
73+
cleaned = ''.join(c for c in text if c.isalnum() or c in ALLOWED_CHARS)
74+
return cleaned.upper()
75+
76+
5577
def recognize_text_easyocr(img, reader):
78+
if not EASY_AVAILABLE or reader is None:
79+
return ""
5680
try:
57-
allowlist = 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
58-
results = reader.readtext(img, detail=1, paragraph=False, allowlist=allowlist)
59-
text = ' '.join([result[1] for result in results if result[2] > 0.2])
60-
cleaned_text = ''.join(c for c in text if c.isalnum() or c in allowlist).upper()
61-
return cleaned_text
81+
results = reader.readtext(img, detail=1, paragraph=False, allowlist=ALLOWED_CHARS)
82+
lines = [result[1] for result in results if len(result) > 2 and result[2] > 0.2]
83+
return normalize_text(' '.join(lines))
6284
except Exception:
6385
return ""
6486

87+
88+
def recognize_text_paddle(img, reader):
89+
if not PADDLE_AVAILABLE or reader is None:
90+
return ""
91+
try:
92+
# PaddleOCR returns a list of detections per image
93+
ocr_results = reader.ocr(img, cls=True)
94+
texts = []
95+
for result in ocr_results:
96+
for entry in result:
97+
if len(entry) >= 2:
98+
candidate = entry[1][0] if isinstance(entry[1], (list, tuple)) else entry[1]
99+
texts.append(candidate)
100+
return normalize_text(' '.join(texts))
101+
except Exception:
102+
return ""
103+
104+
105+
def recognize_text_tesseract(img):
106+
if not TESSERACT_AVAILABLE:
107+
return ""
108+
try:
109+
config = '--oem 3 --psm 7'
110+
text = pytesseract.image_to_string(img, config=config, lang='eng+rus')
111+
return normalize_text(text)
112+
except Exception:
113+
return ""
114+
115+
116+
def recognize_text(img, easy_reader=None, paddle_reader=None):
117+
# Prefer PaddleOCR on Linux because it does not require PyTorch-sized dependencies
118+
text = recognize_text_paddle(img, paddle_reader)
119+
if text:
120+
return text
121+
text = recognize_text_easyocr(img, easy_reader)
122+
if text:
123+
return text
124+
return recognize_text_tesseract(img)
125+
65126
def recognize_plate_from_rtsp(rtsp_url, frame_skip=2, min_score=0.65, min_area=2000, min_height=40, min_aspect=1.2, max_aspect=7.5, max_frames=10, use_ort=False):
66127
"""
67128
Recognize plates from RTSP stream.
@@ -88,7 +149,7 @@ def recognize_plate_from_rtsp(rtsp_url, frame_skip=2, min_score=0.65, min_area=2
88149
backendId=cv.dnn.DNN_BACKEND_OPENCV,
89150
targetId=cv.dnn.DNN_TARGET_CPU
90151
)
91-
reader = easyocr.Reader(['en', 'ru'])
152+
easyocr_reader = easyocr.Reader(['en', 'ru']) if EASY_AVAILABLE else None
92153
paddle_reader = PaddleOCR(lang='en', use_angle_cls=True, show_log=False, use_gpu=False) if PADDLE_AVAILABLE else None
93154
cap = cv.VideoCapture(rtsp_url)
94155
frame_count = 0
@@ -130,7 +191,7 @@ def recognize_plate_from_rtsp(rtsp_url, frame_skip=2, min_score=0.65, min_area=2
130191
continue
131192
plate_img = frame[y_min:y_max, x_min:x_max]
132193
plate_img = enhance_plate_image(plate_img)
133-
text = recognize_text_easyocr(plate_img, reader)
194+
text = recognize_text(plate_img, easyocr_reader, paddle_reader)
134195
results.append({
135196
"score": float(score),
136197
"text": text,
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
onnxruntime==1.17.1
22
opencv-python-headless
33
numpy<2.0
4-
easyocr
4+
paddlepaddle
5+
paddleocr
56
pytesseract
67
pillow

0 commit comments

Comments
 (0)