DawnC commited on
Commit
c8fce61
·
1 Parent(s): 7f08dd3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -28
app.py CHANGED
@@ -166,57 +166,139 @@ async def predict_single_dog(image):
166
  return top1_prob, topk_breeds, topk_probs_percent
167
 
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  async def detect_multiple_dogs(image, conf_threshold=0.35, iou_threshold=0.55):
170
  results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
171
  dogs = []
172
  boxes = []
 
 
173
  for box in results.boxes:
174
  if box.cls == 16: # COCO dataset class for dog is 16
175
  xyxy = box.xyxy[0].tolist()
176
  confidence = box.conf.item()
177
- boxes.append((xyxy, confidence))
 
178
 
179
  if not boxes:
180
  dogs.append((image, 1.0, [0, 0, image.width, image.height]))
181
  else:
182
- nms_boxes = non_max_suppression(boxes, iou_threshold)
 
 
183
 
184
- for box, confidence in nms_boxes:
185
- x1, y1, x2, y2 = box
186
  w, h = x2 - x1, y2 - y1
187
  x1 = max(0, x1 - w * 0.05)
188
  y1 = max(0, y1 - h * 0.05)
189
  x2 = min(image.width, x2 + w * 0.05)
190
  y2 = min(image.height, y2 + h * 0.05)
191
  cropped_image = image.crop((x1, y1, x2, y2))
192
- dogs.append((cropped_image, confidence, [x1, y1, x2, y2]))
193
 
194
  return dogs
195
 
196
 
197
- def non_max_suppression(boxes, iou_threshold):
198
- keep = []
199
- boxes = sorted(boxes, key=lambda x: x[1], reverse=True)
200
- while boxes:
201
- current = boxes.pop(0)
202
- keep.append(current)
203
- boxes = [box for box in boxes if calculate_iou(current[0], box[0]) < iou_threshold]
204
- return keep
205
-
206
- def calculate_iou(box1, box2):
207
- x1 = max(box1[0], box2[0])
208
- y1 = max(box1[1], box2[1])
209
- x2 = min(box1[2], box2[2])
210
- y2 = min(box1[3], box2[3])
211
-
212
- intersection = max(0, x2 - x1) * max(0, y2 - y1)
213
- area1 = (box1[2] - box1[0]) * (box1[3] - box1[1])
214
- area2 = (box2[2] - box2[0]) * (box2[3] - box2[1])
215
-
216
- iou = intersection / float(area1 + area2 - intersection)
217
- return iou
218
-
219
-
220
  async def process_single_dog(image):
221
  top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(image)
222
  if top1_prob < 0.15:
 
166
  return top1_prob, topk_breeds, topk_probs_percent
167
 
168
 
169
+ # async def detect_multiple_dogs(image, conf_threshold=0.35, iou_threshold=0.55):
170
+ # results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
171
+ # dogs = []
172
+ # boxes = []
173
+ # for box in results.boxes:
174
+ # if box.cls == 16: # COCO dataset class for dog is 16
175
+ # xyxy = box.xyxy[0].tolist()
176
+ # confidence = box.conf.item()
177
+ # boxes.append((xyxy, confidence))
178
+
179
+ # if not boxes:
180
+ # dogs.append((image, 1.0, [0, 0, image.width, image.height]))
181
+ # else:
182
+ # nms_boxes = non_max_suppression(boxes, iou_threshold)
183
+
184
+ # for box, confidence in nms_boxes:
185
+ # x1, y1, x2, y2 = box
186
+ # w, h = x2 - x1, y2 - y1
187
+ # x1 = max(0, x1 - w * 0.05)
188
+ # y1 = max(0, y1 - h * 0.05)
189
+ # x2 = min(image.width, x2 + w * 0.05)
190
+ # y2 = min(image.height, y2 + h * 0.05)
191
+ # cropped_image = image.crop((x1, y1, x2, y2))
192
+ # dogs.append((cropped_image, confidence, [x1, y1, x2, y2]))
193
+
194
+ # return dogs
195
+
196
+
197
+ # def non_max_suppression(boxes, iou_threshold):
198
+ # keep = []
199
+ # boxes = sorted(boxes, key=lambda x: x[1], reverse=True)
200
+ # while boxes:
201
+ # current = boxes.pop(0)
202
+ # keep.append(current)
203
+ # boxes = [box for box in boxes if calculate_iou(current[0], box[0]) < iou_threshold]
204
+ # return keep
205
+
206
+ # def calculate_iou(box1, box2):
207
+ # x1 = max(box1[0], box2[0])
208
+ # y1 = max(box1[1], box2[1])
209
+ # x2 = min(box1[2], box2[2])
210
+ # y2 = min(box1[3], box2[3])
211
+
212
+ # intersection = max(0, x2 - x1) * max(0, y2 - y1)
213
+ # area1 = (box1[2] - box1[0]) * (box1[3] - box1[1])
214
+ # area2 = (box2[2] - box2[0]) * (box2[3] - box2[1])
215
+
216
+ # iou = intersection / float(area1 + area2 - intersection)
217
+ # return iou
218
+
219
+ def soft_nms(boxes, scores, sigma=0.5, thresh=0.001, method='gaussian'):
220
+ N = len(boxes)
221
+
222
+ for i in range(N):
223
+ maxscore = scores[i]
224
+ maxpos = i
225
+
226
+ tx1, ty1, tx2, ty2 = boxes[i]
227
+ ts = scores[i]
228
+
229
+ pos = i + 1
230
+ while pos < N:
231
+ if maxscore < scores[pos]:
232
+ maxscore = scores[pos]
233
+ maxpos = pos
234
+ pos += 1
235
+
236
+ # 交換最大分數和當前索引
237
+ boxes[i], boxes[maxpos] = boxes[maxpos].copy(), boxes[i].copy()
238
+ scores[i], scores[maxpos] = scores[maxpos], scores[i]
239
+
240
+ # 對剩餘的框應用 Soft NMS
241
+ for pos in range(i + 1, N):
242
+ tx1, ty1, tx2, ty2 = boxes[pos]
243
+ ts = scores[pos]
244
+
245
+ iou = calculate_iou(boxes[i], boxes[pos])
246
+
247
+ if method == 'linear':
248
+ weight = 1 - iou if iou > thresh else 1
249
+ elif method == 'gaussian':
250
+ weight = torch.exp(-(iou * iou) / sigma)
251
+ else: # 'original'
252
+ if iou > thresh:
253
+ weight = 0
254
+ else:
255
+ weight = 1
256
+
257
+ scores[pos] = weight * scores[pos]
258
+
259
+ if scores[pos] < thresh:
260
+ scores[pos] = 0
261
+
262
+ # 刪除得分為零的框
263
+ keep = scores > 0
264
+ boxes = boxes[keep]
265
+ scores = scores[keep]
266
+
267
+ return boxes, scores
268
+
269
  async def detect_multiple_dogs(image, conf_threshold=0.35, iou_threshold=0.55):
270
  results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
271
  dogs = []
272
  boxes = []
273
+ scores = []
274
+
275
  for box in results.boxes:
276
  if box.cls == 16: # COCO dataset class for dog is 16
277
  xyxy = box.xyxy[0].tolist()
278
  confidence = box.conf.item()
279
+ boxes.append(xyxy)
280
+ scores.append(confidence)
281
 
282
  if not boxes:
283
  dogs.append((image, 1.0, [0, 0, image.width, image.height]))
284
  else:
285
+ boxes = torch.tensor(boxes)
286
+ scores = torch.tensor(scores)
287
+ nms_boxes, nms_scores = soft_nms(boxes, scores, thresh=iou_threshold)
288
 
289
+ for box, score in zip(nms_boxes, nms_scores):
290
+ x1, y1, x2, y2 = box.tolist()
291
  w, h = x2 - x1, y2 - y1
292
  x1 = max(0, x1 - w * 0.05)
293
  y1 = max(0, y1 - h * 0.05)
294
  x2 = min(image.width, x2 + w * 0.05)
295
  y2 = min(image.height, y2 + h * 0.05)
296
  cropped_image = image.crop((x1, y1, x2, y2))
297
+ dogs.append((cropped_image, score.item(), [x1, y1, x2, y2]))
298
 
299
  return dogs
300
 
301
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  async def process_single_dog(image):
303
  top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(image)
304
  if top1_prob < 0.15: