Ich habe versucht, die Bewegung der Fusion zu erkennen, die jeder kennt. Verwenden Sie AnyMotion, um den Winkel aus den Koordinateninformationen des Gelenks zu berechnen und festzustellen, ob es sich um eine fusionsähnliche Haltung handelt.
AnyMotion ist ein API-Plattformdienst für Bewegungsanalysen, der auf der Schätzung der Körperhaltung mithilfe von KI basiert. Es scheint, dass es kostenlos verwendet werden kann, da es derzeit getestet wird.
Es ist möglich, Körperbewegungen zu visualisieren / zu quantifizieren, indem die Skelettkoordinaten einer Person in einem Bild oder Video geschätzt werden, das die Person zeigt, und basierend darauf der Winkel des angegebenen Teils berechnet wird. ..
Geschrieben in CLI, Python SDK, [Jupyter Notebook] auf GitHub Beispiele](https://github.com/nttpc/anymotion-examples) ist verfügbar.
Fusion besteht ursprünglich aus zwei Kriegern, die symmetrische Aktionen zum gleichen Zeitpunkt ausführen. Es besteht jedoch die Einschränkung, dass es derzeit mit AnyMotion nicht möglich ist, die Haltung von zwei oder mehr Personen gleichzeitig zu schätzen. Daher werde ich das Verhalten einzeln analysieren.
Die Fusion hat je nach Ruf drei Bewegungsstufen.
Dieses Mal werden wir der Einfachheit halber die Positionen 2 und 3 definieren, in denen die Bewegung für einen Moment stoppt, und analysieren, ob es eine Bewegung gibt, die für beide gilt. Es ist mir egal, ob kleine Teile wie die Fingerhöhe falsch ausgerichtet sind.
Die oben erwähnte Bewegungsanalyse wird von der Person auf der linken Seite und der Person auf der rechten Seite der Fusion durchgeführt, und wenn sich beide unabhängig vom Zeitpunkt so bewegen, wird die Fusion hergestellt! Ich werde sagen.
Die folgende Tabelle fasst den Zustand des Körpers zusammen, der als Fusion betrachtet wird.
Die Person links (die Person rechts) | "John" | "Huh!" |
---|---|---|
Linke Schulter (rechte Schulter) | 10〜90 | 130〜180 |
Linker Ellbogen (rechter Ellbogen) | 90〜180 | 40〜130 |
Rechte Schulter (linke Schulter) | 120〜200 | 50〜150 |
Rechter Ellbogen (linker Ellbogen) | 150〜200 | 100〜170 |
Linkes Knie (rechtes Knie) | 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
#Vorbereiten der AnyMotion-API
client = Client(client_id="CLIENT_ID",
client_secret="CLIENT_SECRET")
filename = "left.mp4"
#Video-Upload (linke Seite)
left_filename = "fusion_left.mp4"
left_movie_id = client.upload(left_filename).movie_id
print(f"movie_id: {left_movie_id}")
#Skelettextraktion (Schlüsselpunktextraktion) (linke Seite)
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}")
#Video-Upload (rechte Seite)
right_filename = "fusion_right.mp4"
right_movie_id = client.upload(right_filename).movie_id
print(f"movie_id: {right_movie_id}")
#Skelettextraktion (Schlüsselpunktextraktion) (rechte Seite)
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}")
Geben Sie das Teil an, um den Winkel zu erhalten. Die Angabe ist in Offizielles Dokument beschrieben.
#Definition von Winkelanalyseregeln
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"]
},
]
#Winkelanalyse starten (linke Seite)
left_analysis_id = client.analyze_keypoint(left_keypoint_id, rule=analyze_angles_rule)
#Erfassung von Winkelinformationen
left_analysis_result = client.wait_for_analysis(left_analysis_id).json
#Konvertieren Sie die Ergebnisse des Diktatformats in das Listenformat (konvertieren Sie gleichzeitig Zahlen von float nach 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.")
#Beginn der Winkelanalyse (rechte Seite)
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": #Überprüfen Sie, wer links steht
if not e:
e = 70 #Betrachten Sie den Fall, in dem die Beine nicht abgewinkelt sind
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: #Überprüfen Sie, wer rechts steht
if not f:
f = 70 #Betrachten Sie den Fall, in dem die Beine nicht abgewinkelt sind
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": #Überprüfen Sie, wer links steht
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:Winkelinformationen
position: left or right
"""
#Flag zum Speichern, ob jeder Schritt erkannt wurde
phase1 = False
phase2 = False
#Liste zum Speichern des entsprechenden Frames
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")
#Überprüfen Sie die Ausrichtung des Videos
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
#Holen Sie sich den angegebenen Frame des Videos
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
#Verbinden Sie zwei Rahmen horizontal
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
#Ermittelt den Medianwert der erkannten Frames
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)]
#Kombinieren Sie Phase 1-Bilder horizontal
p1_img = get_frame_img_hconcat(left_filename, right_filename, left_p1_center, right_p1_center)
#Kombinieren Sie Phase 2-Bilder horizontal
p2_img = get_frame_img_hconcat(left_filename, right_filename, left_p2_center, right_p2_center)
#Konvertieren Sie vom Numpy-Array in das PIL-Image
im1 = Image.fromarray(cv2.cvtColor(p1_img, cv2.COLOR_BGR2RGB))
im2 = Image.fromarray(cv2.cvtColor(p2_img, cv2.COLOR_BGR2RGB))
#Generieren Sie eine GIF-Animation
im1.save('fusion.gif', save_all=True, append_images=[im2], optimize=False, duration=700, loop=0)
(Ich denke, es gibt eine Menge Dinge, die ich sagen möchte, wie zum Beispiel, dass meine Hände mit Dingen bedeckt sind und meine Finger falsch ausgerichtet sind, aber bitte schauen Sie genau hin ...)
Ich habe es im Jupyter Notebook-Format auf gist hochgeladen.
Ich habe versucht, die Haltung der Fusion anhand der mit AnyMotion geschätzten Haltungsinformationen zu ermitteln. Auf diese Weise können Sie anscheinend auch so etwas wie einen Personal Trainer durchführen, z. B. die Form des Muskeltrainings überprüfen (Ietore). Ich möchte verschiedene andere Dinge ausprobieren, die ich tun kann.
Recommended Posts