DawnC commited on
Commit
2ed0708
β€’
1 Parent(s): d26da0f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +221 -62
app.py CHANGED
@@ -435,6 +435,7 @@ async def predict(image):
435
  image = Image.fromarray(image)
436
 
437
  dogs = await detect_multiple_dogs(image)
 
438
  single_dog_color = '#4A90E2' # ζŸ”ε’Œηš„θ—θ‰²
439
  color_list = ['#4A90E2', '#34C759', '#007AFF', '#5856D6', '#5AC8FA', '#FFB246', '#9C6ADE']
440
  annotated_image = image.copy()
@@ -470,6 +471,7 @@ async def predict(image):
470
  top1_prob, topk_breeds, relative_probs = await predict_single_dog(cropped_image)
471
  combined_confidence = detection_confidence * top1_prob
472
 
 
473
  dogs_info += f'<div class="dog-info-card" style="border-left: 6px solid {color};">'
474
 
475
  if combined_confidence < 0.15:
@@ -478,7 +480,10 @@ async def predict(image):
478
  <span class="dog-label" style="color: {color};">Dog {i+1}</span>
479
  </div>
480
  <div class="breed-info">
481
- <p class="warning-message">The image is unclear or the breed is not in the dataset. Please upload a clearer image.</p>
 
 
 
482
  </div>
483
  '''
484
  elif top1_prob >= 0.45:
@@ -486,46 +491,78 @@ async def predict(image):
486
  description = get_dog_description(breed)
487
  dogs_info += f'''
488
  <div class="dog-info-header" style="background-color: {color}10;">
489
- <span class="dog-label" style="color: {color};">{breed}</span>
 
 
490
  </div>
491
  <div class="breed-info">
492
- <div class="breed-details">
493
- <div class="feature-category">
494
- <div class="feature-title">Basic Information</div>
495
- <div class="basic-info">
496
- <span class="info-item"><strong>Size:</strong> {description['Size']}</span>
497
- <span class="info-item"><strong>Lifespan:</strong> {description['Lifespan']}</span>
498
- </div>
 
499
  </div>
500
-
501
- <div class="feature-category">
502
- <div class="feature-title">Temperament & Personality</div>
503
- <div class="temperament">{description['Temperament']}</div>
504
  </div>
505
-
506
- <div class="feature-category">
507
- <div class="feature-title">Care Requirements</div>
508
- <div class="care-info">
509
- <span class="info-item"><strong>Exercise Needs:</strong> {description['Exercise Needs']}</span>
510
- <span class="info-item"><strong>Grooming:</strong> {description['Grooming Needs']}</span>
511
- <span class="info-item"><strong>Care Level:</strong> {description['Care Level']}</span>
512
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
513
  </div>
514
-
515
- <div class="feature-category">
516
- <div class="feature-title">Family Compatibility</div>
517
- <div class="family-info">
518
- <span class="info-item"><strong>Good with Children:</strong> {description['Good with Children']}</span>
519
- </div>
520
  </div>
521
-
522
- <div class="feature-category">
523
- <div class="feature-title">Description</div>
524
- <div class="description">{description.get('Description', '')}</div>
 
 
 
 
 
 
525
  </div>
526
  </div>
527
- <div class="breed-footer">
528
- <a href="{get_akc_breeds_link(breed)}" target="_blank" class="akc-link">Learn more about {breed} on the AKC website</a>
 
 
 
 
 
 
 
 
 
 
 
529
  </div>
530
  </div>
531
  '''
@@ -536,23 +573,30 @@ async def predict(image):
536
  </div>
537
  <div class="breed-info">
538
  <div class="model-uncertainty-note">
 
539
  Note: The model is showing some uncertainty in its predictions.
540
  Here are the most likely breeds based on the available visual features.
541
  </div>
542
- <h3 class="breeds-title">Top 3 possible breeds:</h3>
543
  '''
544
 
545
  for j, (breed, prob) in enumerate(zip(topk_breeds, relative_probs)):
546
  description = get_dog_description(breed)
547
  dogs_info += f'''
548
- <div class="breed-section">
549
- <div class="confidence-score" style="color: {color};">{breed} (Confidence: {prob})</div>
550
- <div class="breed-info-content">
 
 
 
 
 
 
551
  {format_description_html(description, breed)}
552
  </div>
553
  </div>
554
  '''
555
- dogs_info += '</div>'
556
 
557
  dogs_info += '</div>'
558
 
@@ -566,6 +610,7 @@ async def predict(image):
566
  box-shadow: 0 2px 12px rgba(0,0,0,0.08);
567
  overflow: hidden;
568
  transition: all 0.3s ease;
 
569
  }}
570
 
571
  .dog-info-card:hover {{
@@ -585,59 +630,109 @@ async def predict(image):
585
  line-height: 1.6;
586
  }}
587
 
588
- .feature-category {{
589
- margin-bottom: 24px;
590
- }}
591
-
592
- .feature-title {{
593
- font-size: 16px;
594
- color: #666;
595
- margin-bottom: 12px;
596
- font-weight: 600;
597
  text-transform: uppercase;
598
  letter-spacing: 0.5px;
 
 
 
 
 
 
 
 
 
 
599
  }}
600
 
601
- .basic-info, .care-info, .family-info {{
602
  display: flex;
603
  flex-wrap: wrap;
604
  gap: 16px;
 
605
  }}
606
 
607
  .info-item {{
608
  background: #f8f9fa;
609
- padding: 8px 16px;
610
- border-radius: 6px;
611
- font-size: 14px;
 
 
 
 
 
 
 
 
612
  }}
613
 
614
- .temperament {{
 
 
 
 
 
 
 
 
615
  font-style: italic;
616
  color: #444;
617
  }}
618
 
619
- .description {{
 
 
 
 
620
  line-height: 1.8;
621
  color: #444;
622
  }}
623
 
624
- .breed-footer {{
625
  margin-top: 24px;
626
- padding-top: 16px;
627
- border-top: 1px solid #e1e4e8;
628
  }}
629
 
630
- .akc-link {{
631
- color: #4A90E2;
 
 
 
 
 
632
  text-decoration: none;
633
- font-weight: 500;
 
634
  }}
635
 
636
- .akc-link:hover {{
637
- text-decoration: underline;
 
 
 
 
 
 
 
 
 
 
 
 
 
638
  }}
639
 
640
  .model-uncertainty-note {{
 
 
 
641
  padding: 16px;
642
  background-color: #f8f9fa;
643
  border-left: 4px solid #6c757d;
@@ -646,6 +741,67 @@ async def predict(image):
646
  font-style: italic;
647
  border-radius: 4px;
648
  }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
649
  </style>
650
  {dogs_info}
651
  """
@@ -666,6 +822,9 @@ async def predict(image):
666
 
667
 
668
 
 
 
 
669
  def show_details_html(choice, previous_output, initial_state):
670
  if not choice:
671
  return previous_output, gr.update(visible=True), initial_state
@@ -727,7 +886,7 @@ def format_description_html(description, breed):
727
  with gr.Blocks() as iface:
728
  gr.HTML("<h1 style='text-align: center;'>🐢 Dog Breed Classifier πŸ”</h1>")
729
  gr.HTML("<p style='text-align: center;'>Upload a picture of a dog, and the model will predict its breed and provide detailed information!</p>")
730
- gr.HTML("<p style='text-align: center; color: #666; font-size: 0.9em;'>Note: This is an AI model and predictions may not always be 100% accurate. The model provides its best estimates based on training data.</p>")
731
 
732
 
733
  with gr.Row():
 
435
  image = Image.fromarray(image)
436
 
437
  dogs = await detect_multiple_dogs(image)
438
+ # ζ›΄ζŸ”ε’Œηš„ι‘θ‰²η΅„εˆ
439
  single_dog_color = '#4A90E2' # ζŸ”ε’Œηš„θ—θ‰²
440
  color_list = ['#4A90E2', '#34C759', '#007AFF', '#5856D6', '#5AC8FA', '#FFB246', '#9C6ADE']
441
  annotated_image = image.copy()
 
471
  top1_prob, topk_breeds, relative_probs = await predict_single_dog(cropped_image)
472
  combined_confidence = detection_confidence * top1_prob
473
 
474
+ # ι–‹ε§‹θ³‡θ¨Šε‘η‰‡
475
  dogs_info += f'<div class="dog-info-card" style="border-left: 6px solid {color};">'
476
 
477
  if combined_confidence < 0.15:
 
480
  <span class="dog-label" style="color: {color};">Dog {i+1}</span>
481
  </div>
482
  <div class="breed-info">
483
+ <p class="warning-message">
484
+ <span class="icon">⚠️</span>
485
+ The image is unclear or the breed is not in the dataset. Please upload a clearer image.
486
+ </p>
487
  </div>
488
  '''
489
  elif top1_prob >= 0.45:
 
491
  description = get_dog_description(breed)
492
  dogs_info += f'''
493
  <div class="dog-info-header" style="background-color: {color}10;">
494
+ <span class="dog-label" style="color: {color};">
495
+ <span class="icon">πŸ†</span> {breed}
496
+ </span>
497
  </div>
498
  <div class="breed-info">
499
+ <h2 class="section-title">
500
+ <span class="icon">πŸ“‹</span> BASIC INFORMATION
501
+ </h2>
502
+ <div class="info-section">
503
+ <div class="info-item">
504
+ <span class="icon">πŸ“</span>
505
+ <span class="label">Size:</span>
506
+ <span class="value">{description['Size']}</span>
507
  </div>
508
+ <div class="info-item">
509
+ <span class="icon">⏳</span>
510
+ <span class="label">Lifespan:</span>
511
+ <span class="value">{description['Lifespan']}</span>
512
  </div>
513
+ </div>
514
+
515
+ <h2 class="section-title">
516
+ <span class="icon">πŸ•</span> TEMPERAMENT & PERSONALITY
517
+ </h2>
518
+ <div class="temperament-section">
519
+ <span class="value">{description['Temperament']}</span>
520
+ </div>
521
+
522
+ <h2 class="section-title">
523
+ <span class="icon">πŸ’ͺ</span> CARE REQUIREMENTS
524
+ </h2>
525
+ <div class="care-section">
526
+ <div class="info-item">
527
+ <span class="icon">πŸƒ</span>
528
+ <span class="label">Exercise:</span>
529
+ <span class="value">{description['Exercise Needs']}</span>
530
+ </div>
531
+ <div class="info-item">
532
+ <span class="icon">βœ‚οΈ</span>
533
+ <span class="label">Grooming:</span>
534
+ <span class="value">{description['Grooming Needs']}</span>
535
  </div>
536
+ <div class="info-item">
537
+ <span class="icon">⭐</span>
538
+ <span class="label">Care Level:</span>
539
+ <span class="value">{description['Care Level']}</span>
 
 
540
  </div>
541
+ </div>
542
+
543
+ <h2 class="section-title">
544
+ <span class="icon">πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦</span> FAMILY COMPATIBILITY
545
+ </h2>
546
+ <div class="family-section">
547
+ <div class="info-item">
548
+ <span class="icon">πŸ‘Ά</span>
549
+ <span class="label">Good with Children:</span>
550
+ <span class="value">{description['Good with Children']}</span>
551
  </div>
552
  </div>
553
+
554
+ <h2 class="section-title">
555
+ <span class="icon">πŸ“</span> DESCRIPTION
556
+ </h2>
557
+ <div class="description-section">
558
+ <p>{description.get('Description', '')}</p>
559
+ </div>
560
+
561
+ <div class="action-section">
562
+ <a href="{get_akc_breeds_link(breed)}" target="_blank" class="akc-button">
563
+ <span class="icon">🌐</span>
564
+ Learn more about {breed} on AKC website
565
+ </a>
566
  </div>
567
  </div>
568
  '''
 
573
  </div>
574
  <div class="breed-info">
575
  <div class="model-uncertainty-note">
576
+ <span class="icon">ℹ️</span>
577
  Note: The model is showing some uncertainty in its predictions.
578
  Here are the most likely breeds based on the available visual features.
579
  </div>
580
+ <div class="breeds-list">
581
  '''
582
 
583
  for j, (breed, prob) in enumerate(zip(topk_breeds, relative_probs)):
584
  description = get_dog_description(breed)
585
  dogs_info += f'''
586
+ <div class="breed-option">
587
+ <div class="breed-header">
588
+ <span class="option-number">Option {j+1}</span>
589
+ <span class="breed-name">{breed}</span>
590
+ <span class="confidence-badge" style="background-color: {color}20; color: {color};">
591
+ Confidence: {prob}
592
+ </span>
593
+ </div>
594
+ <div class="breed-content">
595
  {format_description_html(description, breed)}
596
  </div>
597
  </div>
598
  '''
599
+ dogs_info += '</div></div>'
600
 
601
  dogs_info += '</div>'
602
 
 
610
  box-shadow: 0 2px 12px rgba(0,0,0,0.08);
611
  overflow: hidden;
612
  transition: all 0.3s ease;
613
+ background: white;
614
  }}
615
 
616
  .dog-info-card:hover {{
 
630
  line-height: 1.6;
631
  }}
632
 
633
+ .section-title {{
634
+ font-size: 1.2em;
635
+ font-weight: 700;
636
+ color: #2c3e50;
637
+ margin: 28px 0 16px 0;
638
+ padding-bottom: 8px;
639
+ border-bottom: 2px solid #e1e4e8;
 
 
640
  text-transform: uppercase;
641
  letter-spacing: 0.5px;
642
+ display: flex;
643
+ align-items: center;
644
+ gap: 8px;
645
+ }}
646
+
647
+ .icon {{
648
+ font-size: 1.2em;
649
+ display: inline-flex;
650
+ align-items: center;
651
+ justify-content: center;
652
  }}
653
 
654
+ .info-section, .care-section, .family-section {{
655
  display: flex;
656
  flex-wrap: wrap;
657
  gap: 16px;
658
+ margin-bottom: 20px;
659
  }}
660
 
661
  .info-item {{
662
  background: #f8f9fa;
663
+ padding: 12px 16px;
664
+ border-radius: 8px;
665
+ display: flex;
666
+ align-items: center;
667
+ gap: 8px;
668
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
669
+ }}
670
+
671
+ .label {{
672
+ color: #666;
673
+ font-weight: 600;
674
  }}
675
 
676
+ .value {{
677
+ color: #2c3e50;
678
+ }}
679
+
680
+ .temperament-section {{
681
+ background: #f8f9fa;
682
+ padding: 16px;
683
+ border-radius: 8px;
684
+ margin-bottom: 20px;
685
  font-style: italic;
686
  color: #444;
687
  }}
688
 
689
+ .description-section {{
690
+ background: #f8f9fa;
691
+ padding: 16px;
692
+ border-radius: 8px;
693
+ margin: 20px 0;
694
  line-height: 1.8;
695
  color: #444;
696
  }}
697
 
698
+ .action-section {{
699
  margin-top: 24px;
700
+ text-align: center;
 
701
  }}
702
 
703
+ .akc-button {{
704
+ display: inline-flex;
705
+ align-items: center;
706
+ padding: 12px 24px;
707
+ background-color: #4A90E2;
708
+ color: white;
709
+ border-radius: 8px;
710
  text-decoration: none;
711
+ gap: 8px;
712
+ transition: all 0.3s ease;
713
  }}
714
 
715
+ .akc-button:hover {{
716
+ background-color: #357ABD;
717
+ transform: translateY(-1px);
718
+ }}
719
+
720
+ .warning-message {{
721
+ display: flex;
722
+ align-items: center;
723
+ gap: 8px;
724
+ color: #ff3b30;
725
+ font-weight: 500;
726
+ margin: 0;
727
+ padding: 16px;
728
+ background: #fff5f5;
729
+ border-radius: 8px;
730
  }}
731
 
732
  .model-uncertainty-note {{
733
+ display: flex;
734
+ align-items: center;
735
+ gap: 12px;
736
  padding: 16px;
737
  background-color: #f8f9fa;
738
  border-left: 4px solid #6c757d;
 
741
  font-style: italic;
742
  border-radius: 4px;
743
  }}
744
+
745
+ .breeds-list {{
746
+ display: flex;
747
+ flex-direction: column;
748
+ gap: 20px;
749
+ }}
750
+
751
+ .breed-option {{
752
+ background: white;
753
+ border: 1px solid #e1e4e8;
754
+ border-radius: 8px;
755
+ overflow: hidden;
756
+ }}
757
+
758
+ .breed-header {{
759
+ display: flex;
760
+ align-items: center;
761
+ padding: 16px;
762
+ background: #f8f9fa;
763
+ gap: 12px;
764
+ border-bottom: 1px solid #e1e4e8;
765
+ }}
766
+
767
+ .option-number {{
768
+ font-weight: 600;
769
+ color: #666;
770
+ padding: 4px 8px;
771
+ background: #e1e4e8;
772
+ border-radius: 4px;
773
+ }}
774
+
775
+ .breed-name {{
776
+ font-size: 1.1em;
777
+ font-weight: bold;
778
+ color: #2c3e50;
779
+ flex-grow: 1;
780
+ }}
781
+
782
+ .confidence-badge {{
783
+ padding: 4px 12px;
784
+ border-radius: 20px;
785
+ font-size: 0.9em;
786
+ font-weight: 500;
787
+ }}
788
+
789
+ .breed-content {{
790
+ padding: 20px;
791
+ }}
792
+
793
+ ul {{
794
+ padding-left: 0;
795
+ margin: 0;
796
+ list-style-type: none;
797
+ }}
798
+
799
+ li {{
800
+ margin-bottom: 8px;
801
+ display: flex;
802
+ align-items: center;
803
+ gap: 8px;
804
+ }}
805
  </style>
806
  {dogs_info}
807
  """
 
822
 
823
 
824
 
825
+
826
+
827
+
828
  def show_details_html(choice, previous_output, initial_state):
829
  if not choice:
830
  return previous_output, gr.update(visible=True), initial_state
 
886
  with gr.Blocks() as iface:
887
  gr.HTML("<h1 style='text-align: center;'>🐢 Dog Breed Classifier πŸ”</h1>")
888
  gr.HTML("<p style='text-align: center;'>Upload a picture of a dog, and the model will predict its breed and provide detailed information!</p>")
889
+ gr.HTML("<p style='text-align: center; color: #666; font-size: 0.9em;'>Note: The model's predictions may not always be 100% accurate, and it is recommended to use the results as a reference.</p>")
890
 
891
 
892
  with gr.Row():