|
|
import cv2 |
|
|
import torch |
|
|
import torch.nn as nn |
|
|
from transformers import PreTrainedModel, PretrainedConfig |
|
|
|
|
|
|
|
|
import mediapipe as mp |
|
|
mp_pose = mp.solutions.pose |
|
|
pose = mp_pose.Pose() |
|
|
lmPose = mp_pose.PoseLandmark |
|
|
|
|
|
class PostureDetectionConfig(PretrainedConfig): |
|
|
model_type = "posture_detection" |
|
|
|
|
|
def __init__(self, **kwargs): |
|
|
super().__init__(**kwargs) |
|
|
|
|
|
class PostureDetectionModel(PreTrainedModel): |
|
|
config_class = PostureDetectionConfig |
|
|
|
|
|
def __init__(self, config): |
|
|
super().__init__(config) |
|
|
self.pose = pose |
|
|
|
|
|
def forward(self, pixel_values): |
|
|
images = [cv2.cvtColor(pixel_value.numpy(), cv2.COLOR_RGB2BGR) for pixel_value in pixel_values] |
|
|
keypoints = [self.pose.process(image) for image in images] |
|
|
|
|
|
results = [] |
|
|
for image, keypoint in zip(images, keypoints): |
|
|
lm = keypoint.pose_landmarks |
|
|
if lm is None: |
|
|
results.append(None) |
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
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 = self.findDistance(l_shldr_x, l_shldr_y, r_shldr_x, r_shldr_y) |
|
|
|
|
|
|
|
|
neck_inclination = self.findAngle(l_shldr_x, l_shldr_y, l_ear_x, l_ear_y) |
|
|
torso_inclination = self.findAngle(l_hip_x, l_hip_y, l_shldr_x, l_shldr_y) |
|
|
|
|
|
output = { |
|
|
"offset": offset, |
|
|
"neck_inclination": neck_inclination, |
|
|
"torso_inclination": torso_inclination |
|
|
} |
|
|
|
|
|
results.append(output) |
|
|
|
|
|
return results |
|
|
|
|
|
def findDistance(self, x1, y1, x2, y2): |
|
|
dist = torch.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) |
|
|
return dist |
|
|
|
|
|
def findAngle(self, x1, y1, x2, y2): |
|
|
theta = torch.acos((y2 - y1) * (-y1) / (torch.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) * y1)) |
|
|
degree = (180 / torch.pi) * theta |
|
|
return degree |
|
|
|
|
|
|
|
|
MODEL_MAPPING = { |
|
|
PostureDetectionConfig.model_type: PostureDetectionModel |
|
|
} |
|
|
|
|
|
CONFIG_MAPPING = { |
|
|
PostureDetectionConfig.model_type: PostureDetectionConfig |
|
|
} |