muddasser commited on
Commit
18a03cd
·
verified ·
1 Parent(s): f8ac2af

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -42
app.py CHANGED
@@ -5,71 +5,121 @@ import cv2
5
  import numpy as np
6
  import gradio as gr
7
  import os
 
 
 
 
 
 
8
 
9
  # Ensure directories exist
10
  os.makedirs(os.getenv('EASYOCR_MODULE_PATH', '/app/.EasyOCR'), exist_ok=True)
11
  os.makedirs(os.getenv('YOLO_CONFIG_DIR', '/app/.config/Ultralytics'), exist_ok=True)
12
 
13
- # Download pretrained ANPR model (trained to detect license plates)
14
  ANPR_WEIGHTS = "anpr_yolov8.pt"
15
  if not os.path.exists(ANPR_WEIGHTS):
16
- print(f"Downloading model weights to {ANPR_WEIGHTS}")
17
  os.system(f"wget -O {ANPR_WEIGHTS} https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8n.pt")
18
 
19
  # Load YOLO ANPR model with error handling
20
  try:
21
  model = YOLO(ANPR_WEIGHTS)
22
- print(f"Successfully loaded YOLO model from {ANPR_WEIGHTS}")
23
  except Exception as e:
24
- print(f"Error loading YOLO model from {ANPR_WEIGHTS}: {str(e)}")
25
  raise
26
 
27
  # Load OCR reader with specified model storage directory
28
  try:
29
  reader = easyocr.Reader(['en'], model_storage_directory=os.getenv('EASYOCR_MODULE_PATH', '/app/.EasyOCR'))
30
- print("Successfully initialized EasyOCR reader")
31
  except Exception as e:
32
- print(f"Error initializing EasyOCR reader: {str(e)}")
33
  raise
34
 
35
  def detect_and_read_plate(image):
36
- # Initialize an empty list to store detected plate texts
37
- detected_texts = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- results = model(image)
40
- for result in results:
41
- boxes = result.boxes.xyxy.cpu().numpy() # [x1, y1, x2, y2]
42
- for box in boxes:
43
- x1, y1, x2, y2 = map(int, box)
44
- # Crop the detected license plate
45
- plate_img = image[y1:y2, x1:x2]
46
- if plate_img.size == 0:
47
- continue
48
- # OCR to read text
49
- ocr_result = reader.readtext(plate_img)
50
- if ocr_result:
51
- text = " ".join([res[1] for res in ocr_result])
52
- detected_texts.append(text)
53
- print(f"Detected Plate: {text}")
54
- # Draw bounding box (optional, kept for visualization)
55
- cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
56
- # Optionally remove text on image
57
- # cv2.putText(image, text, (x1, y1 - 10),
58
- # cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
59
 
60
- # Join detected texts (in case multiple plates are detected)
61
- output_text = "\n".join(detected_texts) if detected_texts else "No license plate detected"
62
- return image, output_text
 
 
 
 
63
 
64
- # Create Gradio interface
65
- demo = gr.Interface(
66
- fn=detect_and_read_plate,
67
- inputs=gr.Image(type="numpy", label="Upload an image of a car"),
68
- outputs=[
69
- gr.Image(type="numpy", label="Detected License Plate Image"),
70
- gr.Textbox(label="Detected License Plate Number")
71
- ],
72
- title="Automatic Number Plate Recognition (ANPR)",
73
- description="Upload an image of a car to detect and read its license plate. The detected plate number will be shown below the image."
74
- )
75
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
5
  import numpy as np
6
  import gradio as gr
7
  import os
8
+ import logging
9
+ import time
10
+
11
+ # Set up logging
12
+ logging.basicConfig(level=logging.INFO)
13
+ logger = logging.getLogger(__name__)
14
 
15
  # Ensure directories exist
16
  os.makedirs(os.getenv('EASYOCR_MODULE_PATH', '/app/.EasyOCR'), exist_ok=True)
17
  os.makedirs(os.getenv('YOLO_CONFIG_DIR', '/app/.config/Ultralytics'), exist_ok=True)
18
 
19
+ # Download pretrained ANPR model
20
  ANPR_WEIGHTS = "anpr_yolov8.pt"
21
  if not os.path.exists(ANPR_WEIGHTS):
22
+ logger.info(f"Downloading model weights to {ANPR_WEIGHTS}")
23
  os.system(f"wget -O {ANPR_WEIGHTS} https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8n.pt")
24
 
25
  # Load YOLO ANPR model with error handling
26
  try:
27
  model = YOLO(ANPR_WEIGHTS)
28
+ logger.info(f"Successfully loaded YOLO model from {ANPR_WEIGHTS}")
29
  except Exception as e:
30
+ logger.error(f"Error loading YOLO model from {ANPR_WEIGHTS}: {str(e)}")
31
  raise
32
 
33
  # Load OCR reader with specified model storage directory
34
  try:
35
  reader = easyocr.Reader(['en'], model_storage_directory=os.getenv('EASYOCR_MODULE_PATH', '/app/.EasyOCR'))
36
+ logger.info("Successfully initialized EasyOCR reader")
37
  except Exception as e:
38
+ logger.error(f"Error initializing EasyOCR reader: {str(e)}")
39
  raise
40
 
41
  def detect_and_read_plate(image):
42
+ start_time = time.time()
43
+ logger.info("Starting image processing for license plate detection")
44
+
45
+ try:
46
+ # Resize image to reduce processing time (optional, adjust as needed)
47
+ max_size = 640
48
+ h, w = image.shape[:2]
49
+ if max(h, w) > max_size:
50
+ scale = max_size / max(h, w)
51
+ image = cv2.resize(image, (int(w * scale), int(h * scale)))
52
+ logger.info(f"Resized image to {image.shape[:2]}")
53
+
54
+ detected_texts = []
55
+ results = model(image, conf=0.25) # Lower confidence threshold for detection
56
+ logger.info(f"YOLO model returned {len(results)} results")
57
+
58
+ for result in results:
59
+ boxes = result.boxes.xyxy.cpu().numpy() # [x1, y1, x2, y2]
60
+ confidences = result.boxes.conf.cpu().numpy()
61
+ logger.info(f"Detected {len(boxes)} bounding boxes")
62
+
63
+ for box, conf in zip(boxes, confidences):
64
+ x1, y1, x2, y2 = map(int, box)
65
+ # Skip small or invalid boxes
66
+ if (x2 - x1) < 20 or (y2 - y1) < 10:
67
+ logger.warning(f"Skipping small box: ({x1}, {y1}, {x2}, {y2})")
68
+ continue
69
+
70
+ # Crop the detected license plate
71
+ plate_img = image[y1:y2, x1:x2]
72
+ if plate_img.size == 0:
73
+ logger.warning("Empty cropped image, skipping")
74
+ continue
75
+
76
+ # Run OCR with timeout
77
+ try:
78
+ logger.info("Running EasyOCR on cropped plate")
79
+ ocr_result = reader.readtext(plate_img, timeout=5) # 5-second timeout
80
+ if ocr_result:
81
+ text = " ".join([res[1] for res in ocr_result if res[2] > 0.3]) # Filter low-confidence OCR
82
+ if text.strip():
83
+ detected_texts.append(text)
84
+ logger.info(f"Detected Plate: {text} (confidence: {conf:.2f})")
85
+ else:
86
+ logger.info("OCR returned empty or low-confidence text")
87
+ else:
88
+ logger.info("No text detected by EasyOCR")
89
+
90
+ # Draw bounding box
91
+ cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
92
+ except Exception as e:
93
+ logger.warning(f"OCR processing failed: {str(e)}")
94
+ continue
95
+
96
+ # Prepare output
97
+ output_text = "\n".join(detected_texts) if detected_texts else "No license plate detected"
98
+ processing_time = time.time() - start_time
99
+ logger.info(f"Processing completed in {processing_time:.2f} seconds. Output text: {output_text}")
100
+
101
+ return image, output_text
102
+ except Exception as e:
103
+ logger.error(f"Error during detection: {str(e)}")
104
+ return image, f"Error processing image: {str(e)}"
105
+
106
+ # Create Gradio interface with progress feedback
107
+ with gr.Blocks() as demo:
108
+ gr.Markdown("# Automatic Number Plate Recognition (ANPR)")
109
+ gr.Markdown("Upload an image of a car to detect and read its license plate. Results may take a few seconds.")
110
 
111
+ with gr.Row():
112
+ image_input = gr.Image(type="numpy", label="Upload an image of a car")
113
+ with gr.Row():
114
+ image_output = gr.Image(type="numpy", label="Detected License Plate Image")
115
+ text_output = gr.Textbox(label="Detected License Plate Number")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
+ submit_button = gr.Button("Detect License Plate")
118
+ submit_button.click(
119
+ fn=detect_and_read_plate,
120
+ inputs=image_input,
121
+ outputs=[image_output, text_output],
122
+ show_progress=True
123
+ )
124
 
 
 
 
 
 
 
 
 
 
 
 
125
  demo.launch(server_name="0.0.0.0", server_port=7860)