nolenfelten commited on
Commit
287fcc7
·
verified ·
1 Parent(s): 8514e66

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -48
app.py CHANGED
@@ -4,15 +4,19 @@ from huggingface_hub import hf_hub_download
4
  from PIL import Image, ImageDraw
5
  import numpy as np
6
  import json
 
 
7
 
 
8
  REPO_ID = "thoucentric/Shelf_Objects_Detection_Yolov7_Pytorch"
9
  FILENAME = "best.pt"
10
-
11
  yolov7_custom_weights = hf_hub_download(repo_id=REPO_ID, filename=FILENAME)
12
 
13
- model = torch.hub.load('Owaiskhan9654/yolov7-1:main', model='custom', path_or_model=yolov7_custom_weights, force_reload=True) # Github repository https://github.com/Owaiskhan9654
 
14
 
15
- def split_image(image, tile_size=640, overlap=80):
 
16
  img_width, img_height = image.size
17
  tiles = []
18
 
@@ -50,39 +54,76 @@ def draw_bounding_boxes(image, bounding_boxes):
50
  draw.text((bbox['xmin'], bbox['ymin']), f"{bbox['class']} {bbox['confidence']:.2f}", fill=color)
51
  return image
52
 
53
- def non_max_suppression(bounding_boxes, iou_threshold):
 
54
  if not bounding_boxes:
55
  return []
56
 
57
- bboxes = sorted(bounding_boxes, key=lambda x: x['confidence'], reverse=True)
58
- final_bboxes = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
- while bboxes:
61
- chosen_box = bboxes.pop(0)
62
- final_bboxes.append(chosen_box)
63
 
64
- def iou(box1, box2):
65
- x1 = max(box1['xmin'], box2['xmin'])
66
- y1 = max(box1['ymin'], box2['ymin'])
67
- x2 = min(box1['xmax'], box2['xmax'])
68
- y2 = min(box1['ymax'], box2['ymax'])
69
 
70
- intersection = max(0, x2 - x1) * max(0, y2 - y1)
71
- box1_area = (box1['xmax'] - box1['xmin']) * (box1['ymax'] - box1['ymin'])
72
- box2_area = (box2['xmax'] - box2['xmin']) * (box2['ymax'] - box2['ymin'])
 
 
 
 
 
 
 
73
 
74
- union = box1_area + box2_area - intersection
75
- return intersection / union
 
76
 
77
- bboxes = [box for box in bboxes if iou(chosen_box, box) < iou_threshold]
 
 
 
78
 
79
- return final_bboxes
 
80
 
81
- def object_detection(image, model_choice, conf_threshold=0.25, iou_threshold=0.45):
82
- image = Image.fromarray(image) # Convert to PIL Image
83
- model.conf = conf_threshold # set confidence threshold
84
- model.iou = iou_threshold # set IOU threshold
85
- tiles = split_image(image)
 
 
86
  all_bounding_boxes = []
87
 
88
  for tile, box in tiles:
@@ -90,49 +131,126 @@ def object_detection(image, model_choice, conf_threshold=0.25, iou_threshold=0.4
90
  adjusted_bboxes = merge_bounding_boxes(results, box)
91
  all_bounding_boxes.extend(adjusted_bboxes)
92
 
93
- final_bounding_boxes = non_max_suppression(all_bounding_boxes, iou_threshold)
94
  image_with_boxes = draw_bounding_boxes(image, final_bounding_boxes)
95
 
96
  json_response = json.dumps(final_bounding_boxes, indent=4)
97
  return image_with_boxes, json_response
98
 
99
- def save_results(image, json_data):
100
- image.save("output_image.jpg")
101
- with open("output_data.json", "w") as f:
102
- f.write(json_data)
103
- return "Results saved successfully."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
- title = "<center>Yolov7 Custom</center>"
 
 
 
 
 
 
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  inputs = [
108
  gr.inputs.Image(shape=(4080, 1836), image_mode="RGB", source="upload", label="Upload Image", optional=False),
109
- gr.inputs.Dropdown(["best.pt"], default="best.pt", label="Model"),
110
  gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.25, step=0.01, label="Confidence Threshold"),
111
  gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.45, step=0.01, label="IOU Threshold"),
112
  ]
113
  outputs_image = gr.outputs.Image(type="pil", label="Output Image")
114
  outputs_json = gr.Textbox(label="Bounding Boxes JSON")
115
 
116
- Custom_description = "<center>Nolen Felten</center>"
117
-
118
- Footer = ("<br><br><br><br><center><b>Item Classes it will detect(Total 140 Classes) <br></b>")
119
- examples1 = [["Images/Image1.jpg"]]
120
- css = ".output-image {height: 50rem important; width: 100% !important;}, .input-image {height: 50rem !important; width: 100% !important;}"
121
- css = ".image-preview {height: auto important;}"
122
 
 
123
  interface = gr.Interface(
124
  fn=object_detection,
125
  inputs=inputs,
126
  outputs=[outputs_image, outputs_json],
127
- title="Cig Counter",
128
- description=Custom_description,
129
- article=Footer,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  cache_examples=False,
131
- allow_flagging='never',
132
- examples=examples1
133
  )
134
 
135
- interface.launch(debug=True)
 
 
 
 
136
 
137
- save_button = gr.Button("Save Results")
138
- save_button.click(fn=save_results, inputs=[outputs_image, outputs_json], outputs="text")
 
4
  from PIL import Image, ImageDraw
5
  import numpy as np
6
  import json
7
+ import cv2
8
+ from scipy.ndimage import gaussian_filter
9
 
10
+ # Constants and Model Downloads
11
  REPO_ID = "thoucentric/Shelf_Objects_Detection_Yolov7_Pytorch"
12
  FILENAME = "best.pt"
 
13
  yolov7_custom_weights = hf_hub_download(repo_id=REPO_ID, filename=FILENAME)
14
 
15
+ # Load YOLOv7 Custom Model
16
+ model = torch.hub.load('Owaiskhan9654/yolov7-1:main', model='custom', path_or_model=yolov7_custom_weights, force_reload=True)
17
 
18
+ # Image Splitting and Merging Functionality
19
+ def split_image(image, tile_size=640, overlap=160):
20
  img_width, img_height = image.size
21
  tiles = []
22
 
 
54
  draw.text((bbox['xmin'], bbox['ymin']), f"{bbox['class']} {bbox['confidence']:.2f}", fill=color)
55
  return image
56
 
57
+ # Non-Max Suppression Implementations
58
+ def soft_nms(bounding_boxes, iou_threshold=0.3, sigma=0.5, score_threshold=0.001):
59
  if not bounding_boxes:
60
  return []
61
 
62
+ def iou(box1, box2):
63
+ x1 = max(box1['xmin'], box2['xmin'])
64
+ y1 = max(box1['ymin'], box2['ymin'])
65
+ x2 = min(box1['xmax'], box2['xmax'])
66
+ y2 = min(box1['ymax'], box2['ymax'])
67
+
68
+ intersection = max(0, x2 - x1) * max(0, y2 - y1)
69
+ box1_area = (box1['xmax'] - box1['xmin']) * (box1['ymax'] - box1['ymin'])
70
+ box2_area = (box2['xmax'] - box2['xmin']) * (box2['ymax'] - box2['ymin'])
71
+
72
+ union = box1_area + box2_area - intersection
73
+ return intersection / union
74
+
75
+ boxes = sorted(bounding_boxes, key=lambda x: x['confidence'], reverse=True)
76
+ final_boxes = []
77
+
78
+ while boxes:
79
+ chosen_box = boxes.pop(0)
80
+ final_boxes.append(chosen_box)
81
+
82
+ new_boxes = []
83
+ for box in boxes:
84
+ iou_score = iou(chosen_box, box)
85
+ if iou_score > iou_threshold:
86
+ box['confidence'] *= np.exp(-(iou_score ** 2) / sigma)
87
+ if box['confidence'] > score_threshold:
88
+ new_boxes.append(box)
89
+ boxes = new_boxes
90
 
91
+ return final_boxes
 
 
92
 
93
+ # Density Map Generation and Counting Functions
94
+ def generate_density_map(image, bounding_boxes, sigma=4):
95
+ density_map = np.zeros((image.height, image.width))
 
 
96
 
97
+ for bbox in bounding_boxes:
98
+ center_x = int((bbox['xmin'] + bbox['xmax']) / 2)
99
+ center_y = int((bbox['ymin'] + bbox['ymax']) / 2)
100
+ density_map[center_y, center_x] += 1
101
+
102
+ density_map = gaussian_filter(density_map, sigma=sigma)
103
+ return density_map
104
+
105
+ def count_from_density_map(density_map, threshold=0.05):
106
+ return np.sum(density_map > threshold)
107
 
108
+ # Edge Enhancement Functions
109
+ def apply_edge_enhancement(image):
110
+ gray_image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2GRAY)
111
 
112
+ sobel_x = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=3)
113
+ sobel_y = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=3)
114
+ sobel_combined = np.sqrt(sobel_x**2 + sobel_y**2)
115
+ sobel_combined = np.uint8(sobel_combined / sobel_combined.max() * 255)
116
 
117
+ enhanced_image = cv2.cvtColor(sobel_combined, cv2.COLOR_GRAY2RGB)
118
+ return Image.fromarray(enhanced_image)
119
 
120
+ # Object Detection Functions
121
+ def object_detection(image, conf_threshold=0.25, iou_threshold=0.45):
122
+ image = Image.fromarray(image)
123
+ model.conf = conf_threshold
124
+ model.iou = iou_threshold
125
+
126
+ tiles = split_image(image, tile_size=640, overlap=160)
127
  all_bounding_boxes = []
128
 
129
  for tile, box in tiles:
 
131
  adjusted_bboxes = merge_bounding_boxes(results, box)
132
  all_bounding_boxes.extend(adjusted_bboxes)
133
 
134
+ final_bounding_boxes = soft_nms(all_bounding_boxes, iou_threshold=iou_threshold)
135
  image_with_boxes = draw_bounding_boxes(image, final_bounding_boxes)
136
 
137
  json_response = json.dumps(final_bounding_boxes, indent=4)
138
  return image_with_boxes, json_response
139
 
140
+ def object_detection_with_edge_enhancement(image, conf_threshold=0.25, iou_threshold=0.45):
141
+ image = Image.fromarray(image)
142
+ image_enhanced = apply_edge_enhancement(image)
143
+
144
+ model.conf = conf_threshold
145
+ model.iou = iou_threshold
146
+
147
+ tiles = split_image(image_enhanced, tile_size=640, overlap=160)
148
+ all_bounding_boxes = []
149
+
150
+ for tile, box in tiles:
151
+ results = model(tile)
152
+ adjusted_bboxes = merge_bounding_boxes(results, box)
153
+ all_bounding_boxes.extend(adjusted_bboxes)
154
+
155
+ final_bounding_boxes = soft_nms(all_bounding_boxes, iou_threshold=iou_threshold)
156
+ image_with_boxes = draw_bounding_boxes(image_enhanced, final_bounding_boxes)
157
+
158
+ json_response = json.dumps(final_bounding_boxes, indent=4)
159
+ return image_with_boxes, json_response
160
+
161
+ def object_detection_density_edge(image, conf_threshold=0.25, iou_threshold=0.45):
162
+ """Apply edge enhancement and density-based counting."""
163
+ image = Image.fromarray(image)
164
+ image_enhanced = apply_edge_enhancement(image)
165
+
166
+ model.conf = conf_threshold
167
+ model.iou = iou_threshold
168
 
169
+ tiles = split_image(image_enhanced, tile_size=640, overlap=160)
170
+ all_bounding_boxes = []
171
+
172
+ for tile, box in tiles:
173
+ results = model(tile)
174
+ adjusted_bboxes = merge_bounding_boxes(results, box)
175
+ all_bounding_boxes.extend(adjusted_bboxes)
176
 
177
+ final_bounding_boxes = soft_nms(all_bounding_boxes, iou_threshold=iou_threshold)
178
+ density_map = generate_density_map(image_enhanced, final_bounding_boxes)
179
+
180
+ density_map_rescaled = cv2.applyColorMap(
181
+ (density_map / np.max(density_map) * 255).astype(np.uint8),
182
+ cv2.COLORMAP_JET
183
+ )
184
+ density_map_pil = Image.fromarray(cv2.cvtColor(density_map_rescaled, cv2.COLOR_BGR2RGB))
185
+ image_with_density = Image.blend(image_enhanced, density_map_pil, alpha=0.5)
186
+
187
+ json_response = json.dumps(final_bounding_boxes, indent=4)
188
+ object_count = count_from_density_map(density_map)
189
+
190
+ summary = json.dumps({"object_count": int(object_count)}, indent=4)
191
+ return image_with_density, json_response, summary
192
+
193
+ # Gradio Interface Definitions
194
  inputs = [
195
  gr.inputs.Image(shape=(4080, 1836), image_mode="RGB", source="upload", label="Upload Image", optional=False),
 
196
  gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.25, step=0.01, label="Confidence Threshold"),
197
  gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.45, step=0.01, label="IOU Threshold"),
198
  ]
199
  outputs_image = gr.outputs.Image(type="pil", label="Output Image")
200
  outputs_json = gr.Textbox(label="Bounding Boxes JSON")
201
 
202
+ title = "<center>Yolov7 Custom Object Detection</center>"
203
+ description = "<center>Nolen Felten</center>"
204
+ footer = ("<br><br><center><b>Item Classes it will detect (Total 140 Classes)</b></center>")
 
 
 
205
 
206
+ # Regular Object Detection Interface
207
  interface = gr.Interface(
208
  fn=object_detection,
209
  inputs=inputs,
210
  outputs=[outputs_image, outputs_json],
211
+ title=title,
212
+ description=description,
213
+ article=footer,
214
+ cache_examples=False,
215
+ allow_flagging="never"
216
+ )
217
+
218
+ # Edge Enhanced Object Detection Interface
219
+ interface_edge = gr.Interface(
220
+ fn=object_detection_with_edge_enhancement,
221
+ inputs=inputs,
222
+ outputs=[outputs_image, outputs_json],
223
+ title="Object Detection with Edge Enhancement",
224
+ description=description,
225
+ article=footer,
226
+ cache_examples=False,
227
+ allow_flagging="never"
228
+ )
229
+
230
+ # Edge Enhanced Density-Based Counting Interface
231
+ inputs_density_edge = [
232
+ gr.inputs.Image(shape=(4080, 1836), image_mode="RGB", source="upload", label="Upload Image", optional=False),
233
+ gr.inputs.Slider(minimum=0.0, maximum=1.0, default=0.25, step=0.01, label="Confidence Threshold"),
234
+ gr.inputs.Slider(minimum=0.0, maximum 1.0, default=0.45, step=0.01, label="IOU Threshold"),
235
+ ]
236
+ outputs_density_edge = [outputs_image, outputs_json, gr.Textbox(label="Density-based Count Summary")]
237
+
238
+ interface_density_edge = gr.Interface(
239
+ fn=object_detection_density_edge,
240
+ inputs=inputs_density_edge,
241
+ outputs=outputs_density_edge,
242
+ title="Object Detection with Density-Based Counting and Edge Enhancement",
243
+ description=description,
244
+ article=footer,
245
  cache_examples=False,
246
+ allow_flagging="never"
 
247
  )
248
 
249
+ # Launch Gradio Interfaces
250
+ def launch_interfaces():
251
+ interface.launch(debug=True)
252
+ interface_edge.launch(debug=True)
253
+ interface_density_edge.launch(debug=True)
254
 
255
+ if __name__ == "__main__":
256
+ launch_interfaces()