import numpy as np from ultralytics.engine.results import Results KEYPOINT_NAMES = ["nose","left_eye","right_eye","left_ear","right_ear","left_shoulder", "right_shoulder","left_elbow","right_elbow","left_wrist","right_wrist", "left_hip","right_hip","left_knee","right_knee","left_ankle","right_ankle"] def get_keypoints(result: Results): keypoints = None for i, box in enumerate(result.boxes): if box.cls != 0.: # Only consider the person class continue person_conf = box.conf.item() k = result.keypoints.data[i] x = k[:, 0].tolist() y = k[:, 1].tolist() score = k[:, 2] visible = (score > 0.5).tolist() # keypoints = {'x': x, 'y': y, 'visible': visible} keypoints = {key_name: (x_, y_) if v_ else None for key_name,x_,y_,v_ in zip(KEYPOINT_NAMES, x, y, visible)} break return keypoints def calculate_angle(p1, p2, p3): v1 = np.array([p1[0] - p2[0], p1[1] - p2[1]]) v2 = np.array([p3[0] - p2[0], p3[1] - p2[1]]) angle_rad = np.arccos(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))) angle_deg = np.degrees(angle_rad) return angle_deg def calculate_angle_to_horizontal(vector): angle_rad = np.arctan2(vector[1], vector[0]) angle_deg = np.degrees(angle_rad) # Adjust the angle to be within -90 to +90 degrees if angle_deg > 90: angle_deg = 180 - angle_deg elif angle_deg < -90: angle_deg = -180 - angle_deg return -angle_deg def extend_line(start, end, extend_factor=3): vector = np.array(end) - np.array(start) length = np.linalg.norm(vector) unit_vector = vector / np.linalg.norm(vector) new_point = end + unit_vector * length * extend_factor new_point = new_point.tolist() return (new_point[0], new_point[1]) def get_elbow_angles(keypoints: dict): left_elbow_angle = None right_elbow_angle = None if keypoints['left_shoulder'] and keypoints['left_elbow'] and keypoints['left_wrist']: left_elbow_angle = calculate_angle(keypoints['left_shoulder'], keypoints['left_elbow'], keypoints['left_wrist']) if keypoints['right_shoulder'] and keypoints['right_elbow'] and keypoints['right_wrist']: right_elbow_angle = calculate_angle(keypoints['right_shoulder'], keypoints['right_elbow'], keypoints['right_wrist']) return left_elbow_angle, right_elbow_angle def get_eye_angles(keypoints: dict): left_eye_angle = None right_eye_angle = None if keypoints['left_ear'] and keypoints['left_eye']: left_vector = (keypoints['left_eye'][0] - keypoints['left_ear'][0], keypoints['left_eye'][1] - keypoints['left_ear'][1]) left_eye_angle = calculate_angle_to_horizontal(left_vector) if keypoints['right_ear'] and keypoints['right_eye']: right_vector = (keypoints['right_eye'][0] - keypoints['right_ear'][0], keypoints['right_eye'][1] - keypoints['right_ear'][1]) right_eye_angle = calculate_angle_to_horizontal(right_vector) return left_eye_angle, right_eye_angle