[PYTHON] Versuchen Sie, die Fusionsbewegung mit AnyMotion zu erkennen

Überblick

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.

Was ist AnyMotion?

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.

Ziel erreichen

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. fusion-right-all2.gif

  1. "Fu" Die Aktion, die Arme zu drehen und sich aneinander zu lehnen
  2. "John" dreht den Arm nach außen und das Bein nach innen
  3. "Huh!" Die Aktion, den Oberkörper nach innen zu beugen und die Finger auszurichten

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.

Definition der Fusionshaltung

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 -

Vorsichtsmaßnahmen

Ich habe den Code mit dem Python SDK geschrieben

Version verwendet

Vorbereitungen

  $ pip install anymotion-sdk

Videodatei hochladen ~ Skelettextraktion

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}")

Winkel bekommen

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.")

Fusionserkennung

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")

Generieren Sie eine GIF-Animation mit dem erkannten Fusionsrahmen

#Ü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)

fusion.gif

(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 ...)

Ganzer Quellcode

Ich habe es im Jupyter Notebook-Format auf gist hochgeladen.

abschließend

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.

Referenz

Recommended Posts

Versuchen Sie, die Fusionsbewegung mit AnyMotion zu erkennen
[Maschinelles Lernen] Versuchen Sie, Objekte mithilfe der selektiven Suche zu erkennen
Versuchen Sie, Nagios mit pynag zu konfigurieren
Versuchen Sie, Statistiken mit e-Stat abzurufen
Versuchen Sie, Excel mit Python (Xlwings) zu betreiben.
Versuchen Sie es mit Tkinter
Versuchen Sie, mit django-import-export csv-Daten zu django hinzuzufügen
Versuchen Sie es mit Docker-Py
Versuchen Sie, Blueprint with Flask zu verwenden, um Controller zu trennen
Versuchen Sie es mit einem Ausstecher
Versuchen Sie es mit PDFMiner
Versuchen Sie es mit Geopandas
Versuchen Sie es mit Selen
Versuchen Sie es mit scipy
Versuchen Sie es mit pandas.DataFrame
Versuchen Sie, mit Node.js einen HTTP-Server zu erstellen
Versuchen Sie es mit Django-Swiftbrowser
Versuchen Sie es mit matplotlib
Versuchen Sie es mit tf.metrics
Versuchen Sie es mit PyODE
Versuchen Sie, die Bewegung des Sonnensystems zu simulieren
Versuchen Sie, Fische mit Python + OpenCV2.4 (unvollendet) zu erkennen.
(Python) Versuchen Sie, eine Webanwendung mit Django zu entwickeln
Versuchen Sie, mit MVC eine RESTful-API mit Flask 1.0.2 zu erstellen
Versuchen Sie, Tweets mithilfe der Twitter-API in großen Mengen zu löschen
Versuchen Sie, hochfrequente Wörter mit NLTK (Python) zu extrahieren.
Versuchen Sie, Sudoku mit explosiver Geschwindigkeit mit Numpy zu lösen
Versuchen Sie es mit virtualenv (virtualenvwrapper)
[Azure] Versuchen Sie, Azure-Funktionen zu verwenden
Versuchen Sie, yolact zu implementieren
Versuchen Sie es jetzt mit virtualenv
Versuchen Sie es mit W & B.
Versuchen Sie es mit Django templates.html
[Kaggle] Versuchen Sie es mit LGBM
Versuchen Sie es mit dem Feed-Parser von Python.
Versuchen Sie es mit Pythons Tkinter
Versuchen Sie es mit Tweepy [Python2.7]
Versuchen Sie es mit Pytorchs collate_fn
Versuchen Sie es mit GUI, PyQt in Python
Versuchen Sie, eine Excel-Datei mit Python (Pandas / XlsxWriter) zu betreiben
Versuchen Sie, eine Excel-Datei mit Python (Pandas / XlsxWriter) zu betreiben
Versuchen Sie, Lebensmittelfotos mithilfe der Google Cloud Vision-API zu beurteilen
Versuchen Sie, eine multimodale Verteilung mithilfe des EM-Algorithmus zu modellieren
Versuchen Sie, eine lineare Regression mit Pytorch mit Google Colaboratory zu implementieren