DawnC commited on
Commit
196f0d8
1 Parent(s): b1b36ea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +217 -45
app.py CHANGED
@@ -296,41 +296,135 @@ async def detect_multiple_dogs(image, conf_threshold=0.2, iou_threshold=0.5):
296
  return dogs
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), gr.update(visible=False), gr.update(visible=False)
302
 
303
  try:
304
  if isinstance(image, np.ndarray):
305
  image = Image.fromarray(image)
306
 
307
- # 嘗試檢測多隻狗
308
- dogs = await detect_multiple_dogs(image)
309
- if len(dogs) == 0:
310
- # 單狗情境
311
- top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(image)
312
- if top1_prob < 0.2:
313
- return "The image is unclear or the breed is not in the dataset. Please upload a clearer image of a dog.", None, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
314
-
315
- breed = topk_breeds[0]
316
- description = get_dog_description(breed)
317
-
318
- if top1_prob >= 0.5:
319
- formatted_description = format_description(description, breed)
320
- return formatted_description, image, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
321
- else:
322
- explanation = (
323
- f"The model couldn't confidently identify the breed. Here are the top 3 possible breeds:\n\n"
324
- f"1. **{topk_breeds[0]}** ({topk_probs_percent[0]} confidence)\n"
325
- f"2. **{topk_breeds[1]}** ({topk_probs_percent[1]} confidence)\n"
326
- f"3. **{topk_breeds[2]}** ({topk_probs_percent[2]} confidence)\n\n"
327
- "Click on a button to view more information about the breed."
328
- )
329
- return explanation, image, gr.update(visible=True, value=f"More about {topk_breeds[0]}"), gr.update(visible=True, value=f"More about {topk_breeds[1]}"), gr.update(visible=True, value=f"More about {topk_breeds[2]}")
330
 
331
  # 多狗情境
332
  color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
333
  explanations = []
 
334
  annotated_image = image.copy()
335
  draw = ImageDraw.Draw(annotated_image)
336
  font = ImageFont.load_default()
@@ -347,31 +441,96 @@ async def predict(image):
347
  formatted_description = format_description(description, breed)
348
  explanations.append(f"Dog {i+1}: {formatted_description}")
349
  elif top1_prob >= 0.2:
350
- explanations.append(f"Dog {i+1}: Top 3 possible breeds:\n"
351
- f"1. **{topk_breeds[0]}** ({topk_probs_percent[0]} confidence)\n"
352
- f"2. **{topk_breeds[1]}** ({topk_probs_percent[1]} confidence)\n"
353
- f"3. **{topk_breeds[2]}** ({topk_probs_percent[2]} confidence)")
354
  else:
355
  explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset.")
356
 
357
  final_explanation = "\n\n".join(explanations)
358
- return final_explanation, annotated_image, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
 
360
  except Exception as e:
361
- return f"An error occurred: {str(e)}", None, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
362
-
363
- def show_details(choice):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  if not choice:
365
- return "Please select a breed to view details."
366
 
367
  try:
368
  breed = choice.split("More about ")[-1]
369
  description = get_dog_description(breed)
370
- return format_description(description, breed)
 
371
  except Exception as e:
372
- return f"An error occurred while showing details: {e}"
373
-
 
374
 
 
375
  with gr.Blocks() as iface:
376
  gr.HTML("<h1 style='text-align: center;'>🐶 Dog Breed Classifier 🔍</h1>")
377
  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>")
@@ -386,16 +545,33 @@ with gr.Blocks() as iface:
386
  btn1 = gr.Button("View More 1", visible=False)
387
  btn2 = gr.Button("View More 2", visible=False)
388
  btn3 = gr.Button("View More 3", visible=False)
389
-
 
 
 
 
390
  input_image.change(
391
  predict,
392
  inputs=input_image,
393
- outputs=[output, output_image, btn1, btn2, btn3]
394
  )
395
 
396
- btn1.click(show_details, inputs=btn1, outputs=output)
397
- btn2.click(show_details, inputs=btn2, outputs=output)
398
- btn3.click(show_details, inputs=btn3, outputs=output)
 
 
 
 
 
 
 
 
 
 
 
 
 
399
 
400
  gr.Examples(
401
  examples=['Border_Collie.jpg', 'Golden_Retriever.jpeg', 'Saint_Bernard.jpeg', 'French_Bulldog.jpeg', 'Samoyed.jpg'],
@@ -403,7 +579,3 @@ with gr.Blocks() as iface:
403
  )
404
 
405
  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>')
406
-
407
- if __name__ == "__main__":
408
- iface.launch()
409
-
 
296
  return dogs
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), gr.update(visible=False), gr.update(visible=False)
302
+
303
+ # try:
304
+ # if isinstance(image, np.ndarray):
305
+ # image = Image.fromarray(image)
306
+
307
+ # # 嘗試檢測多隻狗
308
+ # dogs = await detect_multiple_dogs(image)
309
+ # if len(dogs) == 0:
310
+ # # 單狗情境
311
+ # top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(image)
312
+ # if top1_prob < 0.2:
313
+ # return "The image is unclear or the breed is not in the dataset. Please upload a clearer image of a dog.", None, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
314
+
315
+ # breed = topk_breeds[0]
316
+ # description = get_dog_description(breed)
317
+
318
+ # if top1_prob >= 0.5:
319
+ # formatted_description = format_description(description, breed)
320
+ # return formatted_description, image, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
321
+ # else:
322
+ # explanation = (
323
+ # f"The model couldn't confidently identify the breed. Here are the top 3 possible breeds:\n\n"
324
+ # f"1. **{topk_breeds[0]}** ({topk_probs_percent[0]} confidence)\n"
325
+ # f"2. **{topk_breeds[1]}** ({topk_probs_percent[1]} confidence)\n"
326
+ # f"3. **{topk_breeds[2]}** ({topk_probs_percent[2]} confidence)\n\n"
327
+ # "Click on a button to view more information about the breed."
328
+ # )
329
+ # return explanation, image, gr.update(visible=True, value=f"More about {topk_breeds[0]}"), gr.update(visible=True, value=f"More about {topk_breeds[1]}"), gr.update(visible=True, value=f"More about {topk_breeds[2]}")
330
+
331
+ # # 多狗情境
332
+ # color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
333
+ # explanations = []
334
+ # annotated_image = image.copy()
335
+ # draw = ImageDraw.Draw(annotated_image)
336
+ # font = ImageFont.load_default()
337
+
338
+ # for i, (cropped_image, _, box) in enumerate(dogs):
339
+ # top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
340
+ # color = color_list[i % len(color_list)]
341
+ # draw.rectangle(box, outline=color, width=3)
342
+ # draw.text((box[0], box[1]), f"Dog {i+1}", fill=color, font=font)
343
+
344
+ # breed = topk_breeds[0]
345
+ # if top1_prob >= 0.5:
346
+ # description = get_dog_description(breed)
347
+ # formatted_description = format_description(description, breed)
348
+ # explanations.append(f"Dog {i+1}: {formatted_description}")
349
+ # elif top1_prob >= 0.2:
350
+ # explanations.append(f"Dog {i+1}: Top 3 possible breeds:\n"
351
+ # f"1. **{topk_breeds[0]}** ({topk_probs_percent[0]} confidence)\n"
352
+ # f"2. **{topk_breeds[1]}** ({topk_probs_percent[1]} confidence)\n"
353
+ # f"3. **{topk_breeds[2]}** ({topk_probs_percent[2]} confidence)")
354
+ # else:
355
+ # explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset.")
356
+
357
+ # final_explanation = "\n\n".join(explanations)
358
+ # return final_explanation, annotated_image, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
359
+
360
+ # except Exception as e:
361
+ # return f"An error occurred: {str(e)}", None, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
362
+
363
+ # def show_details(choice):
364
+ # if not choice:
365
+ # return "Please select a breed to view details."
366
+
367
+ # try:
368
+ # breed = choice.split("More about ")[-1]
369
+ # description = get_dog_description(breed)
370
+ # return format_description(description, breed)
371
+ # except Exception as e:
372
+ # return f"An error occurred while showing details: {e}"
373
+
374
+
375
+ # with gr.Blocks() as iface:
376
+ # gr.HTML("<h1 style='text-align: center;'>🐶 Dog Breed Classifier 🔍</h1>")
377
+ # 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>")
378
+
379
+ # with gr.Row():
380
+ # input_image = gr.Image(label="Upload a dog image", type="pil")
381
+ # output_image = gr.Image(label="Annotated Image")
382
+
383
+ # output = gr.Markdown(label="Prediction Results")
384
+
385
+ # with gr.Row():
386
+ # btn1 = gr.Button("View More 1", visible=False)
387
+ # btn2 = gr.Button("View More 2", visible=False)
388
+ # btn3 = gr.Button("View More 3", visible=False)
389
+
390
+ # input_image.change(
391
+ # predict,
392
+ # inputs=input_image,
393
+ # outputs=[output, output_image, btn1, btn2, btn3]
394
+ # )
395
+
396
+ # btn1.click(show_details, inputs=btn1, outputs=output)
397
+ # btn2.click(show_details, inputs=btn2, outputs=output)
398
+ # btn3.click(show_details, inputs=btn3, outputs=output)
399
+
400
+ # gr.Examples(
401
+ # examples=['Border_Collie.jpg', 'Golden_Retriever.jpeg', 'Saint_Bernard.jpeg', 'French_Bulldog.jpeg', 'Samoyed.jpg'],
402
+ # inputs=input_image
403
+ # )
404
+
405
+ # 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>')
406
+
407
+ # if __name__ == "__main__":
408
+ # iface.launch()
409
+
410
+
411
  async def predict(image):
412
  if image is None:
413
+ 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
414
 
415
  try:
416
  if isinstance(image, np.ndarray):
417
  image = Image.fromarray(image)
418
 
419
+ dogs = await detect_multiple_dogs(image, conf_threshold=0.05)
420
+
421
+ if len(dogs) <= 1:
422
+ return await process_single_dog(image)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
423
 
424
  # 多狗情境
425
  color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
426
  explanations = []
427
+ buttons = []
428
  annotated_image = image.copy()
429
  draw = ImageDraw.Draw(annotated_image)
430
  font = ImageFont.load_default()
 
441
  formatted_description = format_description(description, breed)
442
  explanations.append(f"Dog {i+1}: {formatted_description}")
443
  elif top1_prob >= 0.2:
444
+ dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
445
+ dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
446
+ explanations.append(dog_explanation)
447
+ buttons.extend([gr.update(visible=True, value=f"Dog {i+1}: More about {breed}") for breed in topk_breeds[:3]])
448
  else:
449
  explanations.append(f"Dog {i+1}: The image is unclear or the breed is not in the dataset.")
450
 
451
  final_explanation = "\n\n".join(explanations)
452
+ if buttons:
453
+ final_explanation += "\n\nClick on a button to view more information about the breed."
454
+ initial_state = {
455
+ "explanation": final_explanation,
456
+ "buttons": buttons,
457
+ "show_back": True
458
+ }
459
+ return (final_explanation, annotated_image,
460
+ buttons[0] if len(buttons) > 0 else gr.update(visible=False),
461
+ buttons[1] if len(buttons) > 1 else gr.update(visible=False),
462
+ buttons[2] if len(buttons) > 2 else gr.update(visible=False),
463
+ gr.update(visible=True),
464
+ initial_state)
465
+ else:
466
+ initial_state = {
467
+ "explanation": final_explanation,
468
+ "buttons": [],
469
+ "show_back": False
470
+ }
471
+ return final_explanation, annotated_image, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), initial_state
472
 
473
  except Exception as e:
474
+ error_msg = f"An error occurred: {str(e)}"
475
+ print(error_msg) # 添加日誌輸出
476
+ return error_msg, None, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), None
477
+
478
+ async def process_single_dog(image):
479
+ top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(image)
480
+ if top1_prob < 0.2:
481
+ initial_state = {
482
+ "explanation": "The image is unclear or the breed is not in the dataset. Please upload a clearer image of a dog.",
483
+ "buttons": [],
484
+ "show_back": False
485
+ }
486
+ return initial_state["explanation"], None, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), initial_state
487
+
488
+ breed = topk_breeds[0]
489
+ description = get_dog_description(breed)
490
+
491
+ if top1_prob >= 0.5:
492
+ formatted_description = format_description(description, breed)
493
+ initial_state = {
494
+ "explanation": formatted_description,
495
+ "buttons": [],
496
+ "show_back": False
497
+ }
498
+ return formatted_description, image, gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), initial_state
499
+ else:
500
+ explanation = (
501
+ f"The model couldn't confidently identify the breed. Here are the top 3 possible breeds:\n\n"
502
+ f"1. **{topk_breeds[0]}** ({topk_probs_percent[0]} confidence)\n"
503
+ f"2. **{topk_breeds[1]}** ({topk_probs_percent[1]} confidence)\n"
504
+ f"3. **{topk_breeds[2]}** ({topk_probs_percent[2]} confidence)\n\n"
505
+ "Click on a button to view more information about the breed."
506
+ )
507
+ buttons = [
508
+ gr.update(visible=True, value=f"More about {topk_breeds[0]}"),
509
+ gr.update(visible=True, value=f"More about {topk_breeds[1]}"),
510
+ gr.update(visible=True, value=f"More about {topk_breeds[2]}")
511
+ ]
512
+ initial_state = {
513
+ "explanation": explanation,
514
+ "buttons": buttons,
515
+ "show_back": True
516
+ }
517
+ return explanation, image, buttons[0], buttons[1], buttons[2], gr.update(visible=True), initial_state
518
+
519
+ def show_details(choice, previous_output, initial_state):
520
  if not choice:
521
+ return previous_output, gr.update(visible=True), initial_state
522
 
523
  try:
524
  breed = choice.split("More about ")[-1]
525
  description = get_dog_description(breed)
526
+ formatted_description = format_description(description, breed)
527
+ return formatted_description, gr.update(visible=True), initial_state
528
  except Exception as e:
529
+ error_msg = f"An error occurred while showing details: {e}"
530
+ print(error_msg) # 添加日誌輸出
531
+ return error_msg, gr.update(visible=True), initial_state
532
 
533
+ # 介面部分
534
  with gr.Blocks() as iface:
535
  gr.HTML("<h1 style='text-align: center;'>🐶 Dog Breed Classifier 🔍</h1>")
536
  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>")
 
545
  btn1 = gr.Button("View More 1", visible=False)
546
  btn2 = gr.Button("View More 2", visible=False)
547
  btn3 = gr.Button("View More 3", visible=False)
548
+
549
+ back_button = gr.Button("Back", visible=False)
550
+
551
+ initial_state = gr.State()
552
+
553
  input_image.change(
554
  predict,
555
  inputs=input_image,
556
+ outputs=[output, output_image, btn1, btn2, btn3, back_button, initial_state]
557
  )
558
 
559
+ for btn in [btn1, btn2, btn3]:
560
+ btn.click(
561
+ show_details,
562
+ inputs=[btn, output, initial_state],
563
+ outputs=[output, back_button, initial_state]
564
+ )
565
+
566
+ back_button.click(
567
+ lambda state: (state["explanation"],
568
+ state["buttons"][0] if len(state["buttons"]) > 0 else gr.update(visible=False),
569
+ state["buttons"][1] if len(state["buttons"]) > 1 else gr.update(visible=False),
570
+ state["buttons"][2] if len(state["buttons"]) > 2 else gr.update(visible=False),
571
+ gr.update(visible=state["show_back"])),
572
+ inputs=[initial_state],
573
+ outputs=[output, btn1, btn2, btn3, back_button]
574
+ )
575
 
576
  gr.Examples(
577
  examples=['Border_Collie.jpg', 'Golden_Retriever.jpeg', 'Saint_Bernard.jpeg', 'French_Bulldog.jpeg', 'Samoyed.jpg'],
 
579
  )
580
 
581
  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>')