DawnC commited on
Commit
e296e0a
1 Parent(s): 539c3b0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -141
app.py CHANGED
@@ -153,33 +153,6 @@ def format_description(description, breed):
153
 
154
  return formatted_description
155
 
156
- # async def predict_single_dog(image):
157
- # return await asyncio.to_thread(_predict_single_dog, image)
158
-
159
- # def _predict_single_dog(image):
160
- # image_tensor = preprocess_image(image)
161
- # with torch.no_grad():
162
- # output = model(image_tensor)
163
- # logits = output[0] if isinstance(output, tuple) else output
164
- # probabilities = F.softmax(logits, dim=1)
165
- # topk_probs, topk_indices = torch.topk(probabilities, k=3)
166
- # top1_prob = topk_probs[0][0].item()
167
- # topk_breeds = [dog_breeds[idx.item()] for idx in topk_indices[0]]
168
- # topk_probs_percent = [f"{prob.item() * 100:.2f}%" for prob in topk_probs[0]]
169
- # return top1_prob, topk_breeds, topk_probs_percent
170
-
171
-
172
- # async def detect_multiple_dogs(image, conf_threshold=0.25, iou_threshold=0.4):
173
- # results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
174
- # dogs = []
175
- # for box in results.boxes:
176
- # if box.cls == 16: # COCO 資料集中狗的類別是 16
177
- # xyxy = box.xyxy[0].tolist()
178
- # confidence = box.conf.item()
179
- # cropped_image = image.crop((xyxy[0], xyxy[1], xyxy[2], xyxy[3]))
180
- # dogs.append((cropped_image, confidence, xyxy))
181
- # return dogs
182
-
183
 
184
  async def predict_single_dog(image):
185
  image_tensor = preprocess_image(image)
@@ -194,6 +167,33 @@ 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.25, iou_threshold=0.4):
198
  results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
199
  dogs = []
@@ -212,13 +212,17 @@ async def detect_multiple_dogs(image, conf_threshold=0.25, iou_threshold=0.4):
212
  for box, confidence in nms_boxes:
213
  x1, y1, x2, y2 = box
214
  w, h = x2 - x1, y2 - y1
215
- x1 = max(0, x1 - w * 0.05)
216
- y1 = max(0, y1 - h * 0.05)
217
- x2 = min(image.width, x2 + w * 0.05)
218
- y2 = min(image.height, y2 + h * 0.05)
219
  cropped_image = image.crop((x1, y1, x2, y2))
220
  dogs.append((cropped_image, confidence, [x1, y1, x2, y2]))
221
 
 
 
 
 
222
  return dogs
223
 
224
  def non_max_suppression(boxes, iou_threshold):
@@ -291,16 +295,16 @@ async def process_single_dog(image):
291
  }
292
  return explanation, image, buttons[0], buttons[1], buttons[2], gr.update(visible=True), initial_state
293
 
 
294
  # async def predict(image):
295
  # if image is None:
296
- # return "Please upload an image to start.", None, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), None
 
297
  # try:
298
  # if isinstance(image, np.ndarray):
299
  # image = Image.fromarray(image)
300
- # dogs = await detect_multiple_dogs(image, conf_threshold=0.25, iou_threshold=0.4)
301
-
302
- # if len(dogs) <= 1:
303
- # return await process_single_dog(image)
304
 
305
  # color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
306
  # explanations = []
@@ -308,26 +312,28 @@ async def process_single_dog(image):
308
  # annotated_image = image.copy()
309
  # draw = ImageDraw.Draw(annotated_image)
310
  # font = ImageFont.load_default()
311
-
312
- # for i, (cropped_image, _, box) in enumerate(dogs):
313
  # top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
314
  # color = color_list[i % len(color_list)]
315
  # draw.rectangle(box, outline=color, width=3)
316
  # draw.text((box[0], box[1]), f"Dog {i+1}", fill=color, font=font)
317
-
318
- # breed = topk_breeds[0]
 
319
  # if top1_prob >= 0.5:
 
320
  # description = get_dog_description(breed)
321
  # formatted_description = format_description(description, breed)
322
  # explanations.append(f"Dog {i+1}: {formatted_description}")
323
- # elif top1_prob >= 0.2:
324
  # dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
325
  # dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
326
  # explanations.append(dog_explanation)
327
- # buttons.extend([gr.update(visible=True, value=f"Dog {i+1}: More about {breed}") for breed in topk_breeds[:3]])
328
  # else:
329
- # explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset.")
330
-
331
  # final_explanation = "\n\n".join(explanations)
332
  # if buttons:
333
  # final_explanation += "\n\nClick on a button to view more information about the breed."
@@ -336,111 +342,25 @@ async def process_single_dog(image):
336
  # "buttons": buttons,
337
  # "show_back": True,
338
  # "image": annotated_image,
339
- # "is_multi_dog": True,
340
  # "dogs_info": explanations
341
  # }
342
- # return (final_explanation, annotated_image,
343
- # buttons[0] if len(buttons) > 0 else gr.update(visible=False),
344
- # buttons[1] if len(buttons) > 1 else gr.update(visible=False),
345
- # buttons[2] if len(buttons) > 2 else gr.update(visible=False),
346
- # gr.update(visible=True),
347
- # initial_state)
348
  # else:
349
  # initial_state = {
350
  # "explanation": final_explanation,
351
  # "buttons": [],
352
  # "show_back": False,
353
  # "image": annotated_image,
354
- # "is_multi_dog": True,
355
  # "dogs_info": explanations
356
  # }
357
- # return final_explanation, annotated_image, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), initial_state
358
- # except Exception as e:
359
- # error_msg = f"An error occurred: {str(e)}"
360
- # print(error_msg) # 添加日誌輸出
361
- # return error_msg, None, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), None
362
-
363
 
364
- # def show_details(choice, previous_output, initial_state):
365
- # if not choice:
366
- # return previous_output, gr.update(visible=True), initial_state
367
-
368
- # try:
369
- # breed = choice.split("More about ")[-1]
370
- # description = get_dog_description(breed)
371
- # formatted_description = format_description(description, breed)
372
-
373
- # # 保存當前描述和原始按鈕狀態
374
- # initial_state["current_description"] = formatted_description
375
- # initial_state["original_buttons"] = initial_state.get("buttons", [])
376
-
377
- # return formatted_description, gr.update(visible=True), initial_state
378
  # except Exception as e:
379
- # error_msg = f"An error occurred while showing details: {e}"
380
  # print(error_msg)
381
- # return error_msg, gr.update(visible=True), initial_state
382
-
383
- # def go_back(state):
384
- # buttons = state.get("buttons", [])
385
- # return (
386
- # state["explanation"],
387
- # state["image"],
388
- # buttons[0] if len(buttons) > 0 else gr.update(visible=False),
389
- # buttons[1] if len(buttons) > 1 else gr.update(visible=False),
390
- # buttons[2] if len(buttons) > 2 else gr.update(visible=False),
391
- # gr.update(visible=False), # 隱藏 back 按鈕
392
- # state
393
- # )
394
-
395
- # with gr.Blocks() as iface:
396
- # gr.HTML("<h1 style='text-align: center;'>🐶 Dog Breed Classifier 🔍</h1>")
397
- # gr.HTML("<p style='text-align: center;'>Upload a picture of a dog, and the model will predict its breed, provide detailed information, and include an extra information link!</p>")
398
-
399
- # with gr.Row():
400
- # input_image = gr.Image(label="Upload a dog image", type="pil")
401
- # output_image = gr.Image(label="Annotated Image")
402
-
403
- # output = gr.Markdown(label="Prediction Results")
404
-
405
- # with gr.Row():
406
- # btn1 = gr.Button("View More 1", visible=False)
407
- # btn2 = gr.Button("View More 2", visible=False)
408
- # btn3 = gr.Button("View More 3", visible=False)
409
-
410
- # back_button = gr.Button("Back", visible=False)
411
-
412
- # initial_state = gr.State()
413
-
414
- # input_image.change(
415
- # predict,
416
- # inputs=input_image,
417
- # outputs=[output, output_image, btn1, btn2, btn3, back_button, initial_state]
418
- # )
419
-
420
- # for btn in [btn1, btn2, btn3]:
421
- # btn.click(
422
- # show_details,
423
- # inputs=[btn, output, initial_state],
424
- # outputs=[output, back_button, initial_state]
425
- # )
426
-
427
- # back_button.click(
428
- # go_back,
429
- # inputs=[initial_state],
430
- # outputs=[output, output_image, btn1, btn2, btn3, back_button, initial_state]
431
- # )
432
-
433
- # gr.Examples(
434
- # examples=['Border_Collie.jpg', 'Golden_Retriever.jpeg', 'Saint_Bernard.jpeg', 'French_Bulldog.jpeg', 'Samoyed.jpg'],
435
- # inputs=input_image
436
- # )
437
-
438
- # gr.HTML('For more details on this project and other work, feel free to visit my GitHub <a href="https://github.com/Eric-Chung-0511/Learning-Record/tree/main/Data%20Science%20Projects/Dog_Breed_Classifier">Dog Breed Classifier</a>')
439
-
440
- # if __name__ == "__main__":
441
- # iface.launch()
442
-
443
-
444
 
445
  async def predict(image):
446
  if image is None:
@@ -463,7 +383,9 @@ async def predict(image):
463
  top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
464
  color = color_list[i % len(color_list)]
465
  draw.rectangle(box, outline=color, width=3)
466
- draw.text((box[0], box[1]), f"Dog {i+1}", fill=color, font=font)
 
 
467
 
468
  combined_confidence = detection_confidence * top1_prob
469
 
@@ -471,14 +393,23 @@ async def predict(image):
471
  breed = topk_breeds[0]
472
  description = get_dog_description(breed)
473
  formatted_description = format_description(description, breed)
474
- explanations.append(f"Dog {i+1}: {formatted_description}")
 
 
 
475
  elif combined_confidence >= 0.2:
476
- dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
 
 
 
477
  dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
478
  explanations.append(dog_explanation)
479
- buttons.extend([f"Dog {i+1}: More about {breed}" for breed in topk_breeds[:3]])
480
  else:
481
- explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset. Please upload a clearer image.")
 
 
 
482
 
483
  final_explanation = "\n\n".join(explanations)
484
  if buttons:
 
153
 
154
  return formatted_description
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
  async def predict_single_dog(image):
158
  image_tensor = preprocess_image(image)
 
167
  return top1_prob, topk_breeds, topk_probs_percent
168
 
169
 
170
+ # async def detect_multiple_dogs(image, conf_threshold=0.25, iou_threshold=0.4):
171
+ # results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
172
+ # dogs = []
173
+ # boxes = []
174
+ # for box in results.boxes:
175
+ # if box.cls == 16: # COCO dataset class for dog is 16
176
+ # xyxy = box.xyxy[0].tolist()
177
+ # confidence = box.conf.item()
178
+ # boxes.append((xyxy, confidence))
179
+
180
+ # if not boxes:
181
+ # dogs.append((image, 1.0, [0, 0, image.width, image.height]))
182
+ # else:
183
+ # nms_boxes = non_max_suppression(boxes, iou_threshold)
184
+
185
+ # for box, confidence in nms_boxes:
186
+ # x1, y1, x2, y2 = box
187
+ # w, h = x2 - x1, y2 - y1
188
+ # x1 = max(0, x1 - w * 0.05)
189
+ # y1 = max(0, y1 - h * 0.05)
190
+ # x2 = min(image.width, x2 + w * 0.05)
191
+ # y2 = min(image.height, y2 + h * 0.05)
192
+ # cropped_image = image.crop((x1, y1, x2, y2))
193
+ # dogs.append((cropped_image, confidence, [x1, y1, x2, y2]))
194
+
195
+ # return dogs
196
+
197
  async def detect_multiple_dogs(image, conf_threshold=0.25, iou_threshold=0.4):
198
  results = model_yolo(image, conf=conf_threshold, iou=iou_threshold)[0]
199
  dogs = []
 
212
  for box, confidence in nms_boxes:
213
  x1, y1, x2, y2 = box
214
  w, h = x2 - x1, y2 - y1
215
+ x1 = max(0, x1 - w * 0.1)
216
+ y1 = max(0, y1 - h * 0.1)
217
+ x2 = min(image.width, x2 + w * 0.1)
218
+ y2 = min(image.height, y2 + h * 0.1)
219
  cropped_image = image.crop((x1, y1, x2, y2))
220
  dogs.append((cropped_image, confidence, [x1, y1, x2, y2]))
221
 
222
+ # 如果只检测到一只狗,但置信度较低,添加整张图片作为备选
223
+ if len(dogs) == 1 and dogs[0][1] < 0.5:
224
+ dogs.append((image, 1.0, [0, 0, image.width, image.height]))
225
+
226
  return dogs
227
 
228
  def non_max_suppression(boxes, iou_threshold):
 
295
  }
296
  return explanation, image, buttons[0], buttons[1], buttons[2], gr.update(visible=True), initial_state
297
 
298
+
299
  # async def predict(image):
300
  # if image is None:
301
+ # return "Please upload an image to start.", None, gr.update(visible=False, choices=[]), None
302
+
303
  # try:
304
  # if isinstance(image, np.ndarray):
305
  # image = Image.fromarray(image)
306
+
307
+ # dogs = await detect_multiple_dogs(image)
 
 
308
 
309
  # color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
310
  # explanations = []
 
312
  # annotated_image = image.copy()
313
  # draw = ImageDraw.Draw(annotated_image)
314
  # font = ImageFont.load_default()
315
+
316
+ # for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
317
  # top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
318
  # color = color_list[i % len(color_list)]
319
  # draw.rectangle(box, outline=color, width=3)
320
  # draw.text((box[0], box[1]), f"Dog {i+1}", fill=color, font=font)
321
+
322
+ # combined_confidence = detection_confidence * top1_prob
323
+
324
  # if top1_prob >= 0.5:
325
+ # breed = topk_breeds[0]
326
  # description = get_dog_description(breed)
327
  # formatted_description = format_description(description, breed)
328
  # explanations.append(f"Dog {i+1}: {formatted_description}")
329
+ # elif combined_confidence >= 0.2:
330
  # dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
331
  # dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
332
  # explanations.append(dog_explanation)
333
+ # buttons.extend([f"Dog {i+1}: More about {breed}" for breed in topk_breeds[:3]])
334
  # else:
335
+ # explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset. Please upload a clearer image.")
336
+
337
  # final_explanation = "\n\n".join(explanations)
338
  # if buttons:
339
  # final_explanation += "\n\nClick on a button to view more information about the breed."
 
342
  # "buttons": buttons,
343
  # "show_back": True,
344
  # "image": annotated_image,
345
+ # "is_multi_dog": len(dogs) > 1,
346
  # "dogs_info": explanations
347
  # }
348
+ # return final_explanation, annotated_image, gr.update(visible=True, choices=buttons), initial_state
 
 
 
 
 
349
  # else:
350
  # initial_state = {
351
  # "explanation": final_explanation,
352
  # "buttons": [],
353
  # "show_back": False,
354
  # "image": annotated_image,
355
+ # "is_multi_dog": len(dogs) > 1,
356
  # "dogs_info": explanations
357
  # }
358
+ # return final_explanation, annotated_image, gr.update(visible=False, choices=[]), initial_state
 
 
 
 
 
359
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
  # except Exception as e:
361
+ # error_msg = f"An error occurred: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
362
  # print(error_msg)
363
+ # return error_msg, None, gr.update(visible=False, choices=[]), None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
  async def predict(image):
366
  if image is None:
 
383
  top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
384
  color = color_list[i % len(color_list)]
385
  draw.rectangle(box, outline=color, width=3)
386
+
387
+ if len(dogs) > 1:
388
+ draw.text((box[0], box[1]), f"Dog {i+1}", fill=color, font=font)
389
 
390
  combined_confidence = detection_confidence * top1_prob
391
 
 
393
  breed = topk_breeds[0]
394
  description = get_dog_description(breed)
395
  formatted_description = format_description(description, breed)
396
+ if len(dogs) == 1:
397
+ explanations.append(f"Breed: {breed}\n{formatted_description}")
398
+ else:
399
+ explanations.append(f"Dog {i+1}: Breed: {breed}\n{formatted_description}")
400
  elif combined_confidence >= 0.2:
401
+ if len(dogs) == 1:
402
+ dog_explanation = f"Top 3 possible breeds:\n"
403
+ else:
404
+ dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
405
  dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
406
  explanations.append(dog_explanation)
407
+ buttons.extend([f"{'Dog ' + str(i+1) + ': ' if len(dogs) > 1 else ''}More about {breed}" for breed in topk_breeds[:3]])
408
  else:
409
+ if len(dogs) == 1:
410
+ explanations.append("The image is unclear or the breed is not in the dataset. Please upload a clearer image.")
411
+ else:
412
+ explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset. Please upload a clearer image.")
413
 
414
  final_explanation = "\n\n".join(explanations)
415
  if buttons: