J'ai essayé de détecter le mouvement de fusion que tout le monde connaît. Utilisez AnyMotion pour calculer l'angle à partir des informations de coordonnées de l'articulation et déterminer s'il s'agit d'une posture de type fusion.
AnyMotion est un service de plate-forme d'API d'analyse de mouvement basé sur l'estimation de la posture à l'aide de l'IA. Il semble qu'il puisse être utilisé gratuitement car il est actuellement à l'essai.
Il est possible de visualiser / quantifier les mouvements du corps en estimant les coordonnées squelettiques d'une personne dans une image ou une vidéo montrant la personne et en calculant l'angle de la partie spécifiée en fonction de cela. ..
Écrit dans CLI, Python SDK, [Jupyter Notebook] sur GitHub Exemples](https://github.com/nttpc/anymotion-examples) est disponible.
La fusion se compose à l'origine de deux guerriers exécutant des actions symétriques au même moment, mais il existe une restriction selon laquelle il n'est pas possible d'estimer la posture de deux personnes ou plus en même temps avec AnyMotion pour le moment. Par conséquent, j'analyserai le comportement un par un.
La fusion comporte trois étapes de mouvement selon le cri.
Cette fois, par souci de simplicité, nous définirons les postures 2 et 3 où le mouvement s'arrête un instant, et analyserons s'il y a un mouvement qui s'applique aux deux. Je m'en fiche si de petites pièces telles que la hauteur des doigts sont mal alignées.
L'analyse de mouvement mentionnée ci-dessus est effectuée par la personne du côté gauche et la personne du côté droit de la fusion, et si les deux bougent comme ça quel que soit le moment, la fusion est établie! Je dirais.
Le tableau ci-dessous résume l'état du corps considéré comme une fusion.
--Phase 1: "Jean" Tordant le bras vers l'extérieur et la jambe vers l'intérieur --Phase 2: "Huh!" L'action de plier le haut du corps vers l'intérieur et d'aligner les doigts
La personne à gauche (la personne à droite) | "John" | "Huh!" |
---|---|---|
Épaule gauche (épaule droite) | 10〜90 | 130〜180 |
Coude gauche (coude droit) | 90〜180 | 40〜130 |
Épaule droite (épaule gauche) | 120〜200 | 50〜150 |
Coude droit (coude gauche) | 150〜200 | 100〜170 |
Genou gauche (genou droit) | 10〜80 | - |
$ pip install anymotion-sdk
from anymotion_sdk import Client
from PIL import Image, ImageDraw
import cv2
import matplotlib.pyplot as plt
import ffmpeg
import numpy as np
#Préparation de l'API AnyMotion
client = Client(client_id="CLIENT_ID",
client_secret="CLIENT_SECRET")
filename = "left.mp4"
#Téléchargement vidéo (côté gauche)
left_filename = "fusion_left.mp4"
left_movie_id = client.upload(left_filename).movie_id
print(f"movie_id: {left_movie_id}")
#Extraction du squelette (extraction du point clé) (côté gauche)
left_keypoint_id = client.extract_keypoint(movie_id=left_movie_id)
left_extraction_result = client.wait_for_extraction(left_keypoint_id)
print(f"keypoint_id: {left_keypoint_id}")
#Téléchargement vidéo (côté droit)
right_filename = "fusion_right.mp4"
right_movie_id = client.upload(right_filename).movie_id
print(f"movie_id: {right_movie_id}")
#Extraction du squelette (extraction du point clé) (côté droit)
right_keypoint_id = client.extract_keypoint(movie_id=right_movie_id)
right_extraction_result = client.wait_for_extraction(right_keypoint_id)
print(f"keypoint_id: {right_keypoint_id}")
Spécifiez la pièce pour obtenir l'angle. La manière de spécifier est décrite dans Document officiel.
#Définition des règles d'analyse angulaire
analyze_angles_rule = [
# left arm
{
"analysisType": "vectorAngle",
"points": ["rightShoulder", "leftShoulder", "leftElbow"]
},
{
"analysisType": "vectorAngle",
"points": ["leftShoulder", "leftElbow", "leftWrist"]
},
# right arm
{
"analysisType": "vectorAngle",
"points": ["leftShoulder", "rightShoulder", "rightElbow"]
},
{
"analysisType": "vectorAngle",
"points": ["rightShoulder", "rightElbow", "rightWrist"]
},
# left leg
{
"analysisType": "vectorAngle",
"points": ["rightHip", "leftHip", "leftKnee"]
},
# right leg
{
"analysisType": "vectorAngle",
"points": ["leftHip", "rightHip", "rightKnee"]
},
]
#Démarrer l'analyse de l'angle (côté gauche)
left_analysis_id = client.analyze_keypoint(left_keypoint_id, rule=analyze_angles_rule)
#Acquisition des informations d'angle
left_analysis_result = client.wait_for_analysis(left_analysis_id).json
#Convertir les résultats au format dict en format liste (convertir simultanément les nombres de float en int)
left_angles = [list(map(lambda v: int(v) if v else None, x["values"])) for x in left_analysis_result["result"]]
print("angles analyzed.")
#Début de l'analyse d'angle (côté droit)
right_analysis_id = client.analyze_keypoint(right_keypoint_id, rule=analyze_angles_rule)
right_analysis_result = client.wait_for_analysis(right_analysis_id).json
right_angles = [list(map(lambda v: int(v) if v else None, x["values"])) for x in right_analysis_result["result"]]
print("angles analyzed.")
def is_fusion_phase1(pos, a, b, c, d, e, f):
# pos: left or right
# print(a, b, c, d, e, f)
if pos == "left": #Vérifiez qui se tient à gauche
if not e:
e = 70 #Considérez le cas où les jambes ne sont pas inclinées
return (a in range(10, 90) and \
b in range(90, 180) and \
c in range(120, 200) and \
d in range(150, 200) and \
e in range(10, 80))
else: #Vérifiez qui se tient à droite
if not f:
f = 70 #Considérez le cas où les jambes ne sont pas inclinées
return (c in range(10, 90) and \
d in range(90, 180) and \
a in range(120, 200) and \
b in range(150, 200) and \
f in range(10,80))
def is_fusion_phase2(pos, a, b, c, d, e, f):
# pos: left or right
# print(a, b, c, d, e, f)
if pos == "left": #Vérifiez qui se tient à gauche
return a in range(130, 180) and \
b in range(40, 130) and \
c in range(50, 150) and \
d in range(100, 170)
else:
return c in range(130, 180) and \
d in range(40, 130) and \
a in range(50, 150) and \
b in range(100, 170)
def check_fusion(angles, position):
"""
angles:Informations sur l'angle
position: left or right
"""
#Indicateur pour stocker si chaque étape a été détectée
phase1 = False
phase2 = False
#Liste pour stocker le cadre correspondant
p1 = []
p2 = []
for i in range(len(angles[0])):
if is_fusion_phase1(position, angles[0][i], angles[1][i], angles[2][i], angles[3][i],
angles[4][i], angles[5][i]):
print(i, "Phase1!!!")
phase1 = True
p1.append(i)
elif phase1 and is_fusion_phase2(position, angles[0][i], angles[1][i], angles[2][i], angles[3][i],
angles[4][i], angles[5][i]):
print(i, "Phase2!!!")
phase2 = True
p2.append(i)
if phase1 and phase2:
print("Fusion!!!!!!")
return ((phase1 and phase2), p1, p2)
left_result, left_p1, left_p2 = check_fusion(left_angles, "left")
right_result, right_p1, right_p2 = check_fusion(right_angles, "right")
#Vérifiez l'orientation de la vidéo
def check_rotation(path_video_file):
meta_dict = ffmpeg.probe(path_video_file)
rotateCode = None
try:
if int(meta_dict['streams'][0]['tags']['rotate']) == 90:
rotateCode = cv2.ROTATE_90_CLOCKWISE
elif int(meta_dict['streams'][0]['tags']['rotate']) == 180:
rotateCode = cv2.ROTATE_180
elif int(meta_dict['streams'][0]['tags']['rotate']) == 270:
rotateCode = cv2.ROTATE_90_COUNTERCLOCKWISE
except:
pass
return rotateCode
#Obtenir l'image spécifiée de la vidéo
def get_frame_img(filename, frame_num):
reader = cv2.VideoCapture(filename)
rotateCode = check_rotation(filename)
reader.set(1, frame_num)
ret, frame_img = reader.read()
reader.release()
if not ret:
return None
if rotateCode:
frame_img = cv2.rotate(frame_img, rotateCode)
return frame_img
#Connectez deux cadres horizontalement
def get_frame_img_hconcat(l_filename, r_filename, l_framenum, r_framenum):
l_img = get_frame_img(l_filename, l_framenum)
r_img = get_frame_img(r_filename, r_framenum)
img = cv2.hconcat([l_img, r_img])
return img
#Obtenez la valeur médiane des trames détectées
left_p1_center = left_p1[int(len(left_p1)/2)]
left_p2_center = left_p2[int(len(left_p2)/2)]
right_p1_center = right_p1[int(len(right_p1)/2)]
right_p2_center = right_p2[int(len(right_p2)/2)]
#Combinez les images de la phase 1 horizontalement
p1_img = get_frame_img_hconcat(left_filename, right_filename, left_p1_center, right_p1_center)
#Combinez les images de la phase 2 horizontalement
p2_img = get_frame_img_hconcat(left_filename, right_filename, left_p2_center, right_p2_center)
#Convertir d'un tableau numpy en image PIL
im1 = Image.fromarray(cv2.cvtColor(p1_img, cv2.COLOR_BGR2RGB))
im2 = Image.fromarray(cv2.cvtColor(p2_img, cv2.COLOR_BGR2RGB))
#Générer une animation GIF
im1.save('fusion.gif', save_all=True, append_images=[im2], optimize=False, duration=700, loop=0)
(Je pense qu'il y a beaucoup de choses que je veux dire, telles que mes mains se couvrent de choses et mes doigts sont mal alignés, mais s'il vous plaît, regardez bien ...)
Je l'ai téléchargé sur gist au format Jupyter Notebook.
J'ai essayé de détecter la posture de fusion en utilisant les informations de posture estimées à l'aide d'AnyMotion. En faisant ce genre de chose, il semble que vous puissiez également faire quelque chose comme un entraîneur personnel, comme vérifier la forme d'entraînement musculaire (Ietore). J'aimerais essayer diverses autres choses que je peux faire.
Recommended Posts