Spaces:
Running
Running
File size: 4,391 Bytes
27213d5 4ba5ed3 3b7e472 27213d5 3b7e472 18a03cd 2df0a06 18a03cd 83ce000 2b2bc36 f0e8f2a 3b7e472 18a03cd 3d93d68 27213d5 f0e8f2a 2b2bc36 18a03cd 2b2bc36 18a03cd 2b2bc36 27213d5 f0e8f2a 2b2bc36 18a03cd 2b2bc36 18a03cd 2b2bc36 27213d5 3b7e472 18a03cd a34cd68 18a03cd f0e8f2a 2df0a06 18a03cd 2df0a06 18a03cd a34cd68 27ef20f 2df0a06 18a03cd 2df0a06 f0e8f2a 2df0a06 a34cd68 27ef20f 2df0a06 18a03cd f0e8f2a 18a03cd f0e8f2a 18a03cd a34cd68 f8ac2af 18a03cd f8ac2af 18a03cd 3b7e472 f8ac2af | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | import torch
from ultralytics import YOLO
import easyocr
import cv2
import numpy as np
import gradio as gr
import os
import logging
import re
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Ensure directories exist
os.makedirs(os.getenv('EASYOCR_MODULE_PATH', '/app/.EasyOCR'), exist_ok=True)
os.makedirs(os.getenv('YOLO_CONFIG_DIR', '/app/.config/Ultralytics'), exist_ok=True)
# Download pretrained model
ANPR_WEIGHTS = "anpr_yolov8.pt"
if not os.path.exists(ANPR_WEIGHTS):
logger.info(f"Downloading model weights to {ANPR_WEIGHTS}")
os.system(f"wget -O {ANPR_WEIGHTS} https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8n.pt")
# Load YOLO model
try:
model = YOLO(ANPR_WEIGHTS)
logger.info(f"Successfully loaded YOLO model from {ANPR_WEIGHTS}")
except Exception as e:
logger.error(f"Error loading YOLO model from {ANPR_WEIGHTS}: {str(e)}")
raise
# Load OCR reader
try:
reader = easyocr.Reader(['en'], model_storage_directory=os.getenv('EASYOCR_MODULE_PATH', '/app/.EasyOCR'))
logger.info("Successfully initialized EasyOCR reader")
except Exception as e:
logger.error(f"Error initializing EasyOCR reader: {str(e)}")
raise
def detect_and_read_plate(image):
logger.info("Starting image processing for license plate detection")
try:
detected_texts = []
results = model(image, conf=0.1) # Low confidence for broader detection
logger.info(f"YOLO model returned {len(results)} results")
for result in results:
boxes = result.boxes.xyxy.cpu().numpy()
confidences = result.boxes.conf.cpu().numpy()
logger.info(f"Detected {len(boxes)} bounding boxes")
for box, conf in zip(boxes, confidences):
x1, y1, x2, y2 = map(int, box)
# Minimal size filter
if (x2 - x1) < 20 or (y2 - y1) < 10:
logger.warning(f"Skipping small box: ({x1}, {y1}, {x2}, {y2})")
continue
# Crop the detected license plate
plate_img = image[y1:y2, x1:x2]
if plate_img.size == 0:
logger.warning("Empty cropped image, skipping")
continue
# Run OCR
logger.info("Running EasyOCR on cropped plate")
ocr_result = reader.readtext(plate_img)
if ocr_result:
for res in ocr_result:
text = res[1]
confidence = res[2]
# Light filtering: prefer alphanumeric, avoid overly long text
if len(text) <= 12 and confidence > 0.2 and re.match(r'^[A-Z0-9\s\-]+$', text):
detected_texts.append(f"{text} (conf: {conf:.2f})")
logger.info(f"Detected Plate: {text} (YOLO conf: {conf:.2f}, OCR conf: {confidence:.2f})")
else:
logger.info(f"Rejected text: {text} (OCR conf: {confidence:.2f})")
# Draw bounding box
cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
output_text = "\n".join(detected_texts) if detected_texts else "No license plate detected"
logger.info(f"Output text: {output_text}")
return image, output_text
except Exception as e:
logger.error(f"Error during detection: {str(e)}")
return image, f"Error processing image: {str(e)}"
# Create Gradio interface
with gr.Blocks() as demo:
gr.Markdown("# Automatic Number Plate Recognition (ANPR)")
gr.Markdown("Upload an image of a car to detect and read its license plate. Results may take a few seconds.")
with gr.Row():
image_input = gr.Image(type="numpy", label="Upload an image of a car")
with gr.Row():
image_output = gr.Image(type="numpy", label="Detected License Plate Image")
text_output = gr.Textbox(label="Detected License Plate Number")
submit_button = gr.Button("Detect License Plate")
submit_button.click(
fn=detect_and_read_plate,
inputs=image_input,
outputs=[image_output, text_output],
show_progress=True
)
demo.launch(server_name="0.0.0.0", server_port=7860) |