|
|
import cv2 |
|
|
import math as m |
|
|
import mediapipe as mp |
|
|
|
|
|
def findDistance(x1, y1, x2, y2): |
|
|
dist = m.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) |
|
|
print('distance: ', dist) |
|
|
return dist |
|
|
|
|
|
def findAngle(x1, y1, x2, y2): |
|
|
theta = m.acos((y2 - y1) * (-y1) / (m.sqrt( |
|
|
(x2 - x1) ** 2 + (y2 - y1) ** 2) * y1)) |
|
|
degree = int(180 / m.pi) * theta |
|
|
print('degree: ', degree) |
|
|
return degree |
|
|
|
|
|
mp_pose = mp.solutions.pose |
|
|
pose = mp_pose.Pose() |
|
|
|
|
|
bad_image_path = 'images/bad_posture.jpg' |
|
|
good_image_path = 'images\good_posture.jpeg' |
|
|
image = cv2.imread(bad_image_path) |
|
|
|
|
|
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) |
|
|
|
|
|
keypoints = pose.process(image) |
|
|
|
|
|
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) |
|
|
|
|
|
|
|
|
lm = keypoints.pose_landmarks |
|
|
lmPose = mp_pose.PoseLandmark |
|
|
|
|
|
|
|
|
|
|
|
l_shldr_x = int(lm.landmark[lmPose.LEFT_SHOULDER].x * image.shape[1]) |
|
|
l_shldr_y = int(lm.landmark[lmPose.LEFT_SHOULDER].y * image.shape[0]) |
|
|
|
|
|
r_shldr_x = int(lm.landmark[lmPose.RIGHT_SHOULDER].x * image.shape[1]) |
|
|
r_shldr_y = int(lm.landmark[lmPose.RIGHT_SHOULDER].y * image.shape[0]) |
|
|
|
|
|
l_ear_x = int(lm.landmark[lmPose.LEFT_EAR].x * image.shape[1]) |
|
|
l_ear_y = int(lm.landmark[lmPose.LEFT_EAR].y * image.shape[0]) |
|
|
|
|
|
l_hip_x = int(lm.landmark[lmPose.LEFT_HIP].x * image.shape[1]) |
|
|
l_hip_y = int(lm.landmark[lmPose.LEFT_HIP].y * image.shape[0]) |
|
|
|
|
|
|
|
|
offset = findDistance(l_shldr_x, l_shldr_y, r_shldr_x, r_shldr_y) |
|
|
|
|
|
|
|
|
neck_inclination = findAngle(l_shldr_x, l_shldr_y, l_ear_x, l_ear_y) |
|
|
torso_inclination = findAngle(l_hip_x, l_hip_y, l_shldr_x, l_shldr_y) |
|
|
|
|
|
cv2.circle(image, (l_shldr_x, l_shldr_y), 7, (255, 255, 0), -1) |
|
|
cv2.circle(image, (l_ear_x, l_ear_y), 7, (0, 255, 255), -1) |
|
|
cv2.circle(image, (r_shldr_x, r_shldr_y), 7, (255, 0, 255), -1) |
|
|
cv2.circle(image, (l_hip_x, l_hip_y), 7, (0, 255, 0), -1) |
|
|
|
|
|
|
|
|
cv2.line(image, (l_shldr_x, l_shldr_y), (r_shldr_x, r_shldr_y), (255, 255, 0), 2) |
|
|
cv2.line(image, (l_shldr_x, l_shldr_y), (l_ear_x, l_ear_y), (0, 255, 255), 2) |
|
|
cv2.line(image, (l_ear_x, l_ear_y), (r_shldr_x, r_shldr_y), (255, 0, 255), 2) |
|
|
cv2.line(image, (l_shldr_x, l_shldr_y), (l_hip_x, l_hip_y), (0, 255, 0), 2) |
|
|
cv2.line(image, (l_hip_x, l_hip_y), (r_shldr_x, r_shldr_y), (255, 255, 0), 2) |
|
|
|
|
|
|
|
|
angle_text_string = 'Neck : ' + str(int(neck_inclination)) + 'degrees. Torso : ' + str(int(torso_inclination)) + 'degrees.' |
|
|
cv2.putText(image, angle_text_string, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) |
|
|
|
|
|
|
|
|
|
|
|
if neck_inclination < 40 and torso_inclination < 10: |
|
|
cv2.putText(image, 'Good Posture', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) |
|
|
else: |
|
|
cv2.putText(image, 'Bad Posture', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2) |
|
|
|
|
|
|
|
|
cv2.resize(image, (600, 600)) |
|
|
cv2.imshow('Posture Analysis', image) |
|
|
cv2.waitKey(0) |
|
|
cv2.destroyAllWindows() |