Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
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(
|
|
|
178 |
|
179 |
if not boxes:
|
180 |
dogs.append((image, 1.0, [0, 0, image.width, image.height]))
|
181 |
else:
|
182 |
-
|
|
|
|
|
183 |
|
184 |
-
for box,
|
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,
|
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:
|