danhtran2mind commited on
Commit
15b4fd4
·
verified ·
1 Parent(s): aa89fb8

Upload 25 files

Browse files
.gitattributes CHANGED
@@ -42,3 +42,9 @@ apps/gradio_app/assets/examples/license_plate_detector_ocr/2/lp_video.mp4 filter
42
  assets/examples/license_plate_detector_ocr/2/lp_video_output.mp4 filter=lfs diff=lfs merge=lfs -text
43
  assets/examples/license_plate_detector_ocr/2/lp_video.mp4 filter=lfs diff=lfs merge=lfs -text
44
  assets/gradio_app_demo.jpg filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
42
  assets/examples/license_plate_detector_ocr/2/lp_video_output.mp4 filter=lfs diff=lfs merge=lfs -text
43
  assets/examples/license_plate_detector_ocr/2/lp_video.mp4 filter=lfs diff=lfs merge=lfs -text
44
  assets/gradio_app_demo.jpg filter=lfs diff=lfs merge=lfs -text
45
+ apps/gradio_app/assets/examples/license_plate_detector_ocr/1/lp_image_output.jpg filter=lfs diff=lfs merge=lfs -text
46
+ apps/gradio_app/assets/examples/license_plate_detector_ocr/2/lp_video_output.gif filter=lfs diff=lfs merge=lfs -text
47
+ apps/gradio_app/assets/examples/license_plate_detector_ocr/2/lp_video.gif filter=lfs diff=lfs merge=lfs -text
48
+ assets/examples/license_plate_detector_ocr/1/lp_image_output.jpg filter=lfs diff=lfs merge=lfs -text
49
+ assets/examples/license_plate_detector_ocr/2/lp_video_output.gif filter=lfs diff=lfs merge=lfs -text
50
+ assets/examples/license_plate_detector_ocr/2/lp_video.gif filter=lfs diff=lfs merge=lfs -text
apps/gradio_app.py CHANGED
@@ -1,141 +1,141 @@
1
- import gradio as gr
2
- import os
3
- from gradio_app.config import setup_logging, setup_sys_path
4
- from gradio_app.processor import gradio_process, update_preview, update_visibility, clear_preview_data
5
-
6
- # Initialize logging and sys.path
7
- setup_logging()
8
- setup_sys_path()
9
-
10
- # Load custom CSS
11
- custom_css = open(os.path.join(os.path.dirname(__file__), "gradio_app", "static", "styles.css"), "r").read()
12
-
13
- # Define example files
14
- examples = [
15
- {
16
- "input_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "1", "lp_image.jpg"),
17
- "output_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "1", "lp_image_output.jpg"),
18
- "input_type": "Image"
19
- },
20
- {
21
- "input_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "2", "lp_video.mp4"),
22
- "output_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "2", "lp_video_output.mp4"),
23
- "input_type": "Video"
24
- }
25
- ]
26
-
27
- # Function to handle example selection
28
- def load_example(evt: gr.SelectData):
29
- index = evt.index[0] if evt.index else 0
30
- example = examples[index]
31
- input_file = example["input_file"]
32
- output_file = example["output_file"]
33
- input_type = example["input_type"]
34
-
35
- # Update visibility based on input type
36
- input_preview_image, input_preview_video, output_image, output_video = update_visibility(input_type)
37
-
38
- # Update preview based on input file and type
39
- input_preview_image, input_preview_video = update_preview(input_file, input_type)
40
-
41
- return (
42
- input_file,
43
- input_type,
44
- input_preview_image,
45
- input_preview_video,
46
- output_file if input_type == "Image" else None,
47
- output_file if input_type == "Video" else None,
48
- "Example loaded - click Submit to process"
49
- )
50
-
51
- # Gradio Interface
52
- with gr.Blocks(css=custom_css) as iface:
53
- gr.Markdown(
54
- """
55
- # License Plate Detection and OCR
56
- Detect license plates from images or videos and read their text using
57
- advanced computer vision and OCR for accurate identification.
58
- You can explore source code and contribute to the project on [![GitHub Repo](https://img.shields.io/badge/GitHub-danhtran2mind%2FLicense--Plate--Detector--OCR-blue?style=flat&logo=github)](https://github.com/danhtran2mind/License-Plate-Detector-OCR).
59
-
60
- You can explore HuggingFace Model Hub on [![HuggingFace Model Hub](https://img.shields.io/badge/HuggingFace-danhtran2mind%2Flicense--plate--detector--ocr-yellow?style=flat&logo=huggingface)](https://huggingface.co/danhtran2mind/license-plate-detector-ocr)
61
- """,
62
- elem_classes="markdown-title"
63
- )
64
-
65
-
66
- with gr.Row():
67
- with gr.Column(scale=1):
68
- input_file = gr.File(label="Upload Image or Video", elem_classes="custom-file-input")
69
- input_type = gr.Radio(choices=["Image", "Video"], label="Input Type", value="Image", elem_classes="custom-radio")
70
- with gr.Blocks():
71
- input_preview_image = gr.Image(label="Input Preview", visible=True, elem_classes="custom-image")
72
- input_preview_video = gr.Video(label="Input Preview", visible=False, elem_classes="custom-video")
73
- with gr.Row():
74
- clear_button = gr.Button("Clear", variant="secondary", elem_classes="custom-button secondary")
75
- submit_button = gr.Button("Submit", variant="primary", elem_classes="custom-button primary")
76
- with gr.Column(scale=1):
77
- with gr.Blocks():
78
- output_image = gr.Image(label="Processed Output (Image)", type="numpy", visible=True, elem_classes="custom-image")
79
- output_video = gr.Video(label="Processed Output (Video)", visible=False, elem_classes="custom-video")
80
- output_text = gr.Textbox(label="Detected License Plates", lines=10, elem_classes="custom-textbox")
81
-
82
- # Update preview and output visibility when input type changes
83
- input_type.change(
84
- fn=update_visibility,
85
- inputs=input_type,
86
- outputs=[input_preview_image, input_preview_video, output_image, output_video]
87
- )
88
-
89
- # Update preview when file is uploaded
90
- input_file.change(
91
- fn=update_preview,
92
- inputs=[input_file, input_type],
93
- outputs=[input_preview_image, input_preview_video]
94
- )
95
-
96
- # Bind the processing function
97
- submit_button.click(
98
- fn=gradio_process,
99
- inputs=[input_file, input_type],
100
- outputs=[output_image, output_video, output_text, input_preview_image, input_preview_video]
101
- )
102
-
103
- # Clear button functionality
104
- clear_button.click(
105
- fn=lambda: (None, None, None, "Image", None, None, None, None),
106
- outputs=[input_file, output_image, output_video, input_type, input_preview_image, input_preview_video, output_image, output_video]
107
- ).then(
108
- fn=clear_preview_data,
109
- inputs=None,
110
- outputs=None
111
- )
112
-
113
- # Examples table
114
- with gr.Row():
115
- gr.Markdown("### Examples")
116
-
117
- with gr.Row():
118
- example_table = gr.Dataframe(
119
- value=[[i, ex["input_type"], os.path.basename(ex["input_file"])] for i, ex in enumerate(examples)],
120
- headers=["Index", "Type", "File"],
121
- datatype=["number", "str", "str"],
122
- interactive=True,
123
- elem_classes="custom-table"
124
- )
125
- with gr.Row():
126
- gr.Markdown("""
127
- This project utilizes:
128
-
129
- - **Detection task**: YOLOv12 architecture model (YOLO12n) from [![GitHub Repo](https://img.shields.io/badge/GitHub-sunsmarterjie%2Fyolov12-blue?style=flat&logo=github)](https://github.com/sunsmarterjie/yolov12) and documentation at [![Ultralytics YOLO12](https://img.shields.io/badge/Ultralytics-YOLO12-purple?style=flat)](https://docs.ultralytics.com/models/yolo12/), powered by the Ultralytics platform: [![Ultralytics Inc.](https://img.shields.io/badge/Ultralytics-Inc.-purple?style=flat)](https://docs.ultralytics.com).
130
-
131
- - **OCR task**: PaddleOCR v2.9 from [![GitHub Repo](https://img.shields.io/badge/GitHub-PaddlePaddle%2FPaddleOCR%2Frelease%2F2.9-blue?style=flat&logo=github)](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.9), with the main repository at [![GitHub Repo](https://img.shields.io/badge/GitHub-PaddlePaddle%2FPaddleOCR-blue?style=flat&logo=github)](https://github.com/PaddlePaddle/PaddleOCR) for OCR inference. Explore more about PaddleOCR at [![PaddleOCR Website](https://img.shields.io/badge/PaddleOCR-Website-purple?style=flat)](https://www.paddleocr.ai/main/en/index.html).
132
- """)
133
- # Example table click handler
134
- example_table.select(
135
- fn=load_example,
136
- inputs=None,
137
- outputs=[input_file, input_type, input_preview_image, input_preview_video, output_image, output_video, output_text]
138
- )
139
-
140
- if __name__ == "__main__":
141
  iface.launch()
 
1
+ import gradio as gr
2
+ import os
3
+ from gradio_app.config import setup_logging, setup_sys_path
4
+ from gradio_app.processor import gradio_process, update_preview, update_visibility, clear_preview_data
5
+
6
+ # Initialize logging and sys.path
7
+ setup_logging()
8
+ setup_sys_path()
9
+
10
+ # Load custom CSS
11
+ custom_css = open(os.path.join(os.path.dirname(__file__), "gradio_app", "static", "styles.css"), "r").read()
12
+
13
+ # Define example files
14
+ examples = [
15
+ {
16
+ "input_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "1", "lp_image.jpg"),
17
+ "output_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "1", "lp_image_output.jpg"),
18
+ "input_type": "Image"
19
+ },
20
+ {
21
+ "input_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "2", "lp_video.mp4"),
22
+ "output_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "2", "lp_video_output.mp4"),
23
+ "input_type": "Video"
24
+ }
25
+ ]
26
+
27
+ # Function to handle example selection
28
+ def load_example(evt: gr.SelectData):
29
+ index = evt.index[0] if evt.index else 0
30
+ example = examples[index]
31
+ input_file = example["input_file"]
32
+ output_file = example["output_file"]
33
+ input_type = example["input_type"]
34
+
35
+ # Update visibility based on input type
36
+ input_preview_image, input_preview_video, output_image, output_video = update_visibility(input_type)
37
+
38
+ # Update preview based on input file and type
39
+ input_preview_image, input_preview_video = update_preview(input_file, input_type)
40
+
41
+ return (
42
+ input_file,
43
+ input_type,
44
+ input_preview_image,
45
+ input_preview_video,
46
+ output_file if input_type == "Image" else None,
47
+ output_file if input_type == "Video" else None,
48
+ "Example loaded - click Submit to process"
49
+ )
50
+
51
+ # Gradio Interface
52
+ with gr.Blocks(css=custom_css) as iface:
53
+ gr.Markdown(
54
+ """
55
+ # License Plate Detection and OCR
56
+ Detect license plates from images or videos and read their text using
57
+ advanced computer vision and OCR for accurate identification.
58
+ You can explore source code and contribute to the project on [![GitHub Repo](https://img.shields.io/badge/GitHub-danhtran2mind%2FLicense--Plate--Detector--OCR-blue?style=flat&logo=github)](https://github.com/danhtran2mind/License-Plate-Detector-OCR).
59
+
60
+ You can explore HuggingFace Model Hub on [![HuggingFace Model Hub](https://img.shields.io/badge/HuggingFace-danhtran2mind%2Flicense--plate--detector--ocr-yellow?style=flat&logo=huggingface)](https://huggingface.co/danhtran2mind/license-plate-detector-ocr)
61
+ """,
62
+ elem_classes="markdown-title"
63
+ )
64
+
65
+
66
+ with gr.Row():
67
+ with gr.Column(scale=1):
68
+ input_file = gr.File(label="Upload Image or Video", elem_classes="custom-file-input")
69
+ input_type = gr.Radio(choices=["Image", "Video"], label="Input Type", value="Image", elem_classes="custom-radio")
70
+ with gr.Blocks():
71
+ input_preview_image = gr.Image(label="Input Preview", visible=True, elem_classes="custom-image")
72
+ input_preview_video = gr.Video(label="Input Preview", visible=False, elem_classes="custom-video")
73
+ with gr.Row():
74
+ clear_button = gr.Button("Clear", variant="secondary", elem_classes="custom-button secondary")
75
+ submit_button = gr.Button("Submit", variant="primary", elem_classes="custom-button primary")
76
+ with gr.Column(scale=1):
77
+ with gr.Blocks():
78
+ output_image = gr.Image(label="Processed Output (Image)", type="numpy", visible=True, elem_classes="custom-image")
79
+ output_video = gr.Video(label="Processed Output (Video)", visible=False, elem_classes="custom-video")
80
+ output_text = gr.Textbox(label="Detected License Plates", lines=10, elem_classes="custom-textbox")
81
+
82
+ # Update preview and output visibility when input type changes
83
+ input_type.change(
84
+ fn=update_visibility,
85
+ inputs=input_type,
86
+ outputs=[input_preview_image, input_preview_video, output_image, output_video]
87
+ )
88
+
89
+ # Update preview when file is uploaded
90
+ input_file.change(
91
+ fn=update_preview,
92
+ inputs=[input_file, input_type],
93
+ outputs=[input_preview_image, input_preview_video]
94
+ )
95
+
96
+ # Bind the processing function
97
+ submit_button.click(
98
+ fn=gradio_process,
99
+ inputs=[input_file, input_type],
100
+ outputs=[output_image, output_video, output_text, input_preview_image, input_preview_video]
101
+ )
102
+
103
+ # Clear button functionality
104
+ clear_button.click(
105
+ fn=lambda: (None, None, None, "Image", None, None, None, None),
106
+ outputs=[input_file, output_image, output_video, input_type, input_preview_image, input_preview_video, output_image, output_video]
107
+ ).then(
108
+ fn=clear_preview_data,
109
+ inputs=None,
110
+ outputs=None
111
+ )
112
+
113
+ # Examples table
114
+ with gr.Row():
115
+ gr.Markdown("### Examples")
116
+
117
+ with gr.Row():
118
+ example_table = gr.Dataframe(
119
+ value=[[i, ex["input_type"], os.path.basename(ex["input_file"])] for i, ex in enumerate(examples)],
120
+ headers=["Index", "Type", "File"],
121
+ datatype=["number", "str", "str"],
122
+ interactive=True,
123
+ elem_classes="custom-table"
124
+ )
125
+ with gr.Row():
126
+ gr.Markdown("""
127
+ This project utilizes:
128
+
129
+ - **Detection task**: YOLOv12 architecture model (YOLO12n) from [![GitHub Repo](https://img.shields.io/badge/GitHub-sunsmarterjie%2Fyolov12-blue?style=flat&logo=github)](https://github.com/sunsmarterjie/yolov12) and documentation at [![Ultralytics YOLO12](https://img.shields.io/badge/Ultralytics-YOLO12-purple?style=flat)](https://docs.ultralytics.com/models/yolo12/), powered by the Ultralytics platform: [![Ultralytics Inc.](https://img.shields.io/badge/Ultralytics-Inc.-purple?style=flat)](https://docs.ultralytics.com).
130
+
131
+ - **OCR task**: PaddleOCR v2.9 from [![GitHub Repo](https://img.shields.io/badge/GitHub-PaddlePaddle%2FPaddleOCR%2Frelease%2F2.9-blue?style=flat&logo=github)](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.9), with the main repository at [![GitHub Repo](https://img.shields.io/badge/GitHub-PaddlePaddle%2FPaddleOCR-blue?style=flat&logo=github)](https://github.com/PaddlePaddle/PaddleOCR) for OCR inference. Explore more about PaddleOCR at [![PaddleOCR Website](https://img.shields.io/badge/PaddleOCR-Website-purple?style=flat)](https://www.paddleocr.ai/main/en/index.html).
132
+ """)
133
+ # Example table click handler
134
+ example_table.select(
135
+ fn=load_example,
136
+ inputs=None,
137
+ outputs=[input_file, input_type, input_preview_image, input_preview_video, output_image, output_video, output_text]
138
+ )
139
+
140
+ if __name__ == "__main__":
141
  iface.launch()
apps/gradio_app/assets/examples/license_plate_detector_ocr/1/lp_image_output.jpg CHANGED

Git LFS Details

  • SHA256: b149129d95eb3309aada290de578f91ba712645c29c86fcb67813bd4a8981dea
  • Pointer size: 131 Bytes
  • Size of remote file: 154 kB
apps/gradio_app/assets/examples/license_plate_detector_ocr/2/lp_video.gif ADDED

Git LFS Details

  • SHA256: 8e76c74b73da1cb4f1a0a282b10a9d4c1027dafcc12abde68c7e90d673d0da04
  • Pointer size: 132 Bytes
  • Size of remote file: 2.74 MB
apps/gradio_app/assets/examples/license_plate_detector_ocr/2/lp_video_output.gif ADDED

Git LFS Details

  • SHA256: 0d2a03334eea85c0973932c0c0b43dbcc401478637f1edb21c87be80baef578f
  • Pointer size: 132 Bytes
  • Size of remote file: 2.64 MB
apps/gradio_app/assets/examples/license_plate_detector_ocr/2/lp_video_output.mp4 CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:72dececeb4cc1ce1da5264211578c9331a3fb31d36bf21ac2f40471d70e2121d
3
- size 4984385
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:386eaac8240eaafb06fde82b4a049bfd687ae84b5f2fea73d570070ef67088e5
3
+ size 3284659
apps/gradio_app/old-processor.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import shutil
4
+ import traceback
5
+ import logging
6
+ import gradio as gr
7
+ from gradio_app.utils import convert_to_supported_format
8
+ # Adjust sys.path to include the src directory
9
+ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),
10
+ '..', '..', 'src', 'license_plate_detector_ocr')))
11
+ from infer import infer, is_image_file
12
+
13
+
14
+
15
+ def gradio_process(input_file, input_type):
16
+ """Process the input file (image or video) for license plate detection and OCR."""
17
+ try:
18
+ logging.debug(f"Input file path: {input_file.name}")
19
+ print(f"Input file path: {input_file.name}")
20
+
21
+ # Copy input file to temp_data directory to ensure stability
22
+ temp_input_dir = "apps/gradio_app/temp_data"
23
+ os.makedirs(temp_input_dir, exist_ok=True)
24
+ temp_input_path = os.path.join(temp_input_dir, os.path.basename(input_file.name))
25
+ shutil.copy(input_file.name, temp_input_path)
26
+ logging.debug(f"Copied input file to: {temp_input_path}")
27
+
28
+ # Verify input file exists
29
+ if not os.path.exists(temp_input_path):
30
+ error_msg = f"Error: Input file {temp_input_path} does not exist."
31
+ logging.error(error_msg)
32
+ return None, None, error_msg, None, None
33
+
34
+ # Set output path
35
+ output_dir = "apps/gradio_app/temp_data"
36
+ os.makedirs(output_dir, exist_ok=True)
37
+ output_filename = os.path.splitext(os.path.basename(temp_input_path))[0] + ('_output.jpg' if is_image_file(temp_input_path) else '_output.mp4')
38
+ output_path = os.path.join(output_dir, output_filename)
39
+ logging.debug(f"Output path: {output_path}")
40
+
41
+ # Call the infer function
42
+ result_array, plate_texts = infer(temp_input_path, output_path)
43
+
44
+ if result_array is None and is_image_file(temp_input_path):
45
+ error_msg = f"Error: Processing failed for {temp_input_path}. 'infer' returned None."
46
+ logging.error(error_msg)
47
+ return None, None, error_msg, None, None
48
+
49
+ # Validate output file for videos
50
+ if not is_image_file(temp_input_path):
51
+ if not os.path.exists(output_path):
52
+ error_msg = f"Error: Output video file {output_path} was not created."
53
+ logging.error(error_msg)
54
+ return None, None, error_msg, None, None
55
+ # Convert output video to supported format
56
+ converted_output_path = os.path.join(output_dir, f"converted_{os.path.basename(output_path)}")
57
+ converted_path = convert_to_supported_format(output_path, converted_output_path)
58
+ if converted_path is None:
59
+ error_msg = f"Error: Failed to convert output video {output_path} to supported format."
60
+ logging.error(error_msg)
61
+ return None, None, error_msg, None, None
62
+ output_path = converted_path
63
+
64
+ # Format plate texts
65
+ if is_image_file(temp_input_path):
66
+ formatted_texts = "\n".join(plate_texts) if plate_texts else "No plates detected"
67
+ logging.debug(f"Image processed successfully. Plate texts: {formatted_texts}")
68
+ return result_array, None, formatted_texts, temp_input_path, None
69
+ else:
70
+ formatted_texts = []
71
+ for i, texts in enumerate(plate_texts):
72
+ if texts:
73
+ formatted_texts.append(f"Frame {i+1}: {', '.join(texts)}")
74
+ formatted_texts = "\n".join(formatted_texts) if formatted_texts else "No plates detected"
75
+ logging.debug(f"Video processed successfully. Plate texts: {formatted_texts}")
76
+ return None, output_path, formatted_texts, None, temp_input_path
77
+ except Exception as e:
78
+ error_message = f"Error processing {input_file.name}: {str(e)}\n{traceback.format_exc()}"
79
+ logging.error(error_message)
80
+ print(error_message)
81
+ return None, None, error_message, None, None
82
+
83
+ def update_preview(file, input_type):
84
+ """Return file path for the appropriate preview component based on input type."""
85
+ if not file:
86
+ logging.debug("No file provided for preview.")
87
+ return None, None
88
+ logging.debug(f"Updating preview for {input_type}: {file.name}")
89
+ # Verify file exists
90
+ if not os.path.exists(file.name):
91
+ logging.error(f"Input file {file.name} does not exist.")
92
+ return None, None
93
+ # Check if video format is supported
94
+ if input_type == "Video" and not file.name.lower().endswith(('.mp4', '.webm')):
95
+ logging.error(f"Unsupported video format for {file.name}. Use MP4 or WebM.")
96
+ return None, None
97
+ return file.name if input_type == "Image" else None, file.name if input_type == "Video" else None
98
+
99
+ def update_visibility(input_type):
100
+ """Update visibility of input/output components based on input type."""
101
+ logging.debug(f"Updating visibility for input type: {input_type}")
102
+ is_image = input_type == "Image"
103
+ is_video = input_type == "Video"
104
+ return (
105
+ gr.update(visible=is_image),
106
+ gr.update(visible=is_video),
107
+ gr.update(visible=is_image),
108
+ gr.update(visible=is_video)
109
+ )
apps/old-gradio_app.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import sys
4
+
5
+ # Adjust sys.path to include the src directory
6
+ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src', 'license_plate_detector_ocr')))
7
+ from infer import infer, is_image_file
8
+
9
+ def gradio_process(input_file, input_type):
10
+ """Process the input file (image or video) for license plate detection and OCR."""
11
+ # Debugging: Print input file path
12
+ print(f"Input file path: {input_file.name}")
13
+
14
+ # Set default output path in apps/gradio_app/temp_data/
15
+ output_dir = "apps/gradio_app/temp_data"
16
+ os.makedirs(output_dir, exist_ok=True)
17
+ output_filename = os.path.splitext(os.path.basename(input_file.name))[0] + ('_output.jpg' if is_image_file(input_file.name) else '_output.mp4')
18
+ output_path = os.path.join(output_dir, output_filename)
19
+
20
+ # Call the infer function from infer.py
21
+ result_array, plate_texts = infer(input_file.name, output_path)
22
+
23
+ if result_array is None:
24
+ return None, f"Error: Processing failed for {input_file.name}"
25
+
26
+ # Format plate texts for output
27
+ if is_image_file(input_file.name):
28
+ formatted_texts = "\n".join(plate_texts) if plate_texts else "No plates detected"
29
+ return result_array, formatted_texts
30
+ else:
31
+ # For videos, plate_texts is a list of lists (per frame)
32
+ formatted_texts = []
33
+ for i, texts in enumerate(plate_texts):
34
+ if texts:
35
+ formatted_texts.append(f"Frame {i+1}: {', '.join(texts)}")
36
+ formatted_texts = "\n".join(formatted_texts) if formatted_texts else "No plates detected"
37
+ return output_path, formatted_texts
38
+
39
+ # Gradio Interface
40
+ iface = gr.Interface(
41
+ fn=gradio_process,
42
+ inputs=[
43
+ gr.File(label="Upload Image or Video"),
44
+ gr.Radio(choices=["Image", "Video"], label="Input Type", value="Image")
45
+ ],
46
+ outputs=[
47
+ gr.Image(label="Processed Output", type="numpy"),
48
+ gr.Textbox(label="Detected License Plates")
49
+ ],
50
+ title="License Plate Detection and OCR",
51
+ description="Upload an image or video to detect and read license plates. Outputs are saved in apps/gradio_app/temp_data/."
52
+ )
53
+
54
+ if __name__ == "__main__":
55
+ iface.launch(share=True)
apps/old2-gradio_app.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import sys
4
+ import traceback
5
+ import logging
6
+ import shutil
7
+ import ffmpeg
8
+
9
+ # Set up logging to a file for debugging
10
+ logging.basicConfig(
11
+ filename="apps/gradio_app/debug.log",
12
+ level=logging.DEBUG,
13
+ format="%(asctime)s - %(levelname)s - %(message)s"
14
+ )
15
+
16
+ # Adjust sys.path to include the src directory
17
+ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src', 'license_plate_detector_ocr')))
18
+ from infer import infer, is_image_file
19
+
20
+ def convert_to_supported_format(input_path, output_path):
21
+ """Convert video to a browser-compatible format (MP4 with H.264 codec)."""
22
+ try:
23
+ stream = ffmpeg.input(input_path)
24
+ stream = ffmpeg.output(stream, output_path, vcodec='h264', acodec='aac', format='mp4', loglevel='quiet')
25
+ ffmpeg.run(stream)
26
+ logging.debug(f"Converted video to {output_path}")
27
+ return output_path
28
+ except Exception as e:
29
+ logging.error(f"Error converting video {input_path}: {str(e)}")
30
+ return None
31
+
32
+ def gradio_process(input_file, input_type):
33
+ """Process the input file (image or video) for license plate detection and OCR."""
34
+ try:
35
+ logging.debug(f"Input file path: {input_file.name}")
36
+ print(f"Input file path: {input_file.name}")
37
+
38
+ # Copy input file to temp_data directory to ensure stability
39
+ temp_input_dir = "apps/gradio_app/temp_data"
40
+ os.makedirs(temp_input_dir, exist_ok=True)
41
+ temp_input_path = os.path.join(temp_input_dir, os.path.basename(input_file.name))
42
+ shutil.copy(input_file.name, temp_input_path)
43
+ logging.debug(f"Copied input file to: {temp_input_path}")
44
+
45
+ # Verify input file exists
46
+ if not os.path.exists(temp_input_path):
47
+ error_msg = f"Error: Input file {temp_input_path} does not exist."
48
+ logging.error(error_msg)
49
+ return None, None, error_msg, None, None
50
+
51
+ # Set output path
52
+ output_dir = "apps/gradio_app/temp_data"
53
+ os.makedirs(output_dir, exist_ok=True)
54
+ output_filename = os.path.splitext(os.path.basename(temp_input_path))[0] + ('_output.jpg' if is_image_file(temp_input_path) else '_output.mp4')
55
+ output_path = os.path.join(output_dir, output_filename)
56
+ logging.debug(f"Output path: {output_path}")
57
+
58
+ # Call the infer function
59
+ result_array, plate_texts = infer(temp_input_path, output_path)
60
+
61
+ if result_array is None and is_image_file(temp_input_path):
62
+ error_msg = f"Error: Processing failed for {temp_input_path}. 'infer' returned None."
63
+ logging.error(error_msg)
64
+ return None, None, error_msg, None, None
65
+
66
+ # Validate output file for videos
67
+ if not is_image_file(temp_input_path):
68
+ if not os.path.exists(output_path):
69
+ error_msg = f"Error: Output video file {output_path} was not created."
70
+ logging.error(error_msg)
71
+ return None, None, error_msg, None, None
72
+ # Convert output video to supported format
73
+ converted_output_path = os.path.join(output_dir, f"converted_{os.path.basename(output_path)}")
74
+ converted_path = convert_to_supported_format(output_path, converted_output_path)
75
+ if converted_path is None:
76
+ error_msg = f"Error: Failed to convert output video {output_path} to supported format."
77
+ logging.error(error_msg)
78
+ return None, None, error_msg, None, None
79
+ output_path = converted_path
80
+
81
+ # Format plate texts
82
+ if is_image_file(temp_input_path):
83
+ formatted_texts = "\n".join(plate_texts) if plate_texts else "No plates detected"
84
+ logging.debug(f"Image processed successfully. Plate texts: {formatted_texts}")
85
+ return result_array, None, formatted_texts, temp_input_path, None
86
+ else:
87
+ formatted_texts = []
88
+ for i, texts in enumerate(plate_texts):
89
+ if texts:
90
+ formatted_texts.append(f"Frame {i+1}: {', '.join(texts)}")
91
+ formatted_texts = "\n".join(formatted_texts) if formatted_texts else "No plates detected"
92
+ logging.debug(f"Video processed successfully. Plate texts: {formatted_texts}")
93
+ return None, output_path, formatted_texts, None, temp_input_path
94
+ except Exception as e:
95
+ error_message = f"Error processing {input_file.name}: {str(e)}\n{traceback.format_exc()}"
96
+ logging.error(error_message)
97
+ print(error_message)
98
+ return None, None, error_message, None, None
99
+
100
+ def update_preview(file, input_type):
101
+ """Return file path for the appropriate preview component based on input type."""
102
+ if not file:
103
+ logging.debug("No file provided for preview.")
104
+ return None, None
105
+ logging.debug(f"Updating preview for {input_type}: {file.name}")
106
+ # Verify file exists
107
+ if not os.path.exists(file.name):
108
+ logging.error(f"Input file {file.name} does not exist.")
109
+ return None, None
110
+ # Check if video format is supported
111
+ if input_type == "Video" and not file.name.lower().endswith(('.mp4', '.webm')):
112
+ logging.error(f"Unsupported video format for {file.name}. Use MP4 or WebM.")
113
+ return None, None
114
+ return file.name if input_type == "Image" else None, file.name if input_type == "Video" else None
115
+
116
+ def update_visibility(input_type):
117
+ """Update visibility of input/output components based on input type."""
118
+ logging.debug(f"Updating visibility for input type: {input_type}")
119
+ is_image = input_type == "Image"
120
+ is_video = input_type == "Video"
121
+ return (
122
+ gr.update(visible=is_image),
123
+ gr.update(visible=is_video),
124
+ gr.update(visible=is_image),
125
+ gr.update(visible=is_video)
126
+ )
127
+
128
+ # Gradio Interface
129
+ with gr.Blocks() as iface:
130
+ gr.Markdown(
131
+ """
132
+ # License Plate Detection and OCR
133
+ Upload an image or video to detect and read license plates. Outputs are saved in `apps/gradio_app/temp_data/`.
134
+ Debug logs are saved in `apps/gradio_app/debug.log`.
135
+ """,
136
+ elem_classes="markdown-title"
137
+ )
138
+
139
+ with gr.Row():
140
+ with gr.Column(scale=1):
141
+ input_file = gr.File(label="Upload Image or Video")
142
+ input_type = gr.Radio(choices=["Image", "Video"], label="Input Type", value="Image")
143
+ with gr.Blocks():
144
+ input_preview_image = gr.Image(label="Input Preview", visible=True)
145
+ input_preview_video = gr.Video(label="Input Preview", visible=False)
146
+ with gr.Row():
147
+ clear_button = gr.Button("Clear", variant="secondary")
148
+ submit_button = gr.Button("Submit", variant="primary")
149
+ with gr.Column(scale=2):
150
+ with gr.Blocks():
151
+ output_image = gr.Image(label="Processed Output (Image)", type="numpy", visible=True)
152
+ output_video = gr.Video(label="Processed Output (Video)", visible=False)
153
+ output_text = gr.Textbox(label="Detected License Plates", lines=10)
154
+
155
+ # Update preview and output visibility when input type changes
156
+ input_type.change(
157
+ fn=update_visibility,
158
+ inputs=input_type,
159
+ outputs=[input_preview_image, input_preview_video, output_image, output_video]
160
+ )
161
+
162
+ # Update preview when file is uploaded
163
+ input_file.change(
164
+ fn=update_preview,
165
+ inputs=[input_file, input_type],
166
+ outputs=[input_preview_image, input_preview_video]
167
+ )
168
+
169
+ # Bind the processing function
170
+ submit_button.click(
171
+ fn=gradio_process,
172
+ inputs=[input_file, input_type],
173
+ outputs=[output_image, output_video, output_text, input_preview_image, input_preview_video]
174
+ )
175
+
176
+ # Clear button functionality
177
+ clear_button.click(
178
+ fn=lambda: (None, None, None, "Image", None, None, None, None),
179
+ outputs=[input_file, output_image, output_video, input_type, input_preview_image, input_preview_video, output_image, output_video]
180
+ )
181
+
182
+ if __name__ == "__main__":
183
+ iface.launch(share=True)
apps/old3-gradio_app.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ from gradio_app.config import setup_logging, setup_sys_path
4
+ from gradio_app.processor import gradio_process, update_preview, update_visibility
5
+
6
+ # Initialize logging and sys.path
7
+ setup_logging()
8
+ setup_sys_path()
9
+
10
+ # Load custom CSS
11
+ custom_css = open(os.path.join(os.path.dirname(__file__), "gradio_app", "static", "styles.css"), "r").read()
12
+
13
+ # Gradio Interface
14
+ with gr.Blocks(css=custom_css) as iface:
15
+ gr.Markdown(
16
+ """
17
+ # License Plate Detection and OCR
18
+ Detect license plates from images or videos and read their text using
19
+ advanced computer vision and OCR for accurate identification.
20
+ """,
21
+ elem_classes="markdown-title"
22
+ )
23
+
24
+ with gr.Row():
25
+ with gr.Column(scale=1):
26
+ input_file = gr.File(label="Upload Image or Video", elem_classes="custom-file-input")
27
+ input_type = gr.Radio(choices=["Image", "Video"], label="Input Type", value="Image", elem_classes="custom-radio")
28
+ with gr.Blocks():
29
+ input_preview_image = gr.Image(label="Input Preview", visible=True, elem_classes="custom-image")
30
+ input_preview_video = gr.Video(label="Input Preview", visible=False, elem_classes="custom-video")
31
+ with gr.Row():
32
+ clear_button = gr.Button("Clear", variant="secondary", elem_classes="custom-button secondary")
33
+ submit_button = gr.Button("Submit", variant="primary", elem_classes="custom-button primary")
34
+ with gr.Column(scale=2):
35
+ with gr.Blocks():
36
+ output_image = gr.Image(label="Processed Output (Image)", type="numpy", visible=True, elem_classes="custom-image")
37
+ output_video = gr.Video(label="Processed Output (Video)", visible=False, elem_classes="custom-video")
38
+ output_text = gr.Textbox(label="Detected License Plates", lines=10, elem_classes="custom-textbox")
39
+
40
+ # Update preview and output visibility when input type changes
41
+ input_type.change(
42
+ fn=update_visibility,
43
+ inputs=input_type,
44
+ outputs=[input_preview_image, input_preview_video, output_image, output_video]
45
+ )
46
+
47
+ # Update preview when file is uploaded
48
+ input_file.change(
49
+ fn=update_preview,
50
+ inputs=[input_file, input_type],
51
+ outputs=[input_preview_image, input_preview_video]
52
+ )
53
+
54
+ # Bind the processing function
55
+ submit_button.click(
56
+ fn=gradio_process,
57
+ inputs=[input_file, input_type],
58
+ outputs=[output_image, output_video, output_text, input_preview_image, input_preview_video]
59
+ )
60
+
61
+ # Clear button functionality
62
+ clear_button.click(
63
+ fn=lambda: (None, None, None, "Image", None, None, None, None),
64
+ outputs=[input_file, output_image, output_video, input_type, input_preview_image, input_preview_video, output_image, output_video]
65
+ )
66
+
67
+ if __name__ == "__main__":
68
+ iface.launch(share=True)
assets/examples/license_plate_detector_ocr/1/lp_image_output.jpg CHANGED

Git LFS Details

  • SHA256: b149129d95eb3309aada290de578f91ba712645c29c86fcb67813bd4a8981dea
  • Pointer size: 131 Bytes
  • Size of remote file: 154 kB
assets/examples/license_plate_detector_ocr/2/lp_video.gif ADDED

Git LFS Details

  • SHA256: 8e76c74b73da1cb4f1a0a282b10a9d4c1027dafcc12abde68c7e90d673d0da04
  • Pointer size: 132 Bytes
  • Size of remote file: 2.74 MB
assets/examples/license_plate_detector_ocr/2/lp_video_output.gif ADDED

Git LFS Details

  • SHA256: 0d2a03334eea85c0973932c0c0b43dbcc401478637f1edb21c87be80baef578f
  • Pointer size: 132 Bytes
  • Size of remote file: 2.64 MB
assets/examples/license_plate_detector_ocr/2/lp_video_output.mp4 CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:72dececeb4cc1ce1da5264211578c9331a3fb31d36bf21ac2f40471d70e2121d
3
- size 4984385
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:386eaac8240eaafb06fde82b4a049bfd687ae84b5f2fea73d570070ef67088e5
3
+ size 3284659