DawnC commited on
Commit
ccffdae
1 Parent(s): 2ed0708

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +233 -236
app.py CHANGED
@@ -435,9 +435,9 @@ async def predict(image):
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()
442
  draw = ImageDraw.Draw(annotated_image)
443
 
@@ -601,224 +601,236 @@ async def predict(image):
601
  dogs_info += '</div>'
602
 
603
  html_output = f"""
604
- <style>
605
- .dog-info-card {{
606
- border: 1px solid #e1e4e8;
607
- margin: 32px 0;
608
- padding: 0;
609
- border-radius: 12px;
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 {{
617
- box-shadow: 0 4px 16px rgba(0,0,0,0.12);
618
- }}
619
-
620
- .dog-info-header {{
621
- padding: 20px 24px;
622
- margin: 0;
623
- font-size: 22px;
624
- font-weight: bold;
625
- border-bottom: 1px solid #e1e4e8;
626
- }}
627
-
628
- .breed-info {{
629
- padding: 24px;
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;
739
- margin-bottom: 20px;
740
- color: #495057;
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
- """
808
-
809
- initial_state = {
810
- "dogs_info": dogs_info,
811
- "image": annotated_image,
812
- "is_multi_dog": len(dogs) > 1,
813
- "html_output": html_output
814
- }
815
-
816
- return html_output, annotated_image, initial_state
817
-
818
- except Exception as e:
819
- error_msg = f"An error occurred: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
820
- print(error_msg)
821
- return error_msg, None, None
 
 
 
 
 
 
 
 
 
 
 
 
822
 
823
 
824
 
@@ -851,21 +863,6 @@ def show_details_html(choice, previous_output, initial_state):
851
  return f"<p style='color: red;'>{error_msg}</p>", gr.update(visible=True), initial_state
852
 
853
 
854
- # def format_description_html(description, breed):
855
- # html = "<ul style='list-style-type: none; padding-left: 0;'>"
856
- # if isinstance(description, dict):
857
- # for key, value in description.items():
858
- # html += f"<li style='margin-bottom: 10px;'><strong>{key}:</strong> {value}</li>"
859
- # elif isinstance(description, str):
860
- # html += f"<li>{description}</li>"
861
- # else:
862
- # html += f"<li>No description available for {breed}</li>"
863
- # html += "</ul>"
864
- # akc_link = get_akc_breeds_link(breed)
865
- # html += f'<p><a href="{akc_link}" target="_blank">Learn more about {breed} on the AKC website</a></p>'
866
- # return html
867
-
868
-
869
  def format_description_html(description, breed):
870
  html = "<ul style='list-style-type: none; padding-left: 0;'>"
871
  if isinstance(description, dict):
 
435
  image = Image.fromarray(image)
436
 
437
  dogs = await detect_multiple_dogs(image)
438
+ # 更新顏色組合
439
+ single_dog_color = '#34C759' # 清爽的綠色作為單狗顏色
440
+ color_list = ['#007AFF', '#FF9500', '#5856D6', '#34C759', '#5AC8FA', '#FF3B30', '#9C6ADE'] # 保留藍色但改用不同色調
441
  annotated_image = image.copy()
442
  draw = ImageDraw.Draw(annotated_image)
443
 
 
601
  dogs_info += '</div>'
602
 
603
  html_output = f"""
604
+ <style>
605
+ .dog-info-card {{
606
+ border: 1px solid #e1e4e8;
607
+ margin: 32px 0;
608
+ padding: 0;
609
+ border-radius: 12px;
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 {{
617
+ box-shadow: 0 4px 16px rgba(0,0,0,0.12);
618
+ }}
619
+
620
+ .dog-info-header {{
621
+ padding: 20px 24px;
622
+ margin: 0;
623
+ font-size: 22px;
624
+ font-weight: bold;
625
+ border-bottom: 1px solid #e1e4e8;
626
+ }}
627
+
628
+ .breed-info {{
629
+ padding: 24px;
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
+ color: #444;
686
+ }}
687
+
688
+ .description-section {{
689
+ background: #f8f9fa;
690
+ padding: 16px;
691
+ border-radius: 8px;
692
+ margin: 20px 0;
693
+ line-height: 1.8;
694
+ color: #444;
695
+ }}
696
+
697
+ .action-section {{
698
+ margin-top: 24px;
699
+ text-align: center;
700
+ }}
701
+
702
+ .akc-button {{
703
+ display: inline-flex;
704
+ align-items: center;
705
+ padding: 12px 24px;
706
+ background-color: #4A90E2;
707
+ color: white;
708
+ border-radius: 8px;
709
+ text-decoration: none;
710
+ gap: 8px;
711
+ transition: all 0.3s ease;
712
+ font-weight: 500;
713
+ }}
714
+
715
+ .akc-button:hover {{
716
+ background-color: #357ABD;
717
+ transform: translateY(-1px);
718
+ color: white;
719
+ }}
720
+
721
+ .warning-message {{
722
+ display: flex;
723
+ align-items: center;
724
+ gap: 8px;
725
+ color: #ff3b30;
726
+ font-weight: 500;
727
+ margin: 0;
728
+ padding: 16px;
729
+ background: #fff5f5;
730
+ border-radius: 8px;
731
+ }}
732
+
733
+ .model-uncertainty-note {{
734
+ display: flex;
735
+ align-items: center;
736
+ gap: 12px;
737
+ padding: 16px;
738
+ background-color: #f8f9fa;
739
+ border-left: 4px solid #6c757d;
740
+ margin-bottom: 20px;
741
+ color: #495057;
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
+
806
+ .akc-link {{
807
+ color: #4A90E2;
808
+ text-decoration: none;
809
+ font-weight: 500;
810
+ transition: all 0.3s ease;
811
+ }}
812
+
813
+ .akc-link:hover {{
814
+ text-decoration: underline;
815
+ color: #357ABD;
816
+ }}
817
+ </style>
818
+ {dogs_info}
819
+ """
820
+
821
+ initial_state = {
822
+ "dogs_info": dogs_info,
823
+ "image": annotated_image,
824
+ "is_multi_dog": len(dogs) > 1,
825
+ "html_output": html_output
826
+ }
827
+
828
+ return html_output, annotated_image, initial_state
829
+
830
+ except Exception as e:
831
+ error_msg = f"An error occurred: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
832
+ print(error_msg)
833
+ return error_msg, None, None
834
 
835
 
836
 
 
863
  return f"<p style='color: red;'>{error_msg}</p>", gr.update(visible=True), initial_state
864
 
865
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
866
  def format_description_html(description, breed):
867
  html = "<ul style='list-style-type: none; padding-left: 0;'>"
868
  if isinstance(description, dict):