ytcollector 1.2.3__tar.gz → 1.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ytcollector-1.2.3/ytcollector.egg-info → ytcollector-1.2.4}/PKG-INFO +1 -1
- {ytcollector-1.2.3 → ytcollector-1.2.4}/pyproject.toml +1 -1
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector/__init__.py +1 -1
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector/analyzer.py +18 -31
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector/config.py +2 -1
- {ytcollector-1.2.3 → ytcollector-1.2.4/ytcollector.egg-info}/PKG-INFO +1 -1
- {ytcollector-1.2.3 → ytcollector-1.2.4}/MANIFEST.in +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/README.md +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/setup.cfg +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector/cli.py +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector/dataset_builder.py +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector/downloader.py +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector/models/license_plate_detector.pt +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector/utils.py +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector.egg-info/SOURCES.txt +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector.egg-info/dependency_links.txt +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector.egg-info/entry_points.txt +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector.egg-info/requires.txt +0 -0
- {ytcollector-1.2.3 → ytcollector-1.2.4}/ytcollector.egg-info/top_level.txt +0 -0
|
@@ -32,7 +32,7 @@ try:
|
|
|
32
32
|
except ImportError:
|
|
33
33
|
USE_GPU = False
|
|
34
34
|
|
|
35
|
-
from .config import LICENSE_PLATE_PATTERNS, LICENSE_PLATE_MODEL_PATH, YOLO_CONFIDENCE
|
|
35
|
+
from .config import LICENSE_PLATE_PATTERNS, LICENSE_PLATE_MODEL_PATH, YOLO_CONFIDENCE, YOLO_HIGH_CONFIDENCE
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class VideoAnalyzer:
|
|
@@ -167,9 +167,9 @@ class VideoAnalyzer:
|
|
|
167
167
|
|
|
168
168
|
def detect_license_plate(self, frame, texts=None):
|
|
169
169
|
"""
|
|
170
|
-
ROI 기반 번호판 감지
|
|
170
|
+
ROI 기반 번호판 감지
|
|
171
171
|
1. YOLO로 번호판 영역(ROI)을 먼저 찾음
|
|
172
|
-
2.
|
|
172
|
+
2. 고신뢰도(>=0.6)면 바로 인정, 저신뢰도면 OCR 패턴 매칭 필요
|
|
173
173
|
"""
|
|
174
174
|
if not YOLO_AVAILABLE or frame is None:
|
|
175
175
|
return False
|
|
@@ -177,59 +177,46 @@ class VideoAnalyzer:
|
|
|
177
177
|
try:
|
|
178
178
|
self._init_yolo()
|
|
179
179
|
results = self.yolo_model(frame, verbose=False, conf=YOLO_CONFIDENCE)
|
|
180
|
-
|
|
181
|
-
yolo_detected = False
|
|
182
|
-
roi_ocr_matched = False
|
|
183
180
|
|
|
184
181
|
for r in results:
|
|
185
|
-
# 0: license plate
|
|
186
182
|
for box in r.boxes:
|
|
187
183
|
if box.cls == 0:
|
|
188
|
-
|
|
184
|
+
conf = float(box.conf[0])
|
|
189
185
|
|
|
190
|
-
# ROI 크기 필터링
|
|
186
|
+
# ROI 크기 필터링
|
|
191
187
|
x1, y1, x2, y2 = map(int, box.xyxy[0])
|
|
192
188
|
roi_w, roi_h = x2 - x1, y2 - y1
|
|
193
189
|
frame_h, frame_w = frame.shape[:2]
|
|
194
190
|
roi_area_ratio = (roi_w * roi_h) / (frame_w * frame_h)
|
|
195
191
|
|
|
196
|
-
# ROI가 전체 화면의 0.1% ~ 20% 사이여야 함
|
|
197
192
|
if roi_area_ratio < 0.001 or roi_area_ratio > 0.2:
|
|
198
193
|
continue
|
|
199
194
|
|
|
200
|
-
#
|
|
195
|
+
# 고신뢰도면 바로 인정
|
|
196
|
+
if conf >= YOLO_HIGH_CONFIDENCE:
|
|
197
|
+
return True
|
|
198
|
+
|
|
199
|
+
# 저신뢰도면 OCR 패턴 매칭 필요
|
|
201
200
|
h, w = frame.shape[:2]
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
pad_w = int((x2 - x1) * 0.15)
|
|
202
|
+
pad_h = int((y2 - y1) * 0.15)
|
|
203
|
+
|
|
206
204
|
crop_x1 = max(0, x1 - pad_w)
|
|
207
205
|
crop_y1 = max(0, y1 - pad_h)
|
|
208
206
|
crop_x2 = min(w, x2 + pad_w)
|
|
209
207
|
crop_y2 = min(h, y2 + pad_h)
|
|
210
|
-
|
|
208
|
+
|
|
211
209
|
roi = frame[crop_y1:crop_y2, crop_x1:crop_x2]
|
|
212
210
|
if roi.size > 0:
|
|
213
|
-
# ROI에 대해서만 OCR 실행
|
|
214
211
|
roi_texts = self.detect_text(roi)
|
|
215
212
|
if roi_texts:
|
|
216
|
-
|
|
213
|
+
combined = "".join([re.sub(r'[^0-9가-힣A-Za-z]', '', t) for t in roi_texts])
|
|
217
214
|
for pattern in LICENSE_PLATE_PATTERNS:
|
|
218
|
-
# 개별 텍스트 및 결합 텍스트 확인
|
|
219
215
|
if any(re.search(pattern, re.sub(r'[^0-9가-힣]', '', t)) for t in roi_texts) or \
|
|
220
|
-
re.search(pattern,
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if roi_ocr_matched: break
|
|
225
|
-
if roi_ocr_matched: break
|
|
226
|
-
|
|
227
|
-
# 최종 판정: YOLO 감지 + OCR 패턴 매칭 둘 다 만족해야 함 (오탐지 방지)
|
|
228
|
-
if yolo_detected and roi_ocr_matched:
|
|
229
|
-
return True
|
|
230
|
-
|
|
216
|
+
re.search(pattern, combined):
|
|
217
|
+
return True
|
|
218
|
+
|
|
231
219
|
except Exception as e:
|
|
232
|
-
# print(f" ⚠ 번호판 ROI 분석 에러: {e}")
|
|
233
220
|
pass
|
|
234
221
|
|
|
235
222
|
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|