feat: visual emotion recognition agent #54

Merged
s.o.h.luijkx merged 27 commits from feat/visual-emotion-recognition into main 2026-01-30 16:53:16 +00:00
Showing only changes of commit 35ffd33968 - Show all commits

View File

@@ -64,6 +64,8 @@ class VisualEmotionRecognitionAgent(BaseAgent):
self.video_in_socket = azmq.Context.instance().socket(zmq.SUB)
self.video_in_socket.setsockopt(zmq.RCVHWM, 3)
if self.socket_bind:
self.video_in_socket.bind(self.socket_address)
else:
@@ -71,7 +73,6 @@ class VisualEmotionRecognitionAgent(BaseAgent):
self.video_in_socket.setsockopt_string(zmq.SUBSCRIBE, "")
self.video_in_socket.setsockopt(zmq.RCVTIMEO, self.timeout_ms)
self.video_in_socket.setsockopt(zmq.CONFLATE, 1)
self.add_behavior(self.emotion_update_loop())
@@ -95,21 +96,18 @@ class VisualEmotionRecognitionAgent(BaseAgent):
try:
await self._paused.wait()
frame_bytes = await self.video_in_socket.recv()
width, height, image_bytes = await self.video_in_socket.recv_multipart()
width = int.from_bytes(width, 'little')
height = int.from_bytes(height, 'little')
# Convert bytes to a numpy buffer
nparr = np.frombuffer(frame_bytes, np.uint8)
image_array = np.frombuffer(image_bytes, np.uint8)
# Decode image into the generic Numpy Array DeepFace expects
frame_image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if frame_image is None:
# Could not decode image, skip this frame
self.logger.warning("Received invalid video frame, skipping.")
continue
frame = image_array.reshape((height, width, 3))
# Get the dominant emotion from each face
current_emotions = self.emotion_recognizer.sorted_dominant_emotions(frame_image)
current_emotions = self.emotion_recognizer.sorted_dominant_emotions(frame)
# Update emotion counts for each detected face
for i, emotion in enumerate(current_emotions):
face_stats[i][emotion] += 1
@@ -133,6 +131,9 @@ class VisualEmotionRecognitionAgent(BaseAgent):
except zmq.Again:
self.logger.warning("No video frame received within timeout.")
except Exception as e:
self.logger.error(f"Error in emotion recognition loop: {e}")
async def update_emotions(self, prev_emotions: set[str], emotions: set[str]):
"""