Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
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 = '#
|
440 |
-
color_list = ['#
|
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 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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):
|