feat: face recognition agent #53
@@ -22,6 +22,7 @@ from control_backend.schemas.program import (
|
|||||||
BaseGoal,
|
BaseGoal,
|
||||||
BasicNorm,
|
BasicNorm,
|
||||||
ConditionalNorm,
|
ConditionalNorm,
|
||||||
|
EmotionBelief,
|
||||||
GestureAction,
|
GestureAction,
|
||||||
Goal,
|
Goal,
|
||||||
InferredBelief,
|
InferredBelief,
|
||||||
@@ -459,6 +460,10 @@ class AgentSpeakGenerator:
|
|||||||
@_astify.register
|
@_astify.register
|
||||||
def _(self, sb: SemanticBelief) -> AstExpression:
|
def _(self, sb: SemanticBelief) -> AstExpression:
|
||||||
return AstLiteral(self.slugify(sb))
|
return AstLiteral(self.slugify(sb))
|
||||||
|
|
||||||
|
@_astify.register
|
||||||
|
def _(self, eb: EmotionBelief) -> AstExpression:
|
||||||
|
return AstLiteral("emotion_detected", [AstAtom(eb.emotion)])
|
||||||
|
|
||||||
@_astify.register
|
@_astify.register
|
||||||
def _(self, ib: InferredBelief) -> AstExpression:
|
def _(self, ib: InferredBelief) -> AstExpression:
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class VisualEmotionRecognitionAgent(BaseAgent):
|
|||||||
"""
|
"""
|
||||||
Retrieve a video frame from the input socket.
|
Retrieve a video frame from the input socket.
|
||||||
"""
|
"""
|
||||||
window_duration = 1 # seconds
|
window_duration = 5 # seconds
|
||||||
next_window_time = time.time() + window_duration
|
next_window_time = time.time() + window_duration
|
||||||
|
|
||||||
# To detect false positives
|
# To detect false positives
|
||||||
@@ -82,7 +82,7 @@ class VisualEmotionRecognitionAgent(BaseAgent):
|
|||||||
|
|
||||||
# If window duration has passed, process the collected stats
|
# If window duration has passed, process the collected stats
|
||||||
if time.time() >= next_window_time:
|
if time.time() >= next_window_time:
|
||||||
|
print(face_stats)
|
||||||
window_dominant_emotions = set()
|
window_dominant_emotions = set()
|
||||||
# Determine dominant emotion for each face in the window
|
# Determine dominant emotion for each face in the window
|
||||||
for _, counter in face_stats.items():
|
for _, counter in face_stats.items():
|
||||||
@@ -116,7 +116,7 @@ class VisualEmotionRecognitionAgent(BaseAgent):
|
|||||||
for emotion in emotions_to_remove:
|
for emotion in emotions_to_remove:
|
||||||
self.logger.info(f"Emotion '{emotion}' has disappeared.")
|
self.logger.info(f"Emotion '{emotion}' has disappeared.")
|
||||||
try:
|
try:
|
||||||
emotion_beliefs_remove.append(Belief(name="emotion", arguments=[emotion], remove=True))
|
emotion_beliefs_remove.append(Belief(name="emotion_detected", arguments=[emotion], remove=True))
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
self.logger.warning("Invalid belief for emotion removal: %s", emotion)
|
self.logger.warning("Invalid belief for emotion removal: %s", emotion)
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ class VisualEmotionRecognitionAgent(BaseAgent):
|
|||||||
for emotion in emotions_to_add:
|
for emotion in emotions_to_add:
|
||||||
self.logger.info(f"New emotion detected: '{emotion}'")
|
self.logger.info(f"New emotion detected: '{emotion}'")
|
||||||
try:
|
try:
|
||||||
emotion_beliefs_add.append(Belief(name="emotion", arguments=[emotion]))
|
emotion_beliefs_add.append(Belief(name="emotion_detected", arguments=[emotion]))
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
self.logger.warning("Invalid belief for new emotion: %s", emotion)
|
self.logger.warning("Invalid belief for new emotion: %s", emotion)
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ class DeepFaceEmotionRecognizer(VisualEmotionRecognizer):
|
|||||||
# Sort faces by x coordinate to maintain left-to-right order
|
# Sort faces by x coordinate to maintain left-to-right order
|
||||||
analysis.sort(key=lambda face: face['region']['x'])
|
analysis.sort(key=lambda face: face['region']['x'])
|
||||||
|
|
||||||
|
# Fear op 0, boost 0.2 aan happy, sad -0.1, neutral +0.1
|
||||||
|
|
||||||
analysis = [face for face in analysis if face['face_confidence'] >= 0.90]
|
analysis = [face for face in analysis if face['face_confidence'] >= 0.90]
|
||||||
|
|
||||||
dominant_emotions = [face['dominant_emotion'] for face in analysis]
|
dominant_emotions = [face['dominant_emotion'] for face in analysis]
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ class LogicalOperator(Enum):
|
|||||||
OR = "OR"
|
OR = "OR"
|
||||||
|
|
||||||
|
|
||||||
type Belief = KeywordBelief | SemanticBelief | InferredBelief
|
type Belief = KeywordBelief | SemanticBelief | InferredBelief | EmotionBelief
|
||||||
type BasicBelief = KeywordBelief | SemanticBelief
|
type BasicBelief = KeywordBelief | SemanticBelief | EmotionBelief
|
||||||
|
|
||||||
|
|
||||||
class KeywordBelief(ProgramElement):
|
class KeywordBelief(ProgramElement):
|
||||||
@@ -69,6 +69,15 @@ class InferredBelief(ProgramElement):
|
|||||||
left: Belief
|
left: Belief
|
||||||
right: Belief
|
right: Belief
|
||||||
|
|
||||||
|
class EmotionBelief(ProgramElement):
|
||||||
|
"""
|
||||||
|
Represents a belief that is set when a certain emotion is detected.
|
||||||
|
|
||||||
|
:ivar emotion: The emotion on which this belief gets set.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name: str = ""
|
||||||
|
emotion: str
|
||||||
|
|
||||||
class Norm(ProgramElement):
|
class Norm(ProgramElement):
|
||||||
"""
|
"""
|
||||||
@@ -226,3 +235,9 @@ class Program(BaseModel):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
phases: list[Phase]
|
phases: list[Phase]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
input = input("Enter program JSON: ")
|
||||||
|
program = Program.model_validate_json(input)
|
||||||
|
print(program)
|
||||||
Reference in New Issue
Block a user