File size: 4,075 Bytes
a090915
e2af51e
a090915
 
 
 
e2af51e
a090915
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import numpy as np
from utils.motion_utils import (
    calc_avg_speed,
    calc_motion_intensity,
    calc_sudden_movements,
)
from utils.interaction_utils import (
    get_box_center,
    euclidean_distance,
    relative_distance,
    relative_keypoints,
)


class InteractionAnalyzer:
    """
    Analyze human motion and interactions between people based on poses and bounding boxes.
    """

    def __init__(self):
        # You can later add thresholds or state here if needed
        pass

    def calculate_motion_features(
        self,
        prev_poses: list[list[list[float]]],
        current_poses: list[list[list[float]]],
    ) -> dict:
        """
        Calculate motion features between consecutive frames.

        Args:
            prev_poses: List of keypoints for all people in previous frame
            current_poses: List of keypoints for all people in current frame

        Returns:
            dict: {
                "average_speed": float,
                "motion_intensity": float,
                "sudden_movements": int
            }
        """
        return {
            "average_speed": calc_avg_speed(prev_poses, current_poses),
            "motion_intensity": calc_motion_intensity(prev_poses, current_poses),
            "sudden_movements": calc_sudden_movements(prev_poses, current_poses),
        }

    def calculate_interactions(
        self,
        person_boxes: list[list[float]],
        current_poses: list[list[list[float]]],
        tracked_persons: dict,
    ) -> list[dict]:
        """
        Calculate interactions between people based on bounding boxes and keypoints.

        Args:
            person_boxes: List of bounding boxes [[x1,y1,x2,y2], ...] for each person
            current_poses: List of keypoints for each person
            tracked_persons: Dict mapping person_id -> last tracked box

        Returns:
            List of dictionaries describing interactions between people
        """
        interactions = []

        if len(person_boxes) < 2:
            return interactions

        for i in range(len(person_boxes)):
            for j in range(i + 1, len(person_boxes)):
                try:
                    # Ensure poses exist for both people
                    if i >= len(current_poses) or j >= len(current_poses):
                        continue

                    box1, box2 = person_boxes[i], person_boxes[j]
                    pose1, pose2 = current_poses[i], current_poses[j]

                    # Find person IDs
                    id1, id2 = None, None
                    for pid, tracked_box in tracked_persons.items():
                        if np.array_equal(box1, tracked_box):
                            id1 = pid
                        if np.array_equal(box2, tracked_box):
                            id2 = pid

                    if id1 is None or id2 is None:
                        continue

                    # Build interaction dictionary using utils
                    interaction = {
                        "person1_idx": i,
                        "person2_idx": j,
                        "person1_id": id1,
                        "person2_id": id2,
                        "box1": box1,
                        "box2": box2,
                        "center1": get_box_center(box1),
                        "center2": get_box_center(box2),
                        "distance": euclidean_distance(
                            get_box_center(box1), get_box_center(box2)
                        ),
                        "relative_distance": relative_distance(box1, box2),
                        "keypoints": {
                            "person1": pose1,
                            "person2": pose2,
                            "relative": relative_keypoints(pose1, pose2),
                        },
                    }
                    interactions.append(interaction)

                except Exception as e:
                    print(f"Skipping interaction {i}-{j}: {e}")
                    continue

        return interactions