Update app.py
Browse files
app.py
CHANGED
|
@@ -14,11 +14,19 @@ from datetime import datetime
|
|
| 14 |
try:
|
| 15 |
from license_plate_ocr import extract_license_plate_text
|
| 16 |
OCR_AVAILABLE = True
|
| 17 |
-
print("OCR module loaded successfully")
|
| 18 |
except ImportError as e:
|
| 19 |
-
print(f"OCR module not available: {e}")
|
| 20 |
OCR_AVAILABLE = False
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
torch.hub.download_url_to_file('https://github.com/Janno1402/Helmet-License-Plate-Detection/blob/main/Sample-Image-1.jpg?raw=true', 'sample_1.jpg')
|
| 23 |
torch.hub.download_url_to_file('https://github.com/Janno1402/Helmet-License-Plate-Detection/blob/main/Sample-Image-2.jpg?raw=true', 'sample_2.jpg')
|
| 24 |
torch.hub.download_url_to_file('https://github.com/Janno1402/Helmet-License-Plate-Detection/blob/main/Sample-Image-3.jpg?raw=true', 'sample_3.jpg')
|
|
@@ -28,7 +36,7 @@ torch.hub.download_url_to_file('https://github.com/Janno1402/Helmet-License-Plat
|
|
| 28 |
model = YOLO("best.pt")
|
| 29 |
class_names = {0: 'With Helmet', 1: 'Without Helmet', 2: 'License Plate'}
|
| 30 |
|
| 31 |
-
def crop_license_plates(image, detections, extract_text=False):
|
| 32 |
cropped_plates = []
|
| 33 |
|
| 34 |
try:
|
|
@@ -101,10 +109,18 @@ def crop_license_plates(image, detections, extract_text=False):
|
|
| 101 |
'text': 'Processing...'
|
| 102 |
}
|
| 103 |
|
| 104 |
-
if extract_text and OCR_AVAILABLE:
|
| 105 |
try:
|
| 106 |
-
print(f"Extracting text from license plate {i+1}...")
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
if plate_text and plate_text.strip() and not plate_text.startswith('Error'):
|
| 109 |
plate_data['text'] = plate_text.strip()
|
| 110 |
print(f"Extracted text: {plate_text.strip()}")
|
|
@@ -114,7 +130,7 @@ def crop_license_plates(image, detections, extract_text=False):
|
|
| 114 |
except Exception as e:
|
| 115 |
print(f"OCR extraction failed for plate {i+1}: {e}")
|
| 116 |
plate_data['text'] = f'OCR Failed: {str(e)}'
|
| 117 |
-
elif extract_text and not OCR_AVAILABLE:
|
| 118 |
plate_data['text'] = 'OCR not available'
|
| 119 |
else:
|
| 120 |
plate_data['text'] = 'OCR disabled'
|
|
@@ -204,7 +220,8 @@ def yoloV8_func(
|
|
| 204 |
show_confidence=True,
|
| 205 |
crop_plates=True,
|
| 206 |
extract_text=False,
|
| 207 |
-
ocr_on_no_helmet=False
|
|
|
|
| 208 |
):
|
| 209 |
if image_size is None:
|
| 210 |
image_size = 640
|
|
@@ -245,6 +262,7 @@ def yoloV8_func(
|
|
| 245 |
|
| 246 |
has_no_helmet = any(detection['Object'] == 'Without Helmet' for detection in detections)
|
| 247 |
should_extract_text = extract_text or (ocr_on_no_helmet and has_no_helmet)
|
|
|
|
| 248 |
|
| 249 |
if crop_plates and detections:
|
| 250 |
try:
|
|
@@ -254,12 +272,12 @@ def yoloV8_func(
|
|
| 254 |
if ocr_on_no_helmet and has_no_helmet:
|
| 255 |
print("β οΈ No helmet detected - OCR will be performed on license plates")
|
| 256 |
|
| 257 |
-
cropped_plates = crop_license_plates(image, detections, should_extract_text)
|
| 258 |
print(f"Successfully cropped {len(cropped_plates)} license plates")
|
| 259 |
|
| 260 |
license_plate_gallery = [plate_data['image'] for plate_data in cropped_plates]
|
| 261 |
|
| 262 |
-
if should_extract_text and
|
| 263 |
print("Extracting text from license plates...")
|
| 264 |
plate_texts = []
|
| 265 |
for i, plate_data in enumerate(cropped_plates):
|
|
@@ -269,7 +287,7 @@ def yoloV8_func(
|
|
| 269 |
plate_texts.append(f"π¨ No Helmet Violation - Plate {i+1}: {text}")
|
| 270 |
else:
|
| 271 |
plate_texts.append(f"Plate {i+1}: {text}")
|
| 272 |
-
elif should_extract_text and not
|
| 273 |
plate_texts = ["OCR not available - install requirements: pip install transformers easyocr"]
|
| 274 |
elif not should_extract_text:
|
| 275 |
if ocr_on_no_helmet and not has_no_helmet:
|
|
@@ -361,7 +379,9 @@ with gr.Blocks(css=custom_css, title="YOLOv11 Motorcyclist Helmet Detection") as
|
|
| 361 |
<p>This application uses YOLOv11 to detect Motorcyclists with and without Helmets in images.</p>
|
| 362 |
<p>Upload an image, adjust the parameters, and view the detection results with detailed statistics.</p>
|
| 363 |
<p><strong>Features:</strong> License plate cropping and optional text recognition!</p>
|
| 364 |
-
<p><strong>OCR Status:</strong>
|
|
|
|
|
|
|
| 365 |
</div>
|
| 366 |
""")
|
| 367 |
|
|
@@ -379,13 +399,31 @@ with gr.Blocks(css=custom_css, title="YOLOv11 Motorcyclist Helmet Detection") as
|
|
| 379 |
gr.Markdown("### License Plate Options")
|
| 380 |
crop_plates = gr.Checkbox(value=True, label="Crop License Plates")
|
| 381 |
|
| 382 |
-
|
|
|
|
| 383 |
extract_text = gr.Checkbox(value=False, label="Extract Text from License Plates (OCR)")
|
| 384 |
ocr_on_no_helmet = gr.Checkbox(value=True, label="π¨ Auto-OCR when No Helmet Detected")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 385 |
gr.Markdown("*Note: OCR processing may take additional time*")
|
| 386 |
else:
|
| 387 |
extract_text = gr.Checkbox(value=False, label="Extract Text (OCR Not Available)", interactive=False)
|
| 388 |
ocr_on_no_helmet = gr.Checkbox(value=False, label="π¨ Auto-OCR when No Helmet (Not Available)", interactive=False)
|
|
|
|
| 389 |
gr.Markdown("*Install requirements: `pip install torch transformers easyocr opencv-python`*")
|
| 390 |
|
| 391 |
submit_btn = gr.Button("Detect Objects", variant="primary")
|
|
@@ -450,7 +488,7 @@ with gr.Blocks(css=custom_css, title="YOLOv11 Motorcyclist Helmet Detection") as
|
|
| 450 |
|
| 451 |
submit_btn.click(
|
| 452 |
fn=yoloV8_func,
|
| 453 |
-
inputs=[input_image, image_size, conf_threshold, iou_threshold, show_stats, gr.State(True), crop_plates, extract_text, ocr_on_no_helmet],
|
| 454 |
outputs=[output_image, output_table, output_stats, license_gallery, download_file, plate_text_output]
|
| 455 |
)
|
| 456 |
|
|
|
|
| 14 |
try:
|
| 15 |
from license_plate_ocr import extract_license_plate_text
|
| 16 |
OCR_AVAILABLE = True
|
| 17 |
+
print("Basic OCR module loaded successfully")
|
| 18 |
except ImportError as e:
|
| 19 |
+
print(f"Basic OCR module not available: {e}")
|
| 20 |
OCR_AVAILABLE = False
|
| 21 |
|
| 22 |
+
try:
|
| 23 |
+
from advanced_ocr import extract_license_plate_text_advanced, get_available_models, set_ocr_model
|
| 24 |
+
ADVANCED_OCR_AVAILABLE = True
|
| 25 |
+
print("Advanced OCR module loaded successfully")
|
| 26 |
+
except ImportError as e:
|
| 27 |
+
print(f"Advanced OCR module not available: {e}")
|
| 28 |
+
ADVANCED_OCR_AVAILABLE = False
|
| 29 |
+
|
| 30 |
torch.hub.download_url_to_file('https://github.com/Janno1402/Helmet-License-Plate-Detection/blob/main/Sample-Image-1.jpg?raw=true', 'sample_1.jpg')
|
| 31 |
torch.hub.download_url_to_file('https://github.com/Janno1402/Helmet-License-Plate-Detection/blob/main/Sample-Image-2.jpg?raw=true', 'sample_2.jpg')
|
| 32 |
torch.hub.download_url_to_file('https://github.com/Janno1402/Helmet-License-Plate-Detection/blob/main/Sample-Image-3.jpg?raw=true', 'sample_3.jpg')
|
|
|
|
| 36 |
model = YOLO("best.pt")
|
| 37 |
class_names = {0: 'With Helmet', 1: 'Without Helmet', 2: 'License Plate'}
|
| 38 |
|
| 39 |
+
def crop_license_plates(image, detections, extract_text=False, selected_model="auto"):
|
| 40 |
cropped_plates = []
|
| 41 |
|
| 42 |
try:
|
|
|
|
| 109 |
'text': 'Processing...'
|
| 110 |
}
|
| 111 |
|
| 112 |
+
if extract_text and (OCR_AVAILABLE or ADVANCED_OCR_AVAILABLE):
|
| 113 |
try:
|
| 114 |
+
print(f"Extracting text from license plate {i+1} using {selected_ocr_model}...")
|
| 115 |
+
|
| 116 |
+
if ADVANCED_OCR_AVAILABLE and selected_ocr_model != "basic":
|
| 117 |
+
if selected_ocr_model != "auto":
|
| 118 |
+
set_ocr_model(selected_ocr_model)
|
| 119 |
+
plate_text = extract_license_plate_text_advanced(cropped_plate,
|
| 120 |
+
None if selected_ocr_model == "auto" else selected_ocr_model)
|
| 121 |
+
else:
|
| 122 |
+
plate_text = extract_license_plate_text(cropped_plate)
|
| 123 |
+
|
| 124 |
if plate_text and plate_text.strip() and not plate_text.startswith('Error'):
|
| 125 |
plate_data['text'] = plate_text.strip()
|
| 126 |
print(f"Extracted text: {plate_text.strip()}")
|
|
|
|
| 130 |
except Exception as e:
|
| 131 |
print(f"OCR extraction failed for plate {i+1}: {e}")
|
| 132 |
plate_data['text'] = f'OCR Failed: {str(e)}'
|
| 133 |
+
elif extract_text and not (OCR_AVAILABLE or ADVANCED_OCR_AVAILABLE):
|
| 134 |
plate_data['text'] = 'OCR not available'
|
| 135 |
else:
|
| 136 |
plate_data['text'] = 'OCR disabled'
|
|
|
|
| 220 |
show_confidence=True,
|
| 221 |
crop_plates=True,
|
| 222 |
extract_text=False,
|
| 223 |
+
ocr_on_no_helmet=False,
|
| 224 |
+
selected_ocr_model="auto"
|
| 225 |
):
|
| 226 |
if image_size is None:
|
| 227 |
image_size = 640
|
|
|
|
| 262 |
|
| 263 |
has_no_helmet = any(detection['Object'] == 'Without Helmet' for detection in detections)
|
| 264 |
should_extract_text = extract_text or (ocr_on_no_helmet and has_no_helmet)
|
| 265 |
+
ocr_available = OCR_AVAILABLE or ADVANCED_OCR_AVAILABLE
|
| 266 |
|
| 267 |
if crop_plates and detections:
|
| 268 |
try:
|
|
|
|
| 272 |
if ocr_on_no_helmet and has_no_helmet:
|
| 273 |
print("β οΈ No helmet detected - OCR will be performed on license plates")
|
| 274 |
|
| 275 |
+
cropped_plates = crop_license_plates(image, detections, should_extract_text, selected_ocr_model)
|
| 276 |
print(f"Successfully cropped {len(cropped_plates)} license plates")
|
| 277 |
|
| 278 |
license_plate_gallery = [plate_data['image'] for plate_data in cropped_plates]
|
| 279 |
|
| 280 |
+
if should_extract_text and ocr_available:
|
| 281 |
print("Extracting text from license plates...")
|
| 282 |
plate_texts = []
|
| 283 |
for i, plate_data in enumerate(cropped_plates):
|
|
|
|
| 287 |
plate_texts.append(f"π¨ No Helmet Violation - Plate {i+1}: {text}")
|
| 288 |
else:
|
| 289 |
plate_texts.append(f"Plate {i+1}: {text}")
|
| 290 |
+
elif should_extract_text and not ocr_available:
|
| 291 |
plate_texts = ["OCR not available - install requirements: pip install transformers easyocr"]
|
| 292 |
elif not should_extract_text:
|
| 293 |
if ocr_on_no_helmet and not has_no_helmet:
|
|
|
|
| 379 |
<p>This application uses YOLOv11 to detect Motorcyclists with and without Helmets in images.</p>
|
| 380 |
<p>Upload an image, adjust the parameters, and view the detection results with detailed statistics.</p>
|
| 381 |
<p><strong>Features:</strong> License plate cropping and optional text recognition!</p>
|
| 382 |
+
<p><strong>OCR Status:</strong>
|
| 383 |
+
{'β
Advanced OCR Available' if ADVANCED_OCR_AVAILABLE else 'π‘ Basic OCR Available' if OCR_AVAILABLE else 'β OCR Not Available (install requirements)'}
|
| 384 |
+
</p>
|
| 385 |
</div>
|
| 386 |
""")
|
| 387 |
|
|
|
|
| 399 |
gr.Markdown("### License Plate Options")
|
| 400 |
crop_plates = gr.Checkbox(value=True, label="Crop License Plates")
|
| 401 |
|
| 402 |
+
ocr_available = OCR_AVAILABLE or ADVANCED_OCR_AVAILABLE
|
| 403 |
+
if ocr_available:
|
| 404 |
extract_text = gr.Checkbox(value=False, label="Extract Text from License Plates (OCR)")
|
| 405 |
ocr_on_no_helmet = gr.Checkbox(value=True, label="π¨ Auto-OCR when No Helmet Detected")
|
| 406 |
+
|
| 407 |
+
if ADVANCED_OCR_AVAILABLE:
|
| 408 |
+
models = get_available_models()
|
| 409 |
+
model_choices = [("Auto (Recommended)", "auto"), ("Basic EasyOCR", "basic")]
|
| 410 |
+
for key, info in models.items():
|
| 411 |
+
model_choices.append((info["name"], key))
|
| 412 |
+
|
| 413 |
+
selected_ocr_model = gr.Dropdown(
|
| 414 |
+
choices=model_choices,
|
| 415 |
+
value="auto",
|
| 416 |
+
label="OCR Model Selection",
|
| 417 |
+
info="Choose OCR model (Advanced models require additional setup)"
|
| 418 |
+
)
|
| 419 |
+
else:
|
| 420 |
+
selected_ocr_model = gr.State("basic")
|
| 421 |
+
|
| 422 |
gr.Markdown("*Note: OCR processing may take additional time*")
|
| 423 |
else:
|
| 424 |
extract_text = gr.Checkbox(value=False, label="Extract Text (OCR Not Available)", interactive=False)
|
| 425 |
ocr_on_no_helmet = gr.Checkbox(value=False, label="π¨ Auto-OCR when No Helmet (Not Available)", interactive=False)
|
| 426 |
+
selected_ocr_model = gr.State("basic")
|
| 427 |
gr.Markdown("*Install requirements: `pip install torch transformers easyocr opencv-python`*")
|
| 428 |
|
| 429 |
submit_btn = gr.Button("Detect Objects", variant="primary")
|
|
|
|
| 488 |
|
| 489 |
submit_btn.click(
|
| 490 |
fn=yoloV8_func,
|
| 491 |
+
inputs=[input_image, image_size, conf_threshold, iou_threshold, show_stats, gr.State(True), crop_plates, extract_text, ocr_on_no_helmet, selected_ocr_model],
|
| 492 |
outputs=[output_image, output_table, output_stats, license_gallery, download_file, plate_text_output]
|
| 493 |
)
|
| 494 |
|