Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -14,10 +14,10 @@ model2 = YOLO(model2_path)
|
|
14 |
# Initialize PaddleOCR globally to avoid re-initializing on each call
|
15 |
# For Hugging Face Spaces, ensure necessary PaddleOCR models are downloaded (e.g., within Dockerfile or setup script)
|
16 |
# Using 'en' for English license plates and disabling angle classification for simplicity
|
17 |
-
ocr = PaddleOCR(
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
|
22 |
# Example images paths - these might need adjustment for Hugging Face Spaces
|
23 |
# If these are locally stored, they need to be part of the uploaded files in your Space.
|
@@ -33,6 +33,9 @@ def detect_and_annotate(image):
|
|
33 |
# Convert PIL image to OpenCV format
|
34 |
img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
|
35 |
|
|
|
|
|
|
|
36 |
# Start with a copy of the original image for annotations
|
37 |
annotated_frame = img.copy()
|
38 |
|
@@ -41,71 +44,70 @@ def detect_and_annotate(image):
|
|
41 |
|
42 |
# IMPORTANT FIX: The .plot() method on results[0] already returns a new image with annotations.
|
43 |
# We should use this directly as our base annotated_frame.
|
44 |
-
if results and results[0].boxes: # Check if vehicle results exist and have boxes
|
45 |
# Plot vehicle detections. This returns an annotated NumPy array (BGR format).
|
46 |
-
annotated_frame = results[0].plot(line_width=3)
|
47 |
-
|
48 |
# License plate detection only if vehicle is detected
|
49 |
license_plate_results = model2(img)
|
50 |
-
|
51 |
if license_plate_results and len(license_plate_results[0].boxes) > 0:
|
52 |
# Iterate through detected license plates if there are multiple
|
53 |
for license_box_data in license_plate_results[0].boxes:
|
54 |
license_box = license_box_data.xyxy[0].cpu().numpy()
|
55 |
x1, y1, x2, y2 = map(int, license_box)
|
56 |
-
|
57 |
# Draw rectangle for license plate on the annotated frame
|
58 |
cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), (255, 0, 0), 3)
|
59 |
-
|
60 |
# OCR on license plate region
|
61 |
license_plate_region = img[y1:y2, x1:x2]
|
62 |
-
|
63 |
try:
|
64 |
# IMPORTANT FIX: Pass the NumPy array directly to PaddleOCR's ocr method
|
65 |
# This avoids the file read/write error.
|
66 |
-
ocr_result = ocr.
|
67 |
-
|
68 |
license_plate_text = ""
|
69 |
-
if ocr_result and ocr_result[0]:
|
70 |
-
|
|
|
|
|
71 |
text = re.sub(r'[^a-zA-Z0-9]', '', text)
|
72 |
license_plate_text = text
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
except Exception as e:
|
76 |
-
|
77 |
print(f"OCR error on region: {e}")
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
#
|
84 |
-
annotated_frame = img.copy()
|
85 |
-
# Add text to indicate no vehicles were found
|
86 |
-
h, w, _ = annotated_frame.shape
|
87 |
-
text_message = "No vehicles detected."
|
88 |
-
font_scale = 1.0
|
89 |
-
font_thickness = 2
|
90 |
-
text_size = cv2.getTextSize(text_message, cv2.FONT_HERSHEY_SIMPLEX, font_scale, font_thickness)[0]
|
91 |
-
text_x = (w - text_size[0]) // 2
|
92 |
-
text_y = (h + text_size[1]) // 2
|
93 |
-
cv2.putText(annotated_frame, text_message, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), font_thickness, cv2.LINE_AA)
|
94 |
-
|
95 |
|
96 |
# Convert back to RGB for display in Gradio
|
97 |
annotated_frame = cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB)
|
98 |
-
return annotated_frame
|
99 |
|
100 |
iface = gr.Interface(
|
101 |
fn=detect_and_annotate,
|
102 |
inputs=gr.Image(type="pil"),
|
103 |
-
outputs=gr.Image(type="numpy"),
|
|
|
104 |
title="Vehicle & License Plate Detection with OCR",
|
105 |
-
description="Upload an image. The app will detect vehicles and license plates, perform OCR, and display the result with annotations.",
|
106 |
examples=example_images,
|
107 |
cache_examples=False
|
108 |
)
|
109 |
|
110 |
if __name__ == "__main__":
|
111 |
-
iface.launch(share=True)
|
|
|
14 |
# Initialize PaddleOCR globally to avoid re-initializing on each call
|
15 |
# For Hugging Face Spaces, ensure necessary PaddleOCR models are downloaded (e.g., within Dockerfile or setup script)
|
16 |
# Using 'en' for English license plates and disabling angle classification for simplicity
|
17 |
+
ocr = PaddleOCR(use_doc_orientation_classify=False,
|
18 |
+
use_doc_unwarping=False,
|
19 |
+
use_textline_orientation=False,
|
20 |
+
lang='en') # Added lang='en' for better English OCR
|
21 |
|
22 |
# Example images paths - these might need adjustment for Hugging Face Spaces
|
23 |
# If these are locally stored, they need to be part of the uploaded files in your Space.
|
|
|
33 |
# Convert PIL image to OpenCV format
|
34 |
img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
|
35 |
|
36 |
+
# Initialize message
|
37 |
+
output_message = ""
|
38 |
+
|
39 |
# Start with a copy of the original image for annotations
|
40 |
annotated_frame = img.copy()
|
41 |
|
|
|
44 |
|
45 |
# IMPORTANT FIX: The .plot() method on results[0] already returns a new image with annotations.
|
46 |
# We should use this directly as our base annotated_frame.
|
47 |
+
if results and results[0].boxes and len(results[0].boxes) > 0: # Check if vehicle results exist and have boxes
|
48 |
# Plot vehicle detections. This returns an annotated NumPy array (BGR format).
|
49 |
+
annotated_frame = results[0].plot(line_width=3)
|
50 |
+
|
51 |
# License plate detection only if vehicle is detected
|
52 |
license_plate_results = model2(img)
|
53 |
+
|
54 |
if license_plate_results and len(license_plate_results[0].boxes) > 0:
|
55 |
# Iterate through detected license plates if there are multiple
|
56 |
for license_box_data in license_plate_results[0].boxes:
|
57 |
license_box = license_box_data.xyxy[0].cpu().numpy()
|
58 |
x1, y1, x2, y2 = map(int, license_box)
|
59 |
+
|
60 |
# Draw rectangle for license plate on the annotated frame
|
61 |
cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), (255, 0, 0), 3)
|
62 |
+
|
63 |
# OCR on license plate region
|
64 |
license_plate_region = img[y1:y2, x1:x2]
|
65 |
+
|
66 |
try:
|
67 |
# IMPORTANT FIX: Pass the NumPy array directly to PaddleOCR's ocr method
|
68 |
# This avoids the file read/write error.
|
69 |
+
ocr_result = ocr.ocr(img=license_plate_region, cls=True) # Changed from .predict to .ocr
|
70 |
+
|
71 |
license_plate_text = ""
|
72 |
+
if ocr_result and ocr_result[0] and ocr_result[0][0]: # Check for valid OCR result structure
|
73 |
+
# The OCR result structure for ocr.ocr is different: it's a list of blocks, each containing [bbox, (text, score)]
|
74 |
+
# We are interested in the text from the first block's first item
|
75 |
+
text = ocr_result[0][0][1][0]
|
76 |
text = re.sub(r'[^a-zA-Z0-9]', '', text)
|
77 |
license_plate_text = text
|
78 |
+
output_message += f"Detected License Plate Text: {license_plate_text}\n"
|
79 |
+
else:
|
80 |
+
output_message += "No text found on license plate.\n"
|
81 |
+
|
82 |
+
# Put text on the annotated frame (still show on image for visual feedback)
|
83 |
+
display_text_on_image = license_plate_text if license_plate_text else "No text found"
|
84 |
+
cv2.putText(annotated_frame, display_text_on_image, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
|
85 |
+
|
86 |
except Exception as e:
|
87 |
+
output_message += f"OCR Error: {e}\n"
|
88 |
print(f"OCR error on region: {e}")
|
89 |
+
else:
|
90 |
+
output_message = "No number plate detected in vehicle.\n"
|
91 |
+
else:
|
92 |
+
output_message = "No vehicles detected."
|
93 |
+
# If no vehicles are detected, simply return the original image (or a copy)
|
94 |
+
# as there's no need to annotate it with a "No vehicles detected" message on the image itself.
|
95 |
+
annotated_frame = img.copy() # Ensure we always return an image
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
# Convert back to RGB for display in Gradio
|
98 |
annotated_frame = cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB)
|
99 |
+
return annotated_frame, output_message
|
100 |
|
101 |
iface = gr.Interface(
|
102 |
fn=detect_and_annotate,
|
103 |
inputs=gr.Image(type="pil"),
|
104 |
+
outputs=[gr.Image(type="numpy", label="Annotated Image"),
|
105 |
+
gr.Textbox(label="Detection Messages")], # Added Textbox for messages
|
106 |
title="Vehicle & License Plate Detection with OCR",
|
107 |
+
description="Upload an image. The app will detect vehicles and license plates, perform OCR, and display the result with annotations and messages.",
|
108 |
examples=example_images,
|
109 |
cache_examples=False
|
110 |
)
|
111 |
|
112 |
if __name__ == "__main__":
|
113 |
+
iface.launch(share=True)
|