nolenfelten commited on
Commit
9a04695
·
verified ·
1 Parent(s): f82d829

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +168 -74
app.py CHANGED
@@ -1,37 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  print("import torch")
2
  import torch
3
 
4
  print("import gradio")
5
  import gradio as gr
6
 
 
 
 
 
 
 
7
  print("import huggingface_hub")
8
  from huggingface_hub import hf_hub_download
9
 
10
  print("import PIL")
11
  from PIL import Image, ImageDraw
12
 
13
- print("import numpy")
14
- import numpy as np
15
-
16
- print("import json")
17
- import json
18
-
19
- print("import opencv")
20
- import cv2
21
-
22
  print("import scipy")
23
  from scipy.ndimage import gaussian_filter
24
 
25
 
26
  # Constants and Model Downloads
27
- REPO_ID = "thoucentric/Shelf_Objects_Detection_Yolov7_Pytorch"
28
- FILENAME = "best.pt"
29
- yolov7_custom_weights = hf_hub_download(repo_id=REPO_ID, filename=FILENAME)
30
 
31
  # Load YOLOv7 Custom Model
32
  print("Load YOLOv7 Custom Model")
33
  model = torch.hub.load('Owaiskhan9654/yolov7-1:main', model='custom', path_or_model=yolov7_custom_weights, force_reload=True)
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  # Image Splitting and Merging Functionality
36
  def split_image(image, tile_size=640, overlap=160):
37
  img_width, img_height = image.size
@@ -47,6 +95,8 @@ def split_image(image, tile_size=640, overlap=160):
47
 
48
  return tiles
49
 
 
 
50
  def merge_bounding_boxes(results, box):
51
  adjusted_bboxes = []
52
  for idx, row in results.pandas().xyxy[0].iterrows():
@@ -55,14 +105,17 @@ def merge_bounding_boxes(results, box):
55
  "center_x": (row['xmin'] + row['xmax']) / 2 + box[0],
56
  "center_y": (row['ymin'] + row['ymax']) / 2 + box[1],
57
  "xmin": row['xmin'] + box[0],
58
- "ymin": row['ymin'] + box[1],
59
  "xmax": row['xmax'] + box[0],
 
60
  "ymax": row['ymax'] + box[1],
61
  "confidence": row['confidence'],
62
  }
63
  adjusted_bboxes.append(adjusted_bbox)
64
  return adjusted_bboxes
65
 
 
 
 
66
  def draw_bounding_boxes(image, bounding_boxes):
67
  draw = ImageDraw.Draw(image)
68
  for bbox in bounding_boxes:
@@ -71,6 +124,7 @@ def draw_bounding_boxes(image, bounding_boxes):
71
  draw.text((bbox['xmin'], bbox['ymin']), f"{bbox['class']} {bbox['confidence']:.2f}", fill=color)
72
  return image
73
 
 
74
  # Non-Max Suppression Implementations
75
  def soft_nms(bounding_boxes, iou_threshold=0.3, sigma=0.5, score_threshold=0.001):
76
  if not bounding_boxes:
@@ -107,6 +161,8 @@ def soft_nms(bounding_boxes, iou_threshold=0.3, sigma=0.5, score_threshold=0.001
107
 
108
  return final_boxes
109
 
 
 
110
  # Density Map Generation and Counting Functions
111
  def generate_density_map(image, bounding_boxes, sigma=4):
112
  density_map = np.zeros((image.height, image.width))
@@ -119,9 +175,13 @@ def generate_density_map(image, bounding_boxes, sigma=4):
119
  density_map = gaussian_filter(density_map, sigma=sigma)
120
  return density_map
121
 
 
 
122
  def count_from_density_map(density_map, threshold=0.05):
123
  return np.sum(density_map > threshold)
124
 
 
 
125
  # Edge Enhancement Functions
126
  def apply_edge_enhancement(image):
127
  gray_image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2GRAY)
@@ -134,6 +194,8 @@ def apply_edge_enhancement(image):
134
  enhanced_image = cv2.cvtColor(sobel_combined, cv2.COLOR_GRAY2RGB)
135
  return Image.fromarray(enhanced_image)
136
 
 
 
137
  # Object Detection Functions
138
  def object_detection(image, conf_threshold=0.25, iou_threshold=0.45):
139
  image = Image.fromarray(image)
@@ -154,6 +216,8 @@ def object_detection(image, conf_threshold=0.25, iou_threshold=0.45):
154
  json_response = json.dumps(final_bounding_boxes, indent=4)
155
  return image_with_boxes, json_response
156
 
 
 
157
  def object_detection_with_edge_enhancement(image, conf_threshold=0.25, iou_threshold=0.45):
158
  image = Image.fromarray(image)
159
  image_enhanced = apply_edge_enhancement(image)
@@ -175,6 +239,8 @@ def object_detection_with_edge_enhancement(image, conf_threshold=0.25, iou_thres
175
  json_response = json.dumps(final_bounding_boxes, indent=4)
176
  return image_with_boxes, json_response
177
 
 
 
178
  def object_detection_density_edge(image, conf_threshold=0.25, iou_threshold=0.45):
179
  """Apply edge enhancement and density-based counting."""
180
  image = Image.fromarray(image)
@@ -207,73 +273,101 @@ def object_detection_density_edge(image, conf_threshold=0.25, iou_threshold=0.45
207
  summary = json.dumps({"object_count": int(object_count)}, indent=4)
208
  return image_with_density, json_response, summary
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  # Gradio Interface Definitions
211
  inputs = [
212
- gr.inputs.Image(shape=(4080, 1836), image_mode="RGB", source="upload", label="Upload Image", optional=False),
213
- gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.25, step=0.01, label="Confidence Threshold"),
214
- gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.45, step=0.01, label="IOU Threshold"),
 
 
 
 
215
  ]
216
- outputs_image = [
217
- gr.outputs.Image(type="pil", label="Output Image")
218
- ]
219
- outputs_json = gr.Textbox(label="Bounding Boxes JSON")
220
-
221
- title = "<center>Yolov7 Custom Object Detection</center>"
222
- description = "<center>Nolen Felten</center>"
223
- footer = ("<br><br><center><b>Item Classes it will detect (Total 140 Classes)</b></center>")
224
-
225
-
226
- interfaces = [
227
- # Regular Object Detection Interface
228
- gr.Interface(
229
- fn=object_detection,
230
- inputs=inputs,
231
- outputs=[outputs_image, outputs_json],
232
- title=title,
233
- description=description,
234
- article=footer,
235
- cache_examples=False,
236
- allow_flagging="never"
237
- ),
238
-
239
 
240
- # Edge Enhanced Object Detection Interface
241
- gr.Interface(
242
- fn=object_detection_with_edge_enhancement,
243
- inputs=inputs,
244
- outputs=[outputs_image, outputs_json],
245
- title="Object Detection with Edge Enhancement",
246
- description=description,
247
- article=footer,
248
- cache_examples=False,
249
- allow_flagging="never"
250
- )
251
- ]
252
 
253
- # Edge Enhanced Density-Based Counting Interface
254
- inputs_density_edge = [
255
- gr.inputs.Image(shape=(4080, 1836), image_mode="RGB", source="upload", label="Upload Image", optional=False),
256
- gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.25, step=0.01, label="Confidence Threshold"),
257
- gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.45, step=0.01, label="IOU Threshold"),
 
258
  ]
259
- outputs_density_edge = [outputs_image, outputs_json, gr.Textbox(label="Density-based Count Summary")]
260
-
261
- interface_density_edge = gr.Interface(
262
- fn=object_detection_density_edge,
263
- inputs=inputs_density_edge,
264
- outputs=outputs_density_edge,
265
- title="Object Detection with Density-Based Counting and Edge Enhancement",
266
- description=description,
267
- article=footer,
268
- cache_examples=False,
269
- allow_flagging="never"
 
 
 
 
 
 
 
 
 
270
  )
271
 
272
  # Launch Gradio Interfaces
273
- def launch_interfaces():
274
- interface.launch(debug=True)
275
- interface_edge.launch(debug=True)
276
- interface_density_edge.launch(debug=True)
277
-
278
- if __name__ == "__main__":
279
- launch_interfaces()
 
1
+ print("import io")
2
+ import io
3
+
4
+ print("import requests")
5
+ import requests
6
+
7
+ print("import json")
8
+ import json
9
+
10
+ print("import base64")
11
+ import base64
12
+
13
+ print("import opencv")
14
+ import cv2
15
+
16
  print("import torch")
17
  import torch
18
 
19
  print("import gradio")
20
  import gradio as gr
21
 
22
+ print("import numpy")
23
+ import numpy as np
24
+
25
+ print("import Roboflow")
26
+ from roboflow import Roboflow
27
+
28
  print("import huggingface_hub")
29
  from huggingface_hub import hf_hub_download
30
 
31
  print("import PIL")
32
  from PIL import Image, ImageDraw
33
 
 
 
 
 
 
 
 
 
 
34
  print("import scipy")
35
  from scipy.ndimage import gaussian_filter
36
 
37
 
38
  # Constants and Model Downloads
39
+ print("Download YOLO")
40
+ yolov7_custom_weights = hf_hub_download(repo_id = "nolenfelten/Shelf_Objects_Detection_Yolov7_Pytorch", filename = "best.pt")
 
41
 
42
  # Load YOLOv7 Custom Model
43
  print("Load YOLOv7 Custom Model")
44
  model = torch.hub.load('Owaiskhan9654/yolov7-1:main', model='custom', path_or_model=yolov7_custom_weights, force_reload=True)
45
 
46
+ # Roboflow
47
+ print("Initialize Roboflow")
48
+ rf = Roboflow(api_key="gHiUgOSq9GqTnRy5mErk")
49
+ project = rf.workspace().project("sku-110k")
50
+ model = project.version(2).model
51
+
52
+
53
+ def encode_image(image):
54
+ buffered = io.BytesIO()
55
+ return base64.b64encode(buffered.getvalue()).decode("utf-8")
56
+
57
+
58
+
59
+ def roboflow(image, confidence, overlap, stroke_width=1, labels=False):
60
+ '''
61
+ Send the image to Roboflow API for inference.
62
+ Returns JSON and image with bounding boxes drawn on to it.
63
+ '''
64
+
65
+ json_url = f"https://detect.roboflow.com/sku-110k/2?api_key=gHiUgOSq9GqTnRy5mErk&confidence={confidence}&overlap={overlap}&format=json"
66
+ image_url = f"https://detect.roboflow.com/sku-110k/2?api_key=gHiUgOSq9GqTnRy5mErk&confidence={confidence}&overlap={overlap}&format=image&labels={str(labels).lower()}&stroke={stroke_width}"
67
+
68
+ encoded_image = encode_image(image)
69
+ headers = {"Content-Type": "application/x-www-form-urlencoded"}
70
+
71
+ json_request = requests.post(json_url, data=encoded_image, headers=headers)
72
+ image_request = requests.post(image_url, data=encoded_image, headers=headers)
73
+
74
+ response = {
75
+ "json": json_request.content,
76
+ "image": image_request.content
77
+ }
78
+
79
+ return response
80
+
81
+
82
+
83
  # Image Splitting and Merging Functionality
84
  def split_image(image, tile_size=640, overlap=160):
85
  img_width, img_height = image.size
 
95
 
96
  return tiles
97
 
98
+
99
+
100
  def merge_bounding_boxes(results, box):
101
  adjusted_bboxes = []
102
  for idx, row in results.pandas().xyxy[0].iterrows():
 
105
  "center_x": (row['xmin'] + row['xmax']) / 2 + box[0],
106
  "center_y": (row['ymin'] + row['ymax']) / 2 + box[1],
107
  "xmin": row['xmin'] + box[0],
 
108
  "xmax": row['xmax'] + box[0],
109
+ "ymin": row['ymin'] + box[1],
110
  "ymax": row['ymax'] + box[1],
111
  "confidence": row['confidence'],
112
  }
113
  adjusted_bboxes.append(adjusted_bbox)
114
  return adjusted_bboxes
115
 
116
+
117
+
118
+
119
  def draw_bounding_boxes(image, bounding_boxes):
120
  draw = ImageDraw.Draw(image)
121
  for bbox in bounding_boxes:
 
124
  draw.text((bbox['xmin'], bbox['ymin']), f"{bbox['class']} {bbox['confidence']:.2f}", fill=color)
125
  return image
126
 
127
+
128
  # Non-Max Suppression Implementations
129
  def soft_nms(bounding_boxes, iou_threshold=0.3, sigma=0.5, score_threshold=0.001):
130
  if not bounding_boxes:
 
161
 
162
  return final_boxes
163
 
164
+
165
+
166
  # Density Map Generation and Counting Functions
167
  def generate_density_map(image, bounding_boxes, sigma=4):
168
  density_map = np.zeros((image.height, image.width))
 
175
  density_map = gaussian_filter(density_map, sigma=sigma)
176
  return density_map
177
 
178
+
179
+
180
  def count_from_density_map(density_map, threshold=0.05):
181
  return np.sum(density_map > threshold)
182
 
183
+
184
+
185
  # Edge Enhancement Functions
186
  def apply_edge_enhancement(image):
187
  gray_image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2GRAY)
 
194
  enhanced_image = cv2.cvtColor(sobel_combined, cv2.COLOR_GRAY2RGB)
195
  return Image.fromarray(enhanced_image)
196
 
197
+
198
+
199
  # Object Detection Functions
200
  def object_detection(image, conf_threshold=0.25, iou_threshold=0.45):
201
  image = Image.fromarray(image)
 
216
  json_response = json.dumps(final_bounding_boxes, indent=4)
217
  return image_with_boxes, json_response
218
 
219
+
220
+
221
  def object_detection_with_edge_enhancement(image, conf_threshold=0.25, iou_threshold=0.45):
222
  image = Image.fromarray(image)
223
  image_enhanced = apply_edge_enhancement(image)
 
239
  json_response = json.dumps(final_bounding_boxes, indent=4)
240
  return image_with_boxes, json_response
241
 
242
+
243
+
244
  def object_detection_density_edge(image, conf_threshold=0.25, iou_threshold=0.45):
245
  """Apply edge enhancement and density-based counting."""
246
  image = Image.fromarray(image)
 
273
  summary = json.dumps({"object_count": int(object_count)}, indent=4)
274
  return image_with_density, json_response, summary
275
 
276
+
277
+
278
+ def procedure(image_input, yolov7_confidence_threshold_input, yolov7_IOU_Threshold_input, roboflow_confidence_threshold_input, roboflow_IOU_Threshold_input, roboflow_labels_input, roboflow_stroke_width_input, yolov7_image_output, yolov7_json_output, roboflow_image_output, roboflow_json_output):
279
+ '''
280
+ This function takes in an image and applies both YOLOv7 and Roboflow object detection models to it.
281
+ It then returns the images and JSON results.
282
+ '''
283
+
284
+ print("Begin Roboflow inferences.")
285
+ roboflow_inference = roboflow(image = image_input, labels=roboflow_labels_input, stroke_width=roboflow_stroke_width_input, confidence = roboflow_confidence_threshold_input, overlap = roboflow_IOU_Threshold_input, )
286
+
287
+ yolov7_image, yolov7_json = object_detection(np.array(image_input), yolov7_confidence_threshold_input, yolov7_IOU_Threshold_input)
288
+
289
+ roboflow_image = Image.open(io.BytesIO(roboflow_inference["image"]))
290
+ roboflow_json = roboflow_inference["json"]
291
+
292
+ return yolov7_image, yolov7_json, roboflow_image, roboflow_json
293
+
294
+
295
+ # Uploaded image.
296
+ image_input = gr.Image(shape=(4080, 1836), image_mode="RGB", source="upload", label="Upload Image", optional=False)
297
+
298
+ # YOLOv7 Confidence Threshold input.
299
+ yolov7_confidence_threshold_input = gr.Slider(minimum=0.0, maximum=1.0, value = 0.45, step=0.01, label="YOLOv7 Confidence Threshold")
300
+
301
+ # YOLOv7 IOU Threshold.
302
+ yolov7_IOU_Threshold_input = gr.Slider(minimum=0.0, maximum=1.0, value = 0.45, step=0.01, label="YOLOv7 IOU Threshold")
303
+
304
+ # Roboflow Confidence Threshold input.
305
+ roboflow_confidence_threshold_input = gr.Slider(minimum=0.0, maximum=1.0, value = 0.45, step=0.01, label="Roboflow Confidence Threshold")
306
+
307
+ # Roboflow IOU Threshold.
308
+ roboflow_IOU_Threshold_input = gr.Slider(minimum=0.0, maximum=1.0, value = 0.45, step=0.01, label="Roboflow IOU Threshold")
309
+
310
+ # Roboflow Labels.
311
+ roboflow_labels_input = gr.Checkbox(label="Roboflow Labels")
312
+
313
+ # Roboflow Stroke Width.
314
+ roboflow_stroke_width_input = gr.Radio([1, 2, 5, 10], label="Stroke Width")
315
+
316
+
317
+
318
+ # YOLOv7 Image Output.
319
+ yolov7_image_output = gr.Image(type="pil", label="YOLOv7 Output Image")
320
+
321
+ # YOLOv7 JSON Output.
322
+ yolov7_json_output = gr.Textbox(label="YOLOv7 Bounding Boxes JSON")
323
+
324
+ # Roboflow Image Output.
325
+ roboflow_image_output = gr.Image(type="pil", label="Roboflow Output Image")
326
+
327
+ # Roboflow JSON Output.
328
+ roboflow_json_output = gr.Textbox(label="Roboflow Bounding Boxes JSON")
329
+
330
+
331
  # Gradio Interface Definitions
332
  inputs = [
333
+ image_input,
334
+ yolov7_confidence_threshold_input,
335
+ yolov7_IOU_Threshold_input,
336
+ roboflow_confidence_threshold_input,
337
+ roboflow_IOU_Threshold_input,
338
+ roboflow_labels_input,
339
+ roboflow_stroke_width_input,
340
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
 
 
 
 
 
 
 
 
 
 
 
 
 
342
 
343
+
344
+ outputs = [
345
+ yolov7_image_output,
346
+ yolov7_json_output,
347
+ roboflow_image_output,
348
+ roboflow_json_output,
349
  ]
350
+
351
+
352
+ title = "<center>Cigarette Pack Counter</center>"
353
+ description = "<center><a href='http://counttek.online'><img src='https://mvp-83056e96f7ab.herokuapp.com/static/countteklogo2.png'></a><br><a href='https://nolenfelten.github.io'>Project by Nolen Felten</a></center>"
354
+ footer = ("<center><b>Item Classes it will detect (Total 140 Classes)</b></center>")
355
+
356
+
357
+
358
+ interface = gr.Interface(
359
+ # Run this function when user clicks "Submit".
360
+ fn = procedure,
361
+
362
+ inputs,
363
+
364
+ outputs,
365
+ title = title,
366
+ description = description,
367
+ article = footer,
368
+ cache_examples = False,
369
+ allow_flagging = "never"
370
  )
371
 
372
  # Launch Gradio Interfaces
373
+ interface.launch(debug=True)