Abs6187 commited on
Commit
a516b42
·
verified ·
1 Parent(s): a1ab077

Create ui.py

Browse files
Files changed (1) hide show
  1. ui.py +293 -0
ui.py ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from detector import (
3
+ yolov8_detect,
4
+ download_sample_images,
5
+ get_ocr_status,
6
+ ADVANCED_OCR_AVAILABLE,
7
+ OCR_AVAILABLE
8
+ )
9
+
10
+ try:
11
+ from advanced_ocr import get_available_models
12
+ except ImportError:
13
+ def get_available_models():
14
+ return {}
15
+
16
+ class UIComponents:
17
+ def __init__(self):
18
+ download_sample_images()
19
+ self.ocr_status = get_ocr_status()
20
+ self.custom_css = """
21
+ .gradio-container {
22
+ max-width: 1200px !important;
23
+ margin: 0 auto;
24
+ }
25
+ .main-header {
26
+ text-align: center;
27
+ margin-bottom: 2rem;
28
+ padding: 1rem;
29
+ }
30
+ .main-title {
31
+ font-size: 2rem;
32
+ font-weight: 600;
33
+ color: #333;
34
+ margin: 0;
35
+ }
36
+ .subtitle {
37
+ color: #666;
38
+ font-size: 1rem;
39
+ margin: 0.5rem 0;
40
+ }
41
+ .status-info {
42
+ font-size: 0.9rem;
43
+ color: #888;
44
+ margin: 0.5rem 0;
45
+ }
46
+ .section-gap {
47
+ margin: 1.5rem 0;
48
+ }
49
+ """
50
+
51
+ def toggle_sections(self, extract_text_checked, crop_checked):
52
+ show_gallery = bool(extract_text_checked and crop_checked)
53
+ show_ocr = bool(extract_text_checked)
54
+ return (
55
+ gr.update(visible=show_gallery),
56
+ gr.update(visible=show_ocr),
57
+ )
58
+
59
+ def get_ocr_status_text(self):
60
+ if ADVANCED_OCR_AVAILABLE:
61
+ return "Advanced OCR Available"
62
+ elif OCR_AVAILABLE:
63
+ return "Basic OCR Available"
64
+ else:
65
+ return "OCR Not Available"
66
+
67
+ def create_header(self):
68
+ return gr.HTML(f"""
69
+ <div class="main-header">
70
+ <h1 class="main-title">AI Helmet Detection System</h1>
71
+ <p class="subtitle">Motorcyclist safety monitoring with license plate recognition</p>
72
+ <p class="status-info">YOLOv11 • {self.get_ocr_status_text()} • Real-time Processing</p>
73
+ </div>
74
+ """)
75
+
76
+ def create_settings_panel(self):
77
+ components = {}
78
+
79
+ with gr.Column(scale=1):
80
+ gr.Markdown("### Settings")
81
+
82
+ components['input_image'] = gr.Image(
83
+ type="filepath",
84
+ label="Upload Image",
85
+ sources=["upload", "webcam"]
86
+ )
87
+
88
+ with gr.Row():
89
+ components['image_size'] = gr.Slider(
90
+ minimum=320, maximum=1280, value=640, step=32,
91
+ label="Image Size"
92
+ )
93
+
94
+ with gr.Row():
95
+ components['conf_threshold'] = gr.Slider(
96
+ minimum=0.0, maximum=1.0, value=0.4, step=0.05,
97
+ label="Confidence"
98
+ )
99
+ components['iou_threshold'] = gr.Slider(
100
+ minimum=0.0, maximum=1.0, value=0.5, step=0.05,
101
+ label="IoU Threshold"
102
+ )
103
+
104
+ components['show_stats'] = gr.Checkbox(
105
+ value=True,
106
+ label="Show Statistics"
107
+ )
108
+ components['crop_plates'] = gr.Checkbox(
109
+ value=True,
110
+ label="Extract License Plates"
111
+ )
112
+
113
+ if self.ocr_status["any_available"]:
114
+ components['extract_text'] = gr.Checkbox(
115
+ value=False,
116
+ label="Enable OCR"
117
+ )
118
+ components['ocr_on_no_helmet'] = gr.Checkbox(
119
+ value=True,
120
+ label="Auto-OCR for No Helmet"
121
+ )
122
+
123
+ if ADVANCED_OCR_AVAILABLE:
124
+ models = get_available_models()
125
+ model_choices = [("Auto (Recommended)", "auto"), ("Basic EasyOCR", "basic")]
126
+ for key, info in models.items():
127
+ model_choices.append((info['name'], key))
128
+ components['selected_ocr_model'] = gr.Dropdown(
129
+ choices=model_choices,
130
+ value="auto",
131
+ label="OCR Model"
132
+ )
133
+ else:
134
+ components['selected_ocr_model'] = gr.State("basic")
135
+
136
+ gr.Markdown("*Note: OCR processing may increase detection time.*")
137
+ else:
138
+ components['extract_text'] = gr.Checkbox(
139
+ value=False,
140
+ label="OCR Not Available",
141
+ interactive=False
142
+ )
143
+ components['ocr_on_no_helmet'] = gr.Checkbox(
144
+ value=False,
145
+ label="Auto-OCR (Not Available)",
146
+ interactive=False
147
+ )
148
+ components['selected_ocr_model'] = gr.State("basic")
149
+
150
+ with gr.Row():
151
+ components['submit_btn'] = gr.Button("Start Detection", variant="primary")
152
+ components['clear_btn'] = gr.Button("Clear")
153
+
154
+ return components
155
+
156
+ def create_results_panel(self):
157
+ components = {}
158
+
159
+ with gr.Column(scale=2):
160
+ gr.Markdown("### Results")
161
+
162
+ components['output_image'] = gr.Image(
163
+ type="pil",
164
+ label="Detection Results"
165
+ )
166
+
167
+ with gr.Row():
168
+ components['output_table'] = gr.Dataframe(
169
+ headers=["Object", "Confidence", "Position", "Dimensions"],
170
+ label="Detection Details",
171
+ interactive=False
172
+ )
173
+ components['output_stats'] = gr.Textbox(
174
+ label="Statistics",
175
+ interactive=False,
176
+ lines=6
177
+ )
178
+
179
+ components['license_gallery'] = gr.Gallery(
180
+ label="License Plates",
181
+ columns=3,
182
+ visible=False
183
+ )
184
+
185
+ components['ocr_group'] = gr.Group(visible=False)
186
+ with components['ocr_group']:
187
+ components['plate_text_output'] = gr.Textbox(
188
+ label="OCR Results",
189
+ lines=4,
190
+ interactive=False
191
+ )
192
+
193
+ components['download_file'] = gr.File(
194
+ label="Download Results (ZIP)",
195
+ interactive=False
196
+ )
197
+
198
+ return components
199
+
200
+ def create_examples_tab(self, input_image, output_components):
201
+ with gr.TabItem("Examples"):
202
+ gr.Markdown("### Sample Images")
203
+ gr.Markdown("Click any example to test the detection system:")
204
+
205
+ gr.Examples(
206
+ examples=[
207
+ ["sample_1.jpg"],
208
+ ["sample_2.jpg"],
209
+ ["sample_3.jpg"],
210
+ ["sample_4.jpg"],
211
+ ["sample_6.jpg"],
212
+ ["sample_7.jpg"],
213
+ ["sample_8.jpg"],
214
+ ],
215
+ inputs=input_image,
216
+ outputs=[
217
+ output_components['output_image'],
218
+ output_components['output_table'],
219
+ output_components['output_stats'],
220
+ output_components['license_gallery'],
221
+ output_components['download_file'],
222
+ output_components['plate_text_output'],
223
+ ],
224
+ fn=lambda img: yolov8_detect(
225
+ img, 640, 0.4, 0.5, True, True, True, False
226
+ ),
227
+ cache_examples=True
228
+ )
229
+
230
+ def create_info_tab(self):
231
+ with gr.TabItem("Info"):
232
+ gr.Markdown("### System Information")
233
+
234
+ gr.Markdown(f"""
235
+ **AI Model:** YOLOv11
236
+ **Classes:** Helmet, No Helmet, License Plate
237
+ **OCR Status:** {self.get_ocr_status_text()}
238
+ **Features:** Detection, extraction, text recognition
239
+
240
+ **Privacy:** All processing is local. No data stored.
241
+ **Usage:** For demonstration and research purposes only.
242
+ """)
243
+
244
+ def setup_event_handlers(self, settings_components, results_components):
245
+ settings_components['submit_btn'].click(
246
+ fn=yolov8_detect,
247
+ inputs=[
248
+ settings_components['input_image'],
249
+ settings_components['image_size'],
250
+ settings_components['conf_threshold'],
251
+ settings_components['iou_threshold'],
252
+ settings_components['show_stats'],
253
+ gr.State(True),
254
+ settings_components['crop_plates'],
255
+ settings_components['extract_text'],
256
+ settings_components['ocr_on_no_helmet'],
257
+ settings_components['selected_ocr_model'],
258
+ ],
259
+ outputs=[
260
+ results_components['output_image'],
261
+ results_components['output_table'],
262
+ results_components['output_stats'],
263
+ results_components['license_gallery'],
264
+ results_components['download_file'],
265
+ results_components['plate_text_output'],
266
+ ],
267
+ )
268
+
269
+ settings_components['clear_btn'].click(
270
+ fn=lambda: [None, None, None, None, None, None],
271
+ inputs=[],
272
+ outputs=[
273
+ settings_components['input_image'],
274
+ results_components['output_image'],
275
+ results_components['output_table'],
276
+ results_components['output_stats'],
277
+ results_components['license_gallery'],
278
+ results_components['download_file'],
279
+ results_components['plate_text_output'],
280
+ ],
281
+ )
282
+
283
+ settings_components['extract_text'].change(
284
+ fn=self.toggle_sections,
285
+ inputs=[settings_components['extract_text'], settings_components['crop_plates']],
286
+ outputs=[results_components['license_gallery'], results_components['ocr_group']],
287
+ )
288
+
289
+ settings_components['crop_plates'].change(
290
+ fn=self.toggle_sections,
291
+ inputs=[settings_components['extract_text'], settings_components['crop_plates']],
292
+ outputs=[results_components['license_gallery'], results_components['ocr_group']],
293
+ )