muhammadhamza-stack commited on
Commit
9644ee8
·
1 Parent(s): c6c8bf8

refine the gradio app

Browse files
Files changed (6) hide show
  1. .gitattributes +1 -0
  2. .gitignore +1 -0
  3. app.py +202 -18
  4. licence.jpg +3 -0
  5. licence2.jpg +3 -0
  6. requirements.txt +4 -2
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.jpg filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ venv
app.py CHANGED
@@ -1,21 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import numpy as np
3
  from PIL import Image, ImageEnhance
4
  from ultralytics import YOLO
5
  import cv2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  # Load YOLO model
 
8
  model_path = "./best.pt"
9
- modelY = YOLO(model_path)
10
- modelY.to('cpu')
 
 
 
 
11
 
12
  # Preprocessing function
13
  def preprocessing(image):
14
  if image.mode != 'RGB':
15
  image = image.convert('RGB')
 
 
16
  image = ImageEnhance.Sharpness(image).enhance(2.0)
17
  image = ImageEnhance.Contrast(image).enhance(1.5)
18
  image = ImageEnhance.Brightness(image).enhance(0.8)
 
 
19
  width = 448
20
  aspect_ratio = image.height / image.width
21
  height = int(width * aspect_ratio)
@@ -23,53 +158,102 @@ def preprocessing(image):
23
 
24
  # YOLO document detection and cropping
25
  def detect_and_crop_document(image):
 
 
 
26
  image_np = np.array(image)
27
- results = modelY(image_np, conf=0.80, device='cpu')
 
 
28
  cropped_images = []
29
  predictions = []
30
 
31
  for result in results:
32
  for box in result.boxes:
33
  x1, y1, x2, y2 = map(int, box.xyxy[0])
34
- conf = int(box.conf[0] * 100) # Convert confidence to percentage
35
- cls = int(box.cls[0])
36
- class_name = modelY.names[cls].capitalize() # Capitalize class names
 
37
  cropped_image_np = image_np[y1:y2, x1:x2]
38
- cropped_image = Image.fromarray(cropped_image_np)
39
- cropped_images.append(cropped_image)
40
- predictions.append(f"Detected: STNK {class_name} -- (Confidence: {conf}%)")
 
 
 
41
 
42
- if not cropped_images:
43
- return None, "No document detected"
44
  return cropped_images, predictions
45
 
46
- # Gradio interface
47
  def process_image(image):
 
 
 
48
  preprocessed_image = preprocessing(image)
49
  cropped_images, predictions = detect_and_crop_document(preprocessed_image)
50
 
51
  if cropped_images:
52
  return cropped_images, '\n'.join(predictions)
53
- return None, "No document detected"
 
 
 
 
 
 
 
 
 
 
54
 
55
  with gr.Blocks(css=".gr-button {background-color: #4caf50; color: white; font-size: 16px; padding: 10px 20px; border-radius: 8px;}") as demo:
 
56
  gr.Markdown(
57
  """
58
- <h1 style="text-align: center; color: #4caf50;">📜 License Registration Classification</h1>
59
- <p style="text-align: center; font-size: 18px;">Upload an image and let the YOLO model detect and crop license documents automatically.</p>
60
  """
61
  )
 
 
 
 
 
 
 
 
 
 
 
 
62
  with gr.Row():
63
  with gr.Column(scale=1, min_width=300):
64
  input_image = gr.Image(type="pil", label="Upload License Image", interactive=True)
65
  with gr.Row():
66
  clear_btn = gr.Button("Clear")
67
  submit_btn = gr.Button("Detect Document")
 
68
  with gr.Column(scale=2):
69
- output_image = gr.Gallery(label="Cropped Documents", interactive=False)
70
- output_text = gr.Textbox(label="Detection Result", interactive=False)
71
 
72
  submit_btn.click(process_image, inputs=input_image, outputs=[output_image, output_text])
73
- clear_btn.click(lambda: (None, ""), outputs=[output_image, output_text])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
 
75
  demo.launch()
 
1
+ # import gradio as gr
2
+ # import numpy as np
3
+ # from PIL import Image, ImageEnhance
4
+ # from ultralytics import YOLO
5
+ # import cv2
6
+
7
+ # # Load YOLO model
8
+ # model_path = "./best.pt"
9
+ # modelY = YOLO(model_path)
10
+ # modelY.to('cpu')
11
+
12
+ # # Preprocessing function
13
+ # def preprocessing(image):
14
+ # if image.mode != 'RGB':
15
+ # image = image.convert('RGB')
16
+ # image = ImageEnhance.Sharpness(image).enhance(2.0)
17
+ # image = ImageEnhance.Contrast(image).enhance(1.5)
18
+ # image = ImageEnhance.Brightness(image).enhance(0.8)
19
+ # width = 448
20
+ # aspect_ratio = image.height / image.width
21
+ # height = int(width * aspect_ratio)
22
+ # return image.resize((width, height))
23
+
24
+ # # YOLO document detection and cropping
25
+ # def detect_and_crop_document(image):
26
+ # image_np = np.array(image)
27
+ # results = modelY(image_np, conf=0.80, device='cpu')
28
+ # cropped_images = []
29
+ # predictions = []
30
+
31
+ # for result in results:
32
+ # for box in result.boxes:
33
+ # x1, y1, x2, y2 = map(int, box.xyxy[0])
34
+ # conf = int(box.conf[0] * 100) # Convert confidence to percentage
35
+ # cls = int(box.cls[0])
36
+ # class_name = modelY.names[cls].capitalize() # Capitalize class names
37
+ # cropped_image_np = image_np[y1:y2, x1:x2]
38
+ # cropped_image = Image.fromarray(cropped_image_np)
39
+ # cropped_images.append(cropped_image)
40
+ # predictions.append(f"Detected: STNK {class_name} -- (Confidence: {conf}%)")
41
+
42
+ # if not cropped_images:
43
+ # return None, "No document detected"
44
+ # return cropped_images, predictions
45
+
46
+ # # Gradio interface
47
+ # def process_image(image):
48
+ # preprocessed_image = preprocessing(image)
49
+ # cropped_images, predictions = detect_and_crop_document(preprocessed_image)
50
+
51
+ # if cropped_images:
52
+ # return cropped_images, '\n'.join(predictions)
53
+ # return None, "No document detected"
54
+
55
+ # with gr.Blocks(css=".gr-button {background-color: #4caf50; color: white; font-size: 16px; padding: 10px 20px; border-radius: 8px;}") as demo:
56
+ # gr.Markdown(
57
+ # """
58
+ # <h1 style="text-align: center; color: #4caf50;">📜 License Registration Classification</h1>
59
+ # <p style="text-align: center; font-size: 18px;">Upload an image and let the YOLO model detect and crop license documents automatically.</p>
60
+ # """
61
+ # )
62
+ # with gr.Row():
63
+ # with gr.Column(scale=1, min_width=300):
64
+ # input_image = gr.Image(type="pil", label="Upload License Image", interactive=True)
65
+ # with gr.Row():
66
+ # clear_btn = gr.Button("Clear")
67
+ # submit_btn = gr.Button("Detect Document")
68
+ # with gr.Column(scale=2):
69
+ # output_image = gr.Gallery(label="Cropped Documents", interactive=False)
70
+ # output_text = gr.Textbox(label="Detection Result", interactive=False)
71
+
72
+ # submit_btn.click(process_image, inputs=input_image, outputs=[output_image, output_text])
73
+ # clear_btn.click(lambda: (None, ""), outputs=[output_image, output_text])
74
+
75
+ # demo.launch()
76
+
77
+
78
+
79
+
80
  import gradio as gr
81
  import numpy as np
82
  from PIL import Image, ImageEnhance
83
  from ultralytics import YOLO
84
  import cv2
85
+ import os
86
+
87
+ # --- DOCUMENTATION STRINGS (English Only) ---
88
+
89
+ GUIDELINE_SETUP = """
90
+ ## 1. Quick Start Guide: Setup and Run Instructions
91
+
92
+ This application uses a YOLO model to automatically detect, classify, and extract specific license registration documents (STNK).
93
+
94
+ 1. **Preparation:** Ensure your image clearly shows the target license document.
95
+ 2. **Upload:** Click the 'Upload License Image' box and select your image (JPG, PNG).
96
+ 3. **Run:** Click the **"Detect Document"** button.
97
+ 4. **Review:** The detected documents will appear in the 'Cropped Documents' gallery, and the 'Detection Result' box will show the classification and confidence score.
98
+ """
99
+
100
+ GUIDELINE_INPUT = """
101
+ ## 2. Expected Inputs and Preprocessing
102
+
103
+ | Input Field | Purpose | Requirement |
104
+ | :--- | :--- | :--- |
105
+ | **Upload License Image** | The image containing the license document you want to detect and classify. | Must be an image file (e.g., JPG, PNG). |
106
+
107
+ ### Automatic Preprocessing Steps:
108
+ Before detection, the input image is automatically adjusted to enhance accuracy:
109
+ 1. **Sharpness:** Increased sharpness by 2.0.
110
+ 2. **Contrast:** Increased contrast by 1.5.
111
+ 3. **Brightness:** Slightly reduced brightness by 0.8.
112
+ 4. **Resizing:** The image is resized to a width of 448 pixels while maintaining its original aspect ratio.
113
+ """
114
+
115
+ GUIDELINE_OUTPUT = """
116
+ ## 3. Expected Outputs (Detection and Classification)
117
+
118
+ The application produces two outputs based on a successful detection:
119
+
120
+ 1. **Cropped Documents (Gallery):**
121
+ * This gallery displays only the regions of the image where a license document was confidently detected (Confidence > 80%).
122
+ * If multiple documents are found, all cropped images will appear here.
123
+
124
+ 2. **Detection Result (Textbox):**
125
+ * A text summary listing each detected document, including its specific class name (e.g., 'STNK Class A'), and the model's confidence level (as a percentage).
126
+
127
+ ### Failure Modes:
128
+ * If "No document detected" is returned, it means the model did not find a document with a confidence level of 80% or higher, or the image quality was too poor for detection.
129
+ """
130
+
131
+ # --- CORE LOGIC ---
132
 
133
  # Load YOLO model
134
+ # NOTE: Ensure 'best.pt' is available in the execution directory.
135
  model_path = "./best.pt"
136
+ try:
137
+ modelY = YOLO(model_path)
138
+ modelY.to('cpu')
139
+ except Exception as e:
140
+ print(f"Error loading model: {e}")
141
+ modelY = None
142
 
143
  # Preprocessing function
144
  def preprocessing(image):
145
  if image.mode != 'RGB':
146
  image = image.convert('RGB')
147
+
148
+ # Enhancement steps
149
  image = ImageEnhance.Sharpness(image).enhance(2.0)
150
  image = ImageEnhance.Contrast(image).enhance(1.5)
151
  image = ImageEnhance.Brightness(image).enhance(0.8)
152
+
153
+ # Resizing while preserving aspect ratio
154
  width = 448
155
  aspect_ratio = image.height / image.width
156
  height = int(width * aspect_ratio)
 
158
 
159
  # YOLO document detection and cropping
160
  def detect_and_crop_document(image):
161
+ if modelY is None:
162
+ return [], ["Model not loaded."]
163
+
164
  image_np = np.array(image)
165
+ # Run inference with confidence threshold 0.80
166
+ results = modelY(image_np, conf=0.80, device='cpu', verbose=False)
167
+
168
  cropped_images = []
169
  predictions = []
170
 
171
  for result in results:
172
  for box in result.boxes:
173
  x1, y1, x2, y2 = map(int, box.xyxy[0])
174
+ conf = int(box.conf[0].item() * 100) # Ensure conversion to scalar for item()
175
+ cls = int(box.cls[0].item())
176
+ class_name = modelY.names.get(cls, "Unknown").capitalize()
177
+
178
  cropped_image_np = image_np[y1:y2, x1:x2]
179
+
180
+ # Check for valid crop size before converting to PIL
181
+ if cropped_image_np.size > 0:
182
+ cropped_image = Image.fromarray(cropped_image_np)
183
+ cropped_images.append(cropped_image)
184
+ predictions.append(f"Detected: STNK {class_name} -- (Confidence: {conf}%)")
185
 
 
 
186
  return cropped_images, predictions
187
 
188
+ # Gradio interface function
189
  def process_image(image):
190
+ if image is None:
191
+ raise gr.Error("Please upload an image.")
192
+
193
  preprocessed_image = preprocessing(image)
194
  cropped_images, predictions = detect_and_crop_document(preprocessed_image)
195
 
196
  if cropped_images:
197
  return cropped_images, '\n'.join(predictions)
198
+
199
+ # If no documents are detected with sufficient confidence
200
+ return [], "No document detected (Confidence threshold not met or image is unclear)."
201
+
202
+ # --- GRADIO UI SETUP ---
203
+
204
+ # Define example paths (NOTE: Replace with actual paths if needed)
205
+ examples = [
206
+ ["./licence2.jpg"],
207
+ ["./licence.jpg"],
208
+ ]
209
 
210
  with gr.Blocks(css=".gr-button {background-color: #4caf50; color: white; font-size: 16px; padding: 10px 20px; border-radius: 8px;}") as demo:
211
+
212
  gr.Markdown(
213
  """
214
+ <h1 style="color: #4caf50;">License Registration Classification</h1>
215
+ <p style="font-size: 18px;">Upload an image and let the YOLO model detect and crop license documents automatically.</p>
216
  """
217
  )
218
+
219
+ # 1. GUIDELINES SECTION
220
+ with gr.Accordion("User Guidelines and Documentation", open=False):
221
+ gr.Markdown(GUIDELINE_SETUP)
222
+ gr.Markdown("---")
223
+ gr.Markdown(GUIDELINE_INPUT)
224
+ gr.Markdown("---")
225
+ gr.Markdown(GUIDELINE_OUTPUT)
226
+
227
+ gr.Markdown("---")
228
+
229
+ # 2. APPLICATION INTERFACE
230
  with gr.Row():
231
  with gr.Column(scale=1, min_width=300):
232
  input_image = gr.Image(type="pil", label="Upload License Image", interactive=True)
233
  with gr.Row():
234
  clear_btn = gr.Button("Clear")
235
  submit_btn = gr.Button("Detect Document")
236
+
237
  with gr.Column(scale=2):
238
+ output_image = gr.Gallery(label="Cropped Documents", interactive=False, object_fit="contain")
239
+ output_text = gr.Textbox(label="Detection Result", interactive=False, lines=5)
240
 
241
  submit_btn.click(process_image, inputs=input_image, outputs=[output_image, output_text])
242
+ clear_btn.click(lambda: (None, ""), outputs=[output_image, output_text, input_image], show_progress=False)
243
+
244
+ gr.Markdown("---")
245
+
246
+ # 3. EXAMPLES SECTION
247
+ gr.Markdown("## Sample Data for Testing")
248
+
249
+ gr.Examples(
250
+ examples=examples,
251
+ inputs=input_image,
252
+ outputs=[output_image, output_text],
253
+ fn=process_image,
254
+ cache_examples=False,
255
+ label="Click to load and run a sample detection.",
256
+ )
257
 
258
+ demo.queue()
259
  demo.launch()
licence.jpg ADDED

Git LFS Details

  • SHA256: 4df78ddf6bdda816514c709964727e1b04576a6d36cc6afd218420a4d22cd040
  • Pointer size: 129 Bytes
  • Size of remote file: 7.8 kB
licence2.jpg ADDED

Git LFS Details

  • SHA256: 3edec1e90d0ede0c5e7dc956fe03a19a47256be54aa547c244b7c7c93a3b45a6
  • Pointer size: 130 Bytes
  • Size of remote file: 27.4 kB
requirements.txt CHANGED
@@ -1,6 +1,8 @@
1
- gradio
2
  ultralytics
3
  pillow
4
  numpy
5
  opencv-python
6
- torch
 
 
 
 
 
1
  ultralytics
2
  pillow
3
  numpy
4
  opencv-python
5
+ torch
6
+ numpy<2
7
+ gradio==3.50.2
8
+ gradio-client==0.6.1