Files
JustTwirk/test.py
2025-08-23 17:37:43 +02:00

354 lines
11 KiB
Python

# Copyright (c) OpenMMLab. All rights reserved.
import logging
import time
import cv2
from argparse import ArgumentParser
from mmengine.logging import print_log
from mmpose.apis import inference_topdown, init_model
from mmpose.registry import VISUALIZERS
from mmpose.structures import merge_data_samples
import numpy as np
class Position:
def __init__(self, person_kpts):
if len(person_kpts) == 8:
self.left_elbow_angle = person_kpts[0]
self.right_elbow_angle = person_kpts[1]
self.left_shoulder_angle = person_kpts[2]
self.right_shoulder_angle = person_kpts[3]
self.left_leg_angle = person_kpts[4]
self.right_leg_angle = person_kpts[5]
self.left_hip_angle = person_kpts[6]
self.right_hip_angle = person_kpts[7]
else:
self.left_hip = person_kpts[11]
self.left_knee = person_kpts[13]
self.left_ankle = person_kpts[15]
self.right_hip = person_kpts[12]
self.right_knee = person_kpts[14]
self.right_ankle = person_kpts[16]
self.left_shoulder = person_kpts[5]
self.left_elbow = person_kpts[7]
self.left_wrist = person_kpts[9]
self.right_shoulder = person_kpts[6]
self.right_elbow = person_kpts[8]
self.right_wrist = person_kpts[10]
self.left_elbow_angle = angle_between(self.left_shoulder - self.left_elbow, self.left_wrist - self.left_elbow)
self.right_elbow_angle = angle_between(self.right_shoulder - self.right_elbow, self.right_wrist - self.right_elbow)
self.left_shoulder_angle = angle_between(self.right_shoulder - self.left_shoulder, self.left_elbow - self.left_shoulder)
self.right_shoulder_angle = angle_between(self.left_shoulder - self.right_shoulder, self.right_elbow - self.right_shoulder)
self.left_leg_angle = angle_between(self.left_hip - self.left_knee, self.left_ankle - self.left_knee)
self.right_leg_angle = angle_between(self.right_hip - self.right_knee, self.right_ankle - self.right_knee)
self.left_hip_angle = angle_between(self.left_shoulder - self.left_hip, self.left_knee - self.left_hip)
self.right_hip_angle = angle_between(self.right_shoulder - self.right_hip, self.right_knee - self.right_hip)
def to_array(self):
return [
self.left_elbow_angle,
self.right_elbow_angle,
self.left_shoulder_angle,
self.right_shoulder_angle,
self.left_leg_angle,
self.right_leg_angle,
self.left_hip_angle,
self.right_hip_angle
]
def distance_to(self, position):
error = 0
success = True
for i, x in enumerate(self.to_array()):
if 3 < i < 6:
continue
y = position.to_array()[i]
if abs(y) > 165:
x = abs(x)
y = abs(y)
dist = abs(y - x)
if dist > 20:
success = False
# print(f"{i} nie jest ok: moje: {x}, cel: {y}")
error += abs(y - x)
else:
pass
# print(f"{i} jest ok: moje: {x}, cel: {position.to_array()[i]}")
return (success, error)
def parse_args():
parser = ArgumentParser()
# parser.add_argument('checkpoint', help='Checkpoint file')
parser.add_argument(
'--device', default='cuda:0', help='Device used for inference')
parser.add_argument(
'--draw-heatmap',
action='store_true',
help='Visualize the predicted heatmap')
parser.add_argument(
'--show-kpt-idx',
action='store_true',
default=False,
help='Whether to show the index of keypoints')
parser.add_argument(
'--skeleton-style',
default='mmpose',
type=str,
choices=['mmpose', 'openpose'],
help='Skeleton style selection')
parser.add_argument(
'--kpt-thr',
type=float,
default=0.3,
help='Visualizing keypoint thresholds')
parser.add_argument(
'--radius',
type=int,
default=3,
help='Keypoint radius for visualization')
parser.add_argument(
'--thickness',
type=int,
default=1,
help='Link thickness for visualization')
parser.add_argument(
'--alpha', type=float, default=0.8, help='The transparency of bboxes')
parser.add_argument(
'--camera-id', type=int, default=0, help='Camera device ID')
args = parser.parse_args()
return args
def angle_between(v1, v2):
"""
Liczy kąt między wektorami v1 i v2 w stopniach.
Znak kąta zależy od kierunku (przeciwnie do ruchu wskazówek zegara jest dodatni).
"""
# kąt w radianach
angle = np.arccos(np.clip(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)), -1.0, 1.0))
# obliczamy znak kąta w 2D: + jeśli v2 jest "po lewej" od v1
sign = np.sign(v1[0] * v2[1] - v1[1] * v2[0])
return np.degrees(angle) * sign
def is_visible(kpt, threshold=0.3):
# kpt = [x, y, score]
return kpt[2] > threshold
def main():
args = parse_args()
# build the model from a config file and a checkpoint file
if args.draw_heatmap:
cfg_options = dict(model=dict(test_cfg=dict(output_heatmaps=True)))
else:
cfg_options = None
model = init_model(
"mmpose/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py",
"hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth",
device=args.device,
cfg_options=cfg_options)
# init visualizer
model.cfg.visualizer.radius = args.radius
model.cfg.visualizer.alpha = args.alpha
model.cfg.visualizer.line_width = args.thickness
visualizer = VISUALIZERS.build(model.cfg.visualizer)
visualizer.set_dataset_meta(
model.dataset_meta, skeleton_style=args.skeleton_style)
# start capturing video from camera
cap = cv2.VideoCapture(args.camera_id)
if not cap.isOpened():
print("Error: Cannot open camera")
return
lastDegs = []
lastMove = 0
visible = 0
maha = 0
start = False
oldpos = None
waiting = 100
positions = []
numPositions = 0
tPose = Position(
[
167.5568,
-161.67027,
-166.49443,
168.22028,
110.21745,
166.41733,
167.57822,
-176.08066
]
)
krakowiak = Position(
[np.float32(-98.226715), np.float32(106.39389), np.float32(-135.05656), np.float32(139.48904), np.float32(-149.9036), np.float32(8.216028), np.float32(174.70923), np.float32(-176.893)]
)
krakowiakRight = Position(
[np.float32(-110.61421), np.float32(-174.2424), np.float32(-127.05916), np.float32(174.9463),
np.float32(175.62007), np.float32(166.89127), np.float32(168.8219), np.float32(-178.02744)]
)
while True:
ret, frame = cap.read()
if not ret:
print("Error: Cannot read frame from camera")
break
# convert BGR to RGB
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# inference
batch_results = inference_topdown(model, img)
results = merge_data_samples(batch_results)
person_kpts = results.pred_instances.keypoints[0]
person_visible = results.pred_instances.keypoints_visible[0]
left_hand_visible = person_visible[5] > 0.75 and person_visible[5] > 0.75 and person_visible[9] > 0.75
right_hand_visible = person_visible[6] > 0.75 and person_visible[8] > 0.75 and person_visible[10] > 0.75
left_leg_visible = person_visible[11] > 0.75 and person_visible[13] > 0.75 and person_visible[15] > 0.75
right_leg_visible = person_visible[12] > 0.75 and person_visible[14] > 0.75 and person_visible[16] > 0.75
position = Position(person_kpts)
#
if position.distance_to(tPose)[0]:
print("\rT POSE!", end="")
elif position.distance_to(krakowiak)[0]:
print("\rKrakowiak", end="")
elif position.distance_to(krakowiakRight)[0]:
print("\rKrakowiak right", end="")
else:
print("\rNIC!", end="")
# print(position.left_elbow_angle)
# if oldpos is None:
# oldpos = position
#
# if oldpos.distance_to(position) < 7.5:
# print(f"\r{goalPosition.distance_to(position)}", end="")
#
# oldpos = position
# if error > 200:
# if start:
# if numPositions > 100:
# avgPosition = [0, 0, 0, 0, 0, 0, 0, 0]
#
# for element in positions:
# for i, data in enumerate(element):
# avgPosition[i] += data
#
# for i, element in enumerate(avgPosition):
# avgPosition[i] = avgPosition[i] / numPositions
#
# print(avgPosition)
#
# break
# else:
# print(f"\r{numPositions}", end="")
# if oldpos is None:
# oldpos = position
#
# if oldpos.distance_to(position)[0]:
# positions.insert(0, position.to_array())
# numPositions += 1
#
# oldpos = position
#
# # else:
# # print(f"\rOK!", end="")
#
# if waiting != 0 and not start:
# print(f"\r{waiting}", end="")
# waiting -= 1
# else:
# start = True
# lastDegs.insert(0, (left_elbow_angle, right_elbow_angle))
#
# last = 0
# lastCount = 0
#
# for element in lastDegs:
# last += element[1]
# lastCount += 1
#
# last = last / lastCount
# dist = right_elbow_angle - last
#
# if not right_visible:
# visible = 0
# print("\rNie widać prawej ręki!!!!!!!!", end="")
# else:
# if maha == 0:
# print("\rWidać rękę, nie maha!", end="")
# else:
# maha -= 1
#
# visible += 1
#
# if 15 < abs(dist) < 60 and visible > 5:
# if lastMove != dist > 0:
# maha = 10
# print("\rmaha!", end="")
#
# lastMove = dist > 0
#
# if len(lastDegs) > 5:
# lastDegs.pop()
# visualize
vis_img = visualizer.add_datasample(
'result',
img,
data_sample=results,
draw_gt=False,
draw_bbox=True,
kpt_thr=args.kpt_thr,
draw_heatmap=args.draw_heatmap,
show_kpt_idx=args.show_kpt_idx,
skeleton_style=args.skeleton_style,
show=False,
out_file=None)
# convert RGB back to BGR for OpenCV
vis_img = cv2.cvtColor(vis_img, cv2.COLOR_RGB2BGR)
cv2.imshow('Live Pose Estimation', vis_img)
# press 'q' to quit
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()