Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -194,7 +194,7 @@ async def predict_single_dog(image):
|
|
| 194 |
return top1_prob, topk_breeds, topk_probs_percent
|
| 195 |
|
| 196 |
|
| 197 |
-
async def detect_multiple_dogs(image, conf_threshold=0.
|
| 198 |
results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
|
| 199 |
dogs = []
|
| 200 |
boxes = []
|
|
@@ -203,28 +203,27 @@ async def detect_multiple_dogs(image, conf_threshold=0.25, iou_threshold=0.3):
|
|
| 203 |
xyxy = box.xyxy[0].tolist()
|
| 204 |
confidence = box.conf.item()
|
| 205 |
boxes.append((xyxy, confidence))
|
| 206 |
-
|
| 207 |
-
# 如果沒有檢測到狗,使用整張圖片
|
| 208 |
if not boxes:
|
| 209 |
dogs.append((image, 1.0, [0, 0, image.width, image.height]))
|
| 210 |
else:
|
| 211 |
-
# 按置信度排序
|
| 212 |
sorted_boxes = sorted(boxes, key=lambda x: x[1], reverse=True)
|
| 213 |
-
|
| 214 |
-
# 使用非極大值抑制(NMS)來合併重疊的框
|
| 215 |
nms_boxes = non_max_suppression(sorted_boxes, iou_threshold)
|
| 216 |
|
| 217 |
for box, confidence in nms_boxes:
|
| 218 |
x1, y1, x2, y2 = box
|
| 219 |
-
# 擴大框的大小以包含更多上下文
|
| 220 |
w, h = x2 - x1, y2 - y1
|
| 221 |
-
x1 = max(0, x1 - w * 0.
|
| 222 |
-
y1 = max(0, y1 - h * 0.
|
| 223 |
-
x2 = min(image.width, x2 + w * 0.
|
| 224 |
-
y2 = min(image.height, y2 + h * 0.
|
| 225 |
cropped_image = image.crop((x1, y1, x2, y2))
|
| 226 |
dogs.append((cropped_image, confidence, [x1, y1, x2, y2]))
|
| 227 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
return dogs
|
| 229 |
|
| 230 |
def non_max_suppression(boxes, iou_threshold):
|
|
@@ -447,69 +446,6 @@ async def process_single_dog(image):
|
|
| 447 |
# iface.launch()
|
| 448 |
|
| 449 |
|
| 450 |
-
# async def predict(image):
|
| 451 |
-
# if image is None:
|
| 452 |
-
# return "Please upload an image to start.", None, gr.update(visible=False, choices=[]), None
|
| 453 |
-
|
| 454 |
-
# try:
|
| 455 |
-
# if isinstance(image, np.ndarray):
|
| 456 |
-
# image = Image.fromarray(image)
|
| 457 |
-
|
| 458 |
-
# dogs = await detect_multiple_dogs(image)
|
| 459 |
-
|
| 460 |
-
# color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
|
| 461 |
-
# explanations = []
|
| 462 |
-
# buttons = []
|
| 463 |
-
# annotated_image = image.copy()
|
| 464 |
-
# draw = ImageDraw.Draw(annotated_image)
|
| 465 |
-
# font = ImageFont.load_default()
|
| 466 |
-
|
| 467 |
-
# for i, (cropped_image, _, box) in enumerate(dogs):
|
| 468 |
-
# top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
|
| 469 |
-
# color = color_list[i % len(color_list)]
|
| 470 |
-
# draw.rectangle(box, outline=color, width=3)
|
| 471 |
-
# draw.text((box[0], box[1]), f"Dog {i+1}", fill=color, font=font)
|
| 472 |
-
|
| 473 |
-
# if top1_prob >= 0.5:
|
| 474 |
-
# breed = topk_breeds[0]
|
| 475 |
-
# description = get_dog_description(breed)
|
| 476 |
-
# formatted_description = format_description(description, breed)
|
| 477 |
-
# explanations.append(f"Dog {i+1}: {formatted_description}")
|
| 478 |
-
# elif top1_prob >= 0.2:
|
| 479 |
-
# dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
|
| 480 |
-
# dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
|
| 481 |
-
# explanations.append(dog_explanation)
|
| 482 |
-
# buttons.extend([f"Dog {i+1}: More about {breed}" for breed in topk_breeds[:3]])
|
| 483 |
-
# else:
|
| 484 |
-
# explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset.")
|
| 485 |
-
|
| 486 |
-
# final_explanation = "\n\n".join(explanations)
|
| 487 |
-
# if buttons:
|
| 488 |
-
# final_explanation += "\n\nClick on a button to view more information about the breed."
|
| 489 |
-
# initial_state = {
|
| 490 |
-
# "explanation": final_explanation,
|
| 491 |
-
# "buttons": buttons,
|
| 492 |
-
# "show_back": True,
|
| 493 |
-
# "image": annotated_image,
|
| 494 |
-
# "is_multi_dog": len(dogs) > 1,
|
| 495 |
-
# "dogs_info": explanations
|
| 496 |
-
# }
|
| 497 |
-
# return final_explanation, annotated_image, gr.update(visible=True, choices=buttons), initial_state
|
| 498 |
-
# else:
|
| 499 |
-
# initial_state = {
|
| 500 |
-
# "explanation": final_explanation,
|
| 501 |
-
# "buttons": [],
|
| 502 |
-
# "show_back": False,
|
| 503 |
-
# "image": annotated_image,
|
| 504 |
-
# "is_multi_dog": len(dogs) > 1,
|
| 505 |
-
# "dogs_info": explanations
|
| 506 |
-
# }
|
| 507 |
-
# return final_explanation, annotated_image, gr.update(visible=False, choices=[]), initial_state
|
| 508 |
-
|
| 509 |
-
# except Exception as e:
|
| 510 |
-
# error_msg = f"An error occurred: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
|
| 511 |
-
# print(error_msg)
|
| 512 |
-
# return error_msg, None, gr.update(visible=False, choices=[]), None
|
| 513 |
|
| 514 |
async def predict(image):
|
| 515 |
if image is None:
|
|
@@ -528,27 +464,27 @@ async def predict(image):
|
|
| 528 |
draw = ImageDraw.Draw(annotated_image)
|
| 529 |
font = ImageFont.load_default()
|
| 530 |
|
| 531 |
-
for i, (cropped_image,
|
| 532 |
top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
|
| 533 |
color = color_list[i % len(color_list)]
|
| 534 |
draw.rectangle(box, outline=color, width=3)
|
| 535 |
draw.text((box[0], box[1]), f"Dog {i+1}", fill=color, font=font)
|
| 536 |
|
| 537 |
-
|
|
|
|
|
|
|
|
|
|
| 538 |
breed = topk_breeds[0]
|
| 539 |
description = get_dog_description(breed)
|
| 540 |
formatted_description = format_description(description, breed)
|
| 541 |
explanations.append(f"Dog {i+1}: {formatted_description}")
|
| 542 |
-
elif
|
| 543 |
dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
|
| 544 |
dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
|
| 545 |
explanations.append(dog_explanation)
|
| 546 |
buttons.extend([f"Dog {i+1}: More about {breed}" for breed in topk_breeds[:3]])
|
| 547 |
else:
|
| 548 |
-
|
| 549 |
-
explanations.append("The image is unclear or does not contain a recognized dog breed.")
|
| 550 |
-
else:
|
| 551 |
-
explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset.")
|
| 552 |
|
| 553 |
final_explanation = "\n\n".join(explanations)
|
| 554 |
if buttons:
|
|
|
|
| 194 |
return top1_prob, topk_breeds, topk_probs_percent
|
| 195 |
|
| 196 |
|
| 197 |
+
async def detect_multiple_dogs(image, conf_threshold=0.2, iou_threshold=0.3):
|
| 198 |
results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
|
| 199 |
dogs = []
|
| 200 |
boxes = []
|
|
|
|
| 203 |
xyxy = box.xyxy[0].tolist()
|
| 204 |
confidence = box.conf.item()
|
| 205 |
boxes.append((xyxy, confidence))
|
| 206 |
+
|
|
|
|
| 207 |
if not boxes:
|
| 208 |
dogs.append((image, 1.0, [0, 0, image.width, image.height]))
|
| 209 |
else:
|
|
|
|
| 210 |
sorted_boxes = sorted(boxes, key=lambda x: x[1], reverse=True)
|
|
|
|
|
|
|
| 211 |
nms_boxes = non_max_suppression(sorted_boxes, iou_threshold)
|
| 212 |
|
| 213 |
for box, confidence in nms_boxes:
|
| 214 |
x1, y1, x2, y2 = box
|
|
|
|
| 215 |
w, h = x2 - x1, y2 - y1
|
| 216 |
+
x1 = max(0, x1 - w * 0.1)
|
| 217 |
+
y1 = max(0, y1 - h * 0.1)
|
| 218 |
+
x2 = min(image.width, x2 + w * 0.1)
|
| 219 |
+
y2 = min(image.height, y2 + h * 0.1)
|
| 220 |
cropped_image = image.crop((x1, y1, x2, y2))
|
| 221 |
dogs.append((cropped_image, confidence, [x1, y1, x2, y2]))
|
| 222 |
+
|
| 223 |
+
# 如果只檢測到一隻狗,但置信度較低,添加整張圖片作為備選
|
| 224 |
+
if len(dogs) == 1 and dogs[0][1] < 0.5:
|
| 225 |
+
dogs.append((image, 1.0, [0, 0, image.width, image.height]))
|
| 226 |
+
|
| 227 |
return dogs
|
| 228 |
|
| 229 |
def non_max_suppression(boxes, iou_threshold):
|
|
|
|
| 446 |
# iface.launch()
|
| 447 |
|
| 448 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
|
| 450 |
async def predict(image):
|
| 451 |
if image is None:
|
|
|
|
| 464 |
draw = ImageDraw.Draw(annotated_image)
|
| 465 |
font = ImageFont.load_default()
|
| 466 |
|
| 467 |
+
for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
|
| 468 |
top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
|
| 469 |
color = color_list[i % len(color_list)]
|
| 470 |
draw.rectangle(box, outline=color, width=3)
|
| 471 |
draw.text((box[0], box[1]), f"Dog {i+1}", fill=color, font=font)
|
| 472 |
|
| 473 |
+
# 結合 YOLO 檢測置信度和品種識別置信度
|
| 474 |
+
combined_confidence = detection_confidence * top1_prob
|
| 475 |
+
|
| 476 |
+
if combined_confidence >= 0.4:
|
| 477 |
breed = topk_breeds[0]
|
| 478 |
description = get_dog_description(breed)
|
| 479 |
formatted_description = format_description(description, breed)
|
| 480 |
explanations.append(f"Dog {i+1}: {formatted_description}")
|
| 481 |
+
elif combined_confidence >= 0.2:
|
| 482 |
dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
|
| 483 |
dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
|
| 484 |
explanations.append(dog_explanation)
|
| 485 |
buttons.extend([f"Dog {i+1}: More about {breed}" for breed in topk_breeds[:3]])
|
| 486 |
else:
|
| 487 |
+
explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset.")
|
|
|
|
|
|
|
|
|
|
| 488 |
|
| 489 |
final_explanation = "\n\n".join(explanations)
|
| 490 |
if buttons:
|