- handler.py +32 -6
handler.py
CHANGED
|
@@ -154,6 +154,14 @@ class EndpointHandler:
|
|
| 154 |
def _detect_faces_and_emotions(self, video_path: str) -> Dict:
|
| 155 |
emotions_data = []
|
| 156 |
output_video_path = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
try:
|
| 158 |
# Create a temporary file for the output video
|
| 159 |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as temp_out_video:
|
|
@@ -162,6 +170,8 @@ class EndpointHandler:
|
|
| 162 |
original_video = VideoFileClip(video_path)
|
| 163 |
cap = cv2.VideoCapture(video_path)
|
| 164 |
fps = int(cap.get(cv2.CAP_PROP_FPS))
|
|
|
|
|
|
|
| 165 |
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 166 |
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 167 |
|
|
@@ -179,17 +189,33 @@ class EndpointHandler:
|
|
| 179 |
time_seconds = round(frame_number / fps)
|
| 180 |
result = self.face_detector.detect_emotions(frame)
|
| 181 |
|
|
|
|
| 182 |
for face in result:
|
| 183 |
-
|
|
|
|
|
|
|
| 184 |
emotions = face["emotions"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
emotions["Time(s)"] = time_seconds
|
| 186 |
emotions_data.append(emotions)
|
| 187 |
cv2.rectangle(frame, (box[0], box[1]), (box[0] + box[2], box[1] + box[3]), (0, 155, 255), 2)
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
|
|
|
|
|
|
|
|
|
| 193 |
out.write(frame)
|
| 194 |
frame_number += 1
|
| 195 |
|
|
|
|
| 154 |
def _detect_faces_and_emotions(self, video_path: str) -> Dict:
|
| 155 |
emotions_data = []
|
| 156 |
output_video_path = None
|
| 157 |
+
|
| 158 |
+
# ===================================================================
|
| 159 |
+
# NEW: Confidence threshold for filtering false positives.
|
| 160 |
+
# Only faces where at least one emotion has a score > 0.35 will be kept.
|
| 161 |
+
# You can adjust this value. Higher = stricter filtering. (e.g., 0.40)
|
| 162 |
+
# ===================================================================
|
| 163 |
+
CONFIDENCE_THRESHOLD = 0.35
|
| 164 |
+
|
| 165 |
try:
|
| 166 |
# Create a temporary file for the output video
|
| 167 |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as temp_out_video:
|
|
|
|
| 170 |
original_video = VideoFileClip(video_path)
|
| 171 |
cap = cv2.VideoCapture(video_path)
|
| 172 |
fps = int(cap.get(cv2.CAP_PROP_FPS))
|
| 173 |
+
if fps == 0: # Handle potential issue with video metadata
|
| 174 |
+
fps = 30
|
| 175 |
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 176 |
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 177 |
|
|
|
|
| 189 |
time_seconds = round(frame_number / fps)
|
| 190 |
result = self.face_detector.detect_emotions(frame)
|
| 191 |
|
| 192 |
+
# Process each face found in the frame
|
| 193 |
for face in result:
|
| 194 |
+
# ===================================================================
|
| 195 |
+
# NEW: Filtering logic starts here
|
| 196 |
+
# ===================================================================
|
| 197 |
emotions = face["emotions"]
|
| 198 |
+
max_emotion_score = max(emotions.values())
|
| 199 |
+
|
| 200 |
+
# If the highest emotion score is below our threshold, skip this face
|
| 201 |
+
if max_emotion_score < CONFIDENCE_THRESHOLD:
|
| 202 |
+
continue # Ignore this low-confidence detection
|
| 203 |
+
# ===================================================================
|
| 204 |
+
# End of new filtering logic. The rest of the loop proceeds as before.
|
| 205 |
+
# ===================================================================
|
| 206 |
+
|
| 207 |
+
box = face["box"]
|
| 208 |
emotions["Time(s)"] = time_seconds
|
| 209 |
emotions_data.append(emotions)
|
| 210 |
cv2.rectangle(frame, (box[0], box[1]), (box[0] + box[2], box[1] + box[3]), (0, 155, 255), 2)
|
| 211 |
+
|
| 212 |
+
# Find the dominant emotion to display on the video
|
| 213 |
+
dominant_emotion = max(emotions, key=lambda k: emotions[k] if k != 'Time(s)' else -1)
|
| 214 |
+
text_to_display = f"{dominant_emotion}: {emotions[dominant_emotion]:.2f}"
|
| 215 |
+
|
| 216 |
+
cv2.putText(frame, text_to_display, (box[0], box[1] - 10),
|
| 217 |
+
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2, cv2.LINE_AA)
|
| 218 |
+
|
| 219 |
out.write(frame)
|
| 220 |
frame_number += 1
|
| 221 |
|