File size: 5,039 Bytes
cca6a52 cfbaa51 cca6a52 4cdc77a cca6a52 1ca9b28 cca6a52 1ca9b28 cca6a52 1ca9b28 cca6a52 89a012c cca6a52 1ca9b28 cca6a52 1ca9b28 89a012c 1ca9b28 89a012c 1ca9b28 cca6a52 1ca9b28 cca6a52 1ca9b28 cca6a52 89a012c 1ca9b28 cca6a52 89a012c cca6a52 89a012c 4cdc77a 89a012c cca6a52 1ca9b28 cca6a52 4cdc77a 89a012c 4cdc77a cca6a52 1ca9b28 89a012c cca6a52 89a012c cca6a52 89a012c cca6a52 1ca9b28 cca6a52 89a012c cca6a52 89a012c 1ca9b28 89a012c 1ca9b28 89a012c |
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 120 121 122 123 124 125 126 127 128 129 130 131 132 |
import math
import numpy as np
from CPR_Module.Common.keypoints import CocoKeypoints
from CPR_Module.Common.logging_config import cpr_logger
class PostureAnalyzer:
"""Analyzes the Rescuer's posture during CPR based on the rescuer's keypoints and the patient's chest region."""
def __init__(self, right_arm_angle_threshold, left_arm_angle_threshold, wrist_distance_threshold, history_length_to_average):
self.history_length_to_average = history_length_to_average
self.right_arm_angles = []
self.left_arm_angles = []
self.wrist_distances = []
self.right_arm_angle_threshold = right_arm_angle_threshold
self.left_arm_angle_threshold = left_arm_angle_threshold
self.wrist_distance_threshold = wrist_distance_threshold
def _calculate_angle(self, a, b, c):
"""Calculate angle between three points"""
try:
ang = math.degrees(math.atan2(c[1]-b[1], c[0]-b[0]) -
math.atan2(a[1]-b[1], a[0]-b[0]))
return ang + 360 if ang < 0 else ang
except Exception as e:
cpr_logger.error(f"Angle calculation error: {e}")
return 0
def _check_bended_right_arm(self, keypoints):
"""Check for right arm bending (returns warning)"""
warnings = []
try:
shoulder = keypoints[CocoKeypoints.RIGHT_SHOULDER.value]
elbow = keypoints[CocoKeypoints.RIGHT_ELBOW.value]
wrist = keypoints[CocoKeypoints.RIGHT_WRIST.value]
right_angle = self._calculate_angle(wrist, elbow, shoulder)
self.right_arm_angles.append(right_angle)
avg_right = np.mean(self.right_arm_angles[-self.history_length_to_average:] if self.right_arm_angles else 0)
if avg_right > self.right_arm_angle_threshold:
warnings.append("Right arm bent!")
return warnings
except Exception as e:
cpr_logger.error(f"Right arm check error: {e}")
return warnings
def _check_bended_left_arm(self, keypoints):
"""Check for left arm bending (returns warning)"""
warnings = []
try:
shoulder = keypoints[CocoKeypoints.LEFT_SHOULDER.value]
elbow = keypoints[CocoKeypoints.LEFT_ELBOW.value]
wrist = keypoints[CocoKeypoints.LEFT_WRIST.value]
left_angle = self._calculate_angle(wrist, elbow, shoulder)
self.left_arm_angles.append(left_angle)
avg_left = np.mean(self.left_arm_angles[-self.history_length_to_average:] if self.left_arm_angles else 0)
if avg_left < self.left_arm_angle_threshold:
warnings.append("Left arm bent!")
return warnings
except Exception as e:
cpr_logger.error(f"Left arm check error: {e}")
return warnings
def _check_hands_on_chest(self, keypoints, chest_params):
"""Check if both hands are on the chest (returns warnings)"""
# Get the wrist keypoints
left_wrist = keypoints[CocoKeypoints.LEFT_WRIST.value]
right_wrist = keypoints[CocoKeypoints.RIGHT_WRIST.value]
warnings = []
try:
# Fallback
if chest_params is None:
return ["Both hands not on chest!"]
cx, cy, cw, ch = chest_params
left_in = right_in = False
# Check left hand
if left_wrist is not None:
left_in = (cx - cw/2 < left_wrist[0] < cx + cw/2) and \
(cy - ch/2 < left_wrist[1] < cy + ch/2)
# Check right hand
if right_wrist is not None:
right_in = (cx - cw/2 < right_wrist[0] < cx + cw/2) and \
(cy - ch/2 < right_wrist[1] < cy + ch/2)
# Determine warnings
if not left_in and not right_in:
warnings.append("Both hands not on chest!")
else:
if not left_in:
warnings.append("Left hand not on chest!")
if not right_in:
warnings.append("Right hand not on chest!")
except Exception as e:
cpr_logger.error(f"Hands check error: {e}")
return warnings
def validate_posture(self, keypoints, chest_params):
"""Run all posture validations (returns aggregated warnings)"""
warnings = []
warnings += self._check_hands_on_chest(keypoints, chest_params)
if ("Right hand not on chest!" not in warnings) and ("Both hands not on chest!" not in warnings):
warnings += self._check_bended_right_arm(keypoints)
if ("Left hand not on chest!" not in warnings) and ("Both hands not on chest!" not in warnings):
warnings += self._check_bended_left_arm(keypoints)
return warnings
|