DawnC commited on
Commit
ecd0d87
·
1 Parent(s): 064f508

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +190 -27
app.py CHANGED
@@ -266,6 +266,145 @@ async def process_single_dog(image):
266
  return explanation, image, buttons[0], buttons[1], buttons[2], gr.update(visible=True), initial_state
267
 
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  async def predict(image):
270
  if image is None:
271
  return "Please upload an image to start.", None, gr.update(visible=False, choices=[]), None
@@ -277,7 +416,7 @@ async def predict(image):
277
  dogs = await detect_multiple_dogs(image)
278
 
279
  color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
280
- explanations = []
281
  buttons = []
282
  annotated_image = image.copy()
283
  draw = ImageDraw.Draw(annotated_image)
@@ -287,82 +426,105 @@ async def predict(image):
287
  top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
288
  color = color_list[i % len(color_list)]
289
  draw.rectangle(box, outline=color, width=3)
290
- draw.text((box[0] + 5, box[1] + 5), f"Dog {i+1}", fill=color, font=font) # Adjust the mark place
291
-
292
 
293
  combined_confidence = detection_confidence * top1_prob
 
 
294
 
295
  if top1_prob >= 0.45:
296
  breed = topk_breeds[0]
297
  description = get_dog_description(breed)
298
- formatted_description = format_description(description, breed)
299
- explanations.append(f"Dog {i+1}: {formatted_description}")
300
  elif combined_confidence >= 0.15:
301
- dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
302
- dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
303
- explanations.append(dog_explanation)
304
- buttons.extend([f"Dog {i+1}: More about {breed}" for breed in topk_breeds[:3]])
 
 
 
 
 
 
305
  else:
306
- explanations.append(f"{i+1} The image is unclear or the breed is not in the dataset. Please upload a clearer image.")
307
-
 
308
 
309
- final_explanation = "\n\n".join(explanations)
310
  if buttons:
311
- final_explanation += "\n\nClick on a button to view more information about the breed."
312
  initial_state = {
313
- "explanation": final_explanation,
314
  "buttons": buttons,
315
  "show_back": True,
316
  "image": annotated_image,
317
  "is_multi_dog": len(dogs) > 1,
318
- "dogs_info": explanations
319
  }
320
- return final_explanation, annotated_image, gr.update(visible=True, choices=buttons), initial_state
321
  else:
322
  initial_state = {
323
- "explanation": final_explanation,
324
  "buttons": [],
325
  "show_back": False,
326
  "image": annotated_image,
327
  "is_multi_dog": len(dogs) > 1,
328
- "dogs_info": explanations
329
  }
330
- return final_explanation, annotated_image, gr.update(visible=False, choices=[]), initial_state
331
 
332
  except Exception as e:
333
  error_msg = f"An error occurred: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
334
  print(error_msg)
335
  return error_msg, None, gr.update(visible=False, choices=[]), None
336
 
337
-
338
- def show_details(choice, previous_output, initial_state):
339
  if not choice:
340
  return previous_output, gr.update(visible=True), initial_state
341
 
342
  try:
343
  breed = choice.split("More about ")[-1]
344
  description = get_dog_description(breed)
345
- formatted_description = format_description(description, breed)
 
 
 
 
 
 
 
346
 
347
- initial_state["current_description"] = formatted_description
348
  initial_state["original_buttons"] = initial_state.get("buttons", [])
349
 
350
- return formatted_description, gr.update(visible=True), initial_state
351
  except Exception as e:
352
  error_msg = f"An error occurred while showing details: {e}"
353
  print(error_msg)
354
- return error_msg, gr.update(visible=True), initial_state
 
 
 
 
 
 
 
 
 
 
355
 
356
  def go_back(state):
357
  buttons = state.get("buttons", [])
358
  return (
359
- state["explanation"],
360
  state["image"],
361
  gr.update(visible=True, choices=buttons),
362
  gr.update(visible=False),
363
  state
364
  )
365
 
 
366
  with gr.Blocks() as iface:
367
  gr.HTML("<h1 style='text-align: center;'>🐶 Dog Breed Classifier 🔍</h1>")
368
  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>")
@@ -371,7 +533,7 @@ with gr.Blocks() as iface:
371
  input_image = gr.Image(label="Upload a dog image", type="pil")
372
  output_image = gr.Image(label="Annotated Image")
373
 
374
- output = gr.Markdown(label="Prediction Results")
375
 
376
  breed_buttons = gr.Radio(choices=[], label="More Information", visible=False)
377
 
@@ -404,5 +566,6 @@ with gr.Blocks() as iface:
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()
 
266
  return explanation, image, buttons[0], buttons[1], buttons[2], gr.update(visible=True), initial_state
267
 
268
 
269
+ # async def predict(image):
270
+ # if image is None:
271
+ # return "Please upload an image to start.", None, gr.update(visible=False, choices=[]), None
272
+
273
+ # try:
274
+ # if isinstance(image, np.ndarray):
275
+ # image = Image.fromarray(image)
276
+
277
+ # dogs = await detect_multiple_dogs(image)
278
+
279
+ # color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
280
+ # explanations = []
281
+ # buttons = []
282
+ # annotated_image = image.copy()
283
+ # draw = ImageDraw.Draw(annotated_image)
284
+ # font = ImageFont.load_default()
285
+
286
+ # for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
287
+ # top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
288
+ # color = color_list[i % len(color_list)]
289
+ # draw.rectangle(box, outline=color, width=3)
290
+ # draw.text((box[0] + 5, box[1] + 5), f"Dog {i+1}", fill=color, font=font) # Adjust the mark place
291
+
292
+
293
+ # combined_confidence = detection_confidence * top1_prob
294
+
295
+ # if top1_prob >= 0.45:
296
+ # breed = topk_breeds[0]
297
+ # description = get_dog_description(breed)
298
+ # formatted_description = format_description(description, breed)
299
+ # explanations.append(f"Dog {i+1}: {formatted_description}")
300
+ # elif combined_confidence >= 0.15:
301
+ # dog_explanation = f"Dog {i+1}: Top 3 possible breeds:\n"
302
+ # dog_explanation += "\n".join([f"{j+1}. **{breed}** ({prob} confidence)" for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3]))])
303
+ # explanations.append(dog_explanation)
304
+ # buttons.extend([f"Dog {i+1}: More about {breed}" for breed in topk_breeds[:3]])
305
+ # else:
306
+ # explanations.append(f"{i+1} The image is unclear or the breed is not in the dataset. Please upload a clearer image.")
307
+
308
+
309
+ # final_explanation = "\n\n".join(explanations)
310
+ # if buttons:
311
+ # final_explanation += "\n\nClick on a button to view more information about the breed."
312
+ # initial_state = {
313
+ # "explanation": final_explanation,
314
+ # "buttons": buttons,
315
+ # "show_back": True,
316
+ # "image": annotated_image,
317
+ # "is_multi_dog": len(dogs) > 1,
318
+ # "dogs_info": explanations
319
+ # }
320
+ # return final_explanation, annotated_image, gr.update(visible=True, choices=buttons), initial_state
321
+ # else:
322
+ # initial_state = {
323
+ # "explanation": final_explanation,
324
+ # "buttons": [],
325
+ # "show_back": False,
326
+ # "image": annotated_image,
327
+ # "is_multi_dog": len(dogs) > 1,
328
+ # "dogs_info": explanations
329
+ # }
330
+ # return final_explanation, annotated_image, gr.update(visible=False, choices=[]), initial_state
331
+
332
+ # except Exception as e:
333
+ # error_msg = f"An error occurred: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
334
+ # print(error_msg)
335
+ # return error_msg, None, gr.update(visible=False, choices=[]), None
336
+
337
+
338
+ # def show_details(choice, previous_output, initial_state):
339
+ # if not choice:
340
+ # return previous_output, gr.update(visible=True), initial_state
341
+
342
+ # try:
343
+ # breed = choice.split("More about ")[-1]
344
+ # description = get_dog_description(breed)
345
+ # formatted_description = format_description(description, breed)
346
+
347
+ # initial_state["current_description"] = formatted_description
348
+ # initial_state["original_buttons"] = initial_state.get("buttons", [])
349
+
350
+ # return formatted_description, gr.update(visible=True), initial_state
351
+ # except Exception as e:
352
+ # error_msg = f"An error occurred while showing details: {e}"
353
+ # print(error_msg)
354
+ # return error_msg, gr.update(visible=True), initial_state
355
+
356
+ # def go_back(state):
357
+ # buttons = state.get("buttons", [])
358
+ # return (
359
+ # state["explanation"],
360
+ # state["image"],
361
+ # gr.update(visible=True, choices=buttons),
362
+ # gr.update(visible=False),
363
+ # state
364
+ # )
365
+
366
+ # with gr.Blocks() as iface:
367
+ # gr.HTML("<h1 style='text-align: center;'>🐶 Dog Breed Classifier 🔍</h1>")
368
+ # 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>")
369
+
370
+ # with gr.Row():
371
+ # input_image = gr.Image(label="Upload a dog image", type="pil")
372
+ # output_image = gr.Image(label="Annotated Image")
373
+
374
+ # output = gr.Markdown(label="Prediction Results")
375
+
376
+ # breed_buttons = gr.Radio(choices=[], label="More Information", visible=False)
377
+
378
+ # back_button = gr.Button("Back", visible=False)
379
+
380
+ # initial_state = gr.State()
381
+
382
+ # input_image.change(
383
+ # predict,
384
+ # inputs=input_image,
385
+ # outputs=[output, output_image, breed_buttons, initial_state]
386
+ # )
387
+
388
+ # breed_buttons.change(
389
+ # show_details,
390
+ # inputs=[breed_buttons, output, initial_state],
391
+ # outputs=[output, back_button, initial_state]
392
+ # )
393
+
394
+ # back_button.click(
395
+ # go_back,
396
+ # inputs=[initial_state],
397
+ # outputs=[output, output_image, breed_buttons, back_button, initial_state]
398
+ # )
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
+
408
  async def predict(image):
409
  if image is None:
410
  return "Please upload an image to start.", None, gr.update(visible=False, choices=[]), None
 
416
  dogs = await detect_multiple_dogs(image)
417
 
418
  color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
419
+ html_output = "<style>.dog-info{border:1px solid #ddd;margin-bottom:20px;padding:15px;border-radius:5px;box-shadow:0 2px 5px rgba(0,0,0,0.1);}.dog-info h2{background-color:#f0f0f0;padding:10px;margin:-15px -15px 15px -15px;border-radius:5px 5px 0 0;}.breed-buttons{margin-top:10px;}</style>"
420
  buttons = []
421
  annotated_image = image.copy()
422
  draw = ImageDraw.Draw(annotated_image)
 
426
  top1_prob, topk_breeds, topk_probs_percent = await predict_single_dog(cropped_image)
427
  color = color_list[i % len(color_list)]
428
  draw.rectangle(box, outline=color, width=3)
429
+ draw.text((box[0] + 5, box[1] + 5), f"Dog {i+1}", fill=color, font=font)
 
430
 
431
  combined_confidence = detection_confidence * top1_prob
432
+ html_output += f'<div class="dog-info" style="border-left: 5px solid {color};">'
433
+ html_output += f'<h2>Dog {i+1}</h2>'
434
 
435
  if top1_prob >= 0.45:
436
  breed = topk_breeds[0]
437
  description = get_dog_description(breed)
438
+ html_output += format_description_html(description, breed)
 
439
  elif combined_confidence >= 0.15:
440
+ html_output += f"<p>Top 3 possible breeds:</p><ul>"
441
+ for j, (breed, prob) in enumerate(zip(topk_breeds[:3], topk_probs_percent[:3])):
442
+ html_output += f"<li><strong>{breed}</strong> ({prob} confidence)</li>"
443
+ html_output += "</ul>"
444
+ html_output += '<div class="breed-buttons">'
445
+ for breed in topk_breeds[:3]:
446
+ button_id = f"Dog {i+1}: More about {breed}"
447
+ html_output += f'<button onclick="handle_button_click(\'{button_id}\')">{button_id}</button>'
448
+ buttons.append(button_id)
449
+ html_output += '</div>'
450
  else:
451
+ html_output += "<p>The image is unclear or the breed is not in the dataset. Please upload a clearer image.</p>"
452
+
453
+ html_output += '</div>'
454
 
 
455
  if buttons:
456
+ html_output += "<script>function handle_button_click(button_id) { document.querySelector('input[type=radio][value=\"' + button_id + '\"]').click(); }</script>"
457
  initial_state = {
458
+ "explanation": html_output,
459
  "buttons": buttons,
460
  "show_back": True,
461
  "image": annotated_image,
462
  "is_multi_dog": len(dogs) > 1,
463
+ "dogs_info": html_output
464
  }
465
+ return html_output, annotated_image, gr.update(visible=True, choices=buttons), initial_state
466
  else:
467
  initial_state = {
468
+ "explanation": html_output,
469
  "buttons": [],
470
  "show_back": False,
471
  "image": annotated_image,
472
  "is_multi_dog": len(dogs) > 1,
473
+ "dogs_info": html_output
474
  }
475
+ return html_output, annotated_image, gr.update(visible=False, choices=[]), initial_state
476
 
477
  except Exception as e:
478
  error_msg = f"An error occurred: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
479
  print(error_msg)
480
  return error_msg, None, gr.update(visible=False, choices=[]), None
481
 
482
+ def show_details_html(choice, previous_output, initial_state):
 
483
  if not choice:
484
  return previous_output, gr.update(visible=True), initial_state
485
 
486
  try:
487
  breed = choice.split("More about ")[-1]
488
  description = get_dog_description(breed)
489
+ formatted_description = format_description_html(description, breed)
490
+
491
+ html_output = f"""
492
+ <div class="dog-info">
493
+ <h2>{breed}</h2>
494
+ {formatted_description}
495
+ </div>
496
+ """
497
 
498
+ initial_state["current_description"] = html_output
499
  initial_state["original_buttons"] = initial_state.get("buttons", [])
500
 
501
+ return html_output, gr.update(visible=True), initial_state
502
  except Exception as e:
503
  error_msg = f"An error occurred while showing details: {e}"
504
  print(error_msg)
505
+ return f"<p style='color: red;'>{error_msg}</p>", gr.update(visible=True), initial_state
506
+
507
+ def format_description_html(description, breed):
508
+ html = "<ul>"
509
+ for key, value in description.items():
510
+ html += f"<li><strong>{key}:</strong> {value}</li>"
511
+ html += "</ul>"
512
+ akc_link = get_akc_breeds_link()
513
+ html += f'<p><a href="{akc_link}" target="_blank">Learn more about {breed} on the AKC website</a></p>'
514
+ return html
515
+
516
 
517
  def go_back(state):
518
  buttons = state.get("buttons", [])
519
  return (
520
+ state["dogs_info"], # 這裡應該是完整的 HTML 內容
521
  state["image"],
522
  gr.update(visible=True, choices=buttons),
523
  gr.update(visible=False),
524
  state
525
  )
526
 
527
+
528
  with gr.Blocks() as iface:
529
  gr.HTML("<h1 style='text-align: center;'>🐶 Dog Breed Classifier 🔍</h1>")
530
  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>")
 
533
  input_image = gr.Image(label="Upload a dog image", type="pil")
534
  output_image = gr.Image(label="Annotated Image")
535
 
536
+ output = gr.HTML(label="Prediction Results") # 改為 HTML 輸出
537
 
538
  breed_buttons = gr.Radio(choices=[], label="More Information", visible=False)
539
 
 
566
 
567
  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>')
568
 
569
+
570
  if __name__ == "__main__":
571
  iface.launch()