danhtran2mind commited on
Commit
bce32c7
·
verified ·
1 Parent(s): f154d1e

Create gradio_app.py

Browse files
Files changed (1) hide show
  1. apps/gradio_app.py +153 -0
apps/gradio_app.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 model directory and get available models
14
+ model_dir = os.path.join(os.path.dirname(__file__), "yolo", "finetune", "runs", "license_plate_detector", "weights")
15
+ model_files = [f for f in os.listdir(model_dir) if os.path.isfile(os.path.join(model_dir, f)) and f.endswith('.onnx')]
16
+ default_model = next((element for element in model_files if "best" in element), None)
17
+
18
+ # Define example files
19
+ examples = [
20
+ {
21
+ "input_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "1", "lp_image.jpg"),
22
+ "output_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "1", "lp_image_output.jpg"),
23
+ "input_type": "Image",
24
+ "model_path": os.path.join(model_dir, "best.pt") if os.path.exists(os.path.join(model_dir, "best.pt")) else None
25
+ },
26
+ {
27
+ "input_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "2", "lp_video.mp4"),
28
+ "output_file": os.path.join(os.path.dirname(__file__), "gradio_app", "assets", "examples", "license_plate_detector_ocr", "2", "lp_video_output.mp4"),
29
+ "input_type": "Video",
30
+ "model_path": os.path.join(model_dir, "best.pt") if os.path.exists(os.path.join(model_dir, "best.pt")) else None
31
+ }
32
+ ]
33
+
34
+ # Function to handle example selection
35
+ def load_example(evt: gr.SelectData):
36
+ index = evt.index[0] if evt.index else 0
37
+ example = examples[index]
38
+ input_file = example["input_file"]
39
+ output_file = example["output_file"]
40
+ input_type = example["input_type"]
41
+ model_path = example["model_path"]
42
+
43
+ # Update visibility based on input type
44
+ input_preview_image, input_preview_video, output_image, output_video = update_visibility(input_type)
45
+
46
+ # Update preview based on input file and type
47
+ input_preview_image, input_preview_video = update_preview(input_file, input_type)
48
+
49
+ return (
50
+ input_file,
51
+ input_type,
52
+ input_preview_image,
53
+ input_preview_video,
54
+ output_file if input_type == "Image" else None,
55
+ output_file if input_type == "Video" else None,
56
+ model_path,
57
+ "Example loaded - click Submit to process"
58
+ )
59
+
60
+ # Gradio Interface
61
+ with gr.Blocks(css=custom_css) as iface:
62
+ gr.Markdown(
63
+ """
64
+ # License Plate Detection and OCR
65
+ Detect license plates from images or videos and read their text using
66
+ advanced computer vision and OCR for accurate identification.
67
+ """,
68
+ elem_classes="markdown-title"
69
+ )
70
+ gr.HTML("""
71
+ You can explore the source code and contribute to the project on
72
+ <a href="https://github.com/danhtran2mind/License-Plate-Detector-OCR">danhtran2mind/License-Plate-Detector-OCR</a>.
73
+ You can explore the HuggingFace Model Hub on
74
+ <a href="https://huggingface.co/danhtran2mind/license-plate-detector-ocr">danhtran2mind/license-plate-detector-ocr</a>.
75
+ """)
76
+
77
+ with gr.Row():
78
+ with gr.Column(scale=1):
79
+ input_file = gr.File(label="Upload Image or Video", elem_classes="custom-file-input")
80
+ input_type = gr.Radio(choices=["Image", "Video"], label="Input Type", value="Image", elem_classes="custom-radio")
81
+ model_path = gr.Dropdown(choices=model_files, label="Select Model", value=default_model, elem_classes="custom-dropdown")
82
+ with gr.Blocks():
83
+ input_preview_image = gr.Image(label="Input Preview", visible=True, elem_classes="custom-image")
84
+ input_preview_video = gr.Video(label="Input Preview", visible=False, elem_classes="custom-video")
85
+ with gr.Row():
86
+ clear_button = gr.Button("Clear", variant="secondary", elem_classes="custom-button secondary")
87
+ submit_button = gr.Button("Submit", variant="primary", elem_classes="custom-button primary")
88
+ with gr.Column(scale=1):
89
+ with gr.Blocks():
90
+ output_image = gr.Image(label="Processed Output (Image)", type="numpy", visible=True, elem_classes="custom-image")
91
+ output_video = gr.Video(label="Processed Output (Video)", visible=False, elem_classes="custom-video")
92
+ output_text = gr.Textbox(label="Detected License Plates", lines=10, elem_classes="custom-textbox")
93
+
94
+ # Update preview and output visibility when input type changes
95
+ input_type.change(
96
+ fn=update_visibility,
97
+ inputs=input_type,
98
+ outputs=[input_preview_image, input_preview_video, output_image, output_video]
99
+ )
100
+
101
+ # Update preview when file is uploaded
102
+ input_file.change(
103
+ fn=update_preview,
104
+ inputs=[input_file, input_type],
105
+ outputs=[input_preview_image, input_preview_video]
106
+ )
107
+
108
+ # Bind the processing function
109
+ submit_button.click(
110
+ fn=gradio_process,
111
+ inputs=[model_path, input_file, input_type],
112
+ outputs=[output_image, output_video, output_text, input_preview_image, input_preview_video]
113
+ )
114
+
115
+ # Clear button functionality
116
+ clear_button.click(
117
+ fn=lambda: (None, None, None, "Image", None, None, None, default_model),
118
+ outputs=[input_file, output_image, output_video, input_type, input_preview_image, input_preview_video, output_text, model_path]
119
+ ).then(
120
+ fn=clear_preview_data,
121
+ inputs=None,
122
+ outputs=None
123
+ )
124
+
125
+ # Examples table
126
+ with gr.Row():
127
+ gr.Markdown("### Examples")
128
+
129
+ with gr.Row():
130
+ example_table = gr.Dataframe(
131
+ value=[[i, ex["input_type"], os.path.basename(ex["input_file"]), os.path.basename(ex["model_path"])] for i, ex in enumerate(examples)],
132
+ headers=["Index", "Type", "File", "Model"],
133
+ datatype=["number", "str", "str", "str"],
134
+ interactive=True,
135
+ elem_classes="custom-table"
136
+ )
137
+ with gr.Row():
138
+ gr.Markdown("""
139
+ This project utilizes:
140
+
141
+ - **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).
142
+
143
+ - **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).
144
+ """)
145
+ # Example table click handler
146
+ example_table.select(
147
+ fn=load_example,
148
+ inputs=None,
149
+ outputs=[input_file, input_type, input_preview_image, input_preview_video, output_image, output_video, model_path, output_text]
150
+ )
151
+
152
+ if __name__ == "__main__":
153
+ iface.launch()