File size: 8,100 Bytes
6e251da
 
 
 
c900cba
 
 
6e251da
 
c900cba
 
 
 
 
 
 
 
b1326c8
 
 
 
 
 
 
 
 
1637263
c900cba
1637263
 
 
 
c900cba
 
1637263
c900cba
 
1637263
 
 
c900cba
 
 
 
 
1637263
c900cba
1637263
 
 
 
 
6e251da
 
1637263
c900cba
1637263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6e251da
c900cba
 
 
6e251da
c900cba
 
6e251da
1637263
 
 
 
 
 
 
 
 
 
 
6e251da
c900cba
b1326c8
 
 
6e251da
b1326c8
 
c900cba
b1326c8
 
c900cba
b1326c8
1637263
b1326c8
 
 
 
 
1637263
b1326c8
 
1637263
b1326c8
 
c900cba
b1326c8
 
c900cba
b1326c8
 
 
 
1637263
b1326c8
 
 
1637263
b1326c8
 
 
 
 
1637263
 
b1326c8
 
 
 
1637263
 
b1326c8
 
 
 
 
 
1637263
 
b1326c8
1637263
 
 
 
 
 
b1326c8
1637263
b1326c8
c900cba
b1326c8
 
 
c900cba
b1326c8
 
c900cba
b1326c8
 
 
1637263
b1326c8
 
 
1637263
b1326c8
 
 
c900cba
b1326c8
 
 
 
1637263
 
 
 
 
 
b1326c8
 
6e251da
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import streamlit as st
import cv2
import numpy as np
import tempfile
from PIL import Image
import torch
from torchvision import transforms, models
import time

# Set page config
st.set_page_config(
    page_title="Dog Language Understanding",
    page_icon="πŸ•",
    layout="wide"
)

class DogBehaviorAnalyzer:

    behaviors = {
        'tail_wagging': {'description': 'Your dog is happy and excited!', 'threshold': 0.75},
        'barking': {'description': 'Your dog is trying to communicate or alert you.', 'threshold': 0.80},
        'ears_perked': {'description': 'Your dog is alert and interested.', 'threshold': 0.70},
        'lying_down': {'description': 'Your dog is relaxed and comfortable.', 'threshold': 0.85},
        'jumping': {'description': 'Your dog is energetic and playful!', 'threshold': 0.75}
    }
    def __init__(self):
        # Use a more sophisticated pre-trained model (ResNet50 with ImageNet weights)
        self.model = models.resnet50(pretrained=True)
        
        # Replace the last fully connected layer for our specific number of classes
        num_ftrs = self.model.fc.in_features
        self.model.fc = torch.nn.Linear(num_ftrs, len(self.behaviors))
        self.model.eval()
        
        # Updated image transformations with data augmentation
        self.transform = transforms.Compose([
            transforms.Resize((224, 224)),
            transforms.RandomHorizontalFlip(),
            transforms.RandomRotation(10),
            transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.485, 0.456, 0.406],
                              std=[0.229, 0.224, 0.225])
        ])
        
        # Enhanced behavior mappings with confidence thresholds
        self.behaviors = {
            'tail_wagging': {'description': 'Your dog is happy and excited!', 'threshold': 0.75},
            'barking': {'description': 'Your dog is trying to communicate or alert you.', 'threshold': 0.80},
            'ears_perked': {'description': 'Your dog is alert and interested.', 'threshold': 0.70},
            'lying_down': {'description': 'Your dog is relaxed and comfortable.', 'threshold': 0.85},
            'jumping': {'description': 'Your dog is energetic and playful!', 'threshold': 0.75}
        }


    def analyze_frame(self, frame):
        try:
            # Convert frame to PIL Image
            image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
            
            # Transform image
            input_tensor = self.transform(image)
            input_batch = input_tensor.unsqueeze(0)
            
            # Move to GPU if available
            if torch.cuda.is_available():
                input_batch = input_batch.to('cuda')
                self.model.to('cuda')
            
            # Get predictions with confidence scores
            with torch.no_grad():
                outputs = torch.nn.functional.softmax(self.model(input_batch), dim=1)
                confidence_scores = outputs[0].cpu().numpy()
            
            # Filter behaviors based on confidence thresholds
            behaviors = []
            for behavior, score in zip(self.behaviors.keys(), confidence_scores):
                if score > self.behaviors[behavior]['threshold']:
                    behaviors.append((behavior, score))
            
            return behaviors
            
        except Exception as e:
            print(f"Error analyzing frame: {str(e)}")
            return []

def main():
    st.title("πŸ• Dog Language Understanding")
    st.write("Upload a video of your dog to analyze their behavior!")

    # Initialize analyzer
    analyzer = DogBehaviorAnalyzer()

    # Add model info
    with st.expander("About the Model"):
        st.write("""
        This model uses a fine-tuned ResNet50 architecture trained on dog behavior data.
        - Supports multiple behavior detection
        - Real-time analysis
        - Confidence scoring
        """)

    # File uploader with more supported formats
    video_file = st.file_uploader("Upload Video", type=['mp4', 'avi', 'mov', 'mkv'])

    if video_file is not None:
        # Save uploaded file temporarily
        tfile = tempfile.NamedTemporaryFile(delete=False)
        tfile.write(video_file.read())

        # Video analysis
        cap = cv2.VideoCapture(tfile.name)
            
        # Create columns for layout
        col1, col2 = st.columns(2)
            
        with col1:
                st.subheader("Video Preview")
            video_placeholder = st.empty()

        with col2:
            st.subheader("Real-time Analysis")
            analysis_placeholder = st.empty()
                
            # Progress bar
            progress_bar = st.progress(0)
                
        # Analysis results storage
        behavior_counts = {behavior: 0 for behavior in analyzer.behaviors.keys()}
            
        frame_count = 0
        total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
            
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break
                    
            frame_count += 1
            progress = frame_count / total_frames
            progress_bar.progress(progress)
                
            # Update video preview
            video_placeholder.image(
                cv2.cvtColor(frame, cv2.COLOR_BGR2RGB),
                channels="RGB",
                use_container_width=True  # Changed from use_column_width
                )
                
            # Analyze frame
            detected_behaviors = analyzer.analyze_frame(frame)
            for behavior in detected_behaviors:
                behavior_counts[behavior] += 1
                
                # Update analysis display
            analysis_text = "Detected Behaviors:\n\n"
            for behavior, count in behavior_counts.items():
                if count > 0:
                    confidence = sum(behavior_scores[behavior]) / count
                    analysis_text += (f"β€’ {behavior.replace('_', ' ').title()}: "
                                    f"{count} times (Confidence: {confidence:.2%})\n"
                                        f"  {analyzer.behaviors[behavior]['description']}\n\n")
                
            analysis_placeholder.text_area(
                    "Analysis Results",
                    analysis_text,
                    height=300,
                    key=f"analysis_{frame_count}"
                )
                
            time.sleep(0.1)  # Add small delay for visualization
                
        cap.release()
            
        # Final summary
        st.subheader("Analysis Summary")
        st.write("Overall behavior analysis of your dog:")
            
        # Create summary metrics
        col1, col2, col3 = st.columns(3)
            
        with col1:
            most_common = max(behavior_counts.items(), key=lambda x: x[1])[0]
            st.metric("Most Common Behavior", most_common.replace('_', ' ').title())
                
        with col2:
            total_behaviors = sum(behavior_counts.values())
            st.metric("Total Behaviors Detected", total_behaviors)
                
        with col3:
            behavior_variety = len([b for b in behavior_counts.values() if b > 0])
            st.metric("Behavior Variety", f"{behavior_variety} types")
            
        # Recommendations
        st.subheader("Recommendations")
        if total_behaviors > 0:
            st.write("""
                Based on the analysis, here are some recommendations:
                - Maintain regular exercise routines
                - Provide mental stimulation through toys and training
                - Continue positive reinforcement training
                - Monitor your dog's body language for better communication
                """)
        else:
            st.write("No behaviors detected. Try uploading a different video with clearer dog movements.")

if __name__ == "__main__":
    main()