순서
드디어 이 프로젝트의 핵심! 각도 계산입니다.
#! calculate angles
def calculate_angle(a,b,c):
a = np.array(a) # First : 11
b = np.array(b) # Mid : 13
c = np.array(c) # End : 15
#any three points, numpy arrays
#calculate our radians for our particular joint and then the angle
radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0])
#converting that into an angle
angle = np.abs(radians*180.0/np.pi)
#arm isn't goiing to fo 360 degrees
if angle >180.0:
angle = 360-angle
return angle
이전 파트에서 출력 했던 좌표를 기준으로 생각해주시면 됩니다.
y from our endpoint - y form our midpoint
c1 : LEFT_WRIST y
b1 : LEFT_ELBOW y
c0 : LEFT_WRIST x
b0 : LEFT_ELBOW x
a1 : LEFT_SHOULDER y
a0 : LEFT_SHOULDER x
x, y 2 point
shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y] #a
elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x,landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y] #b
wrist = [landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x,landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y] #c
shoulder, elbow, wrist
([0.900646984577179, 1.1172715425491333],
[1.064361333847046, 1.0996811389923096],
[0.8742879629135132, 0.7958428263664246])
calculate_ angle(shoulder, elbow, wrist)
64.10362817199086
tuple(np.multiply(elbow, [640, 480]).astype(int))
(681, 527)
아래 코드는 이전 파트에서 사용했던 코드에 추가 한 것 입니다.
cap = cv2.VideoCapture(0)
## Setup mediapipe instance
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
while cap.isOpened():
ret, frame = cap.read()
# Recolor image to RGB
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
# Make detection
results = pose.process(image)
# Recolor back to BGR
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# Extract landmarks
try:
landmarks = results.pose_landmarks.landmark
#! Get coordinates
shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y]
elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x,landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y]
wrist = [landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x,landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y]
#!Calculate angle
angle = calculate_angle(shoulder, elbow, wrist)
#! Visualize angle
cv2.putText(image, str(angle),
tuple(np.multiply(elbow, [640, 480]).astype(int)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA
)
except:
pass
# Render detections
mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=2),
mp_drawing.DrawingSpec(color=(245,66,230), thickness=2, circle_radius=2)
)
cv2.imshow('Mediapipe Feed', image)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Get coordinates, Calculate angle, Visualize angle 부분을 봐주시면 됩니다.