[PYTHON] J'ai essayé de photographier une vague de tortue en utilisant OpenPose

introduction

Je voulais filmer des vagues de Kamehame, alors je l'ai fait.

Movie_DOK.gif

Vous pouvez également masquer la ligne estimée.

Movie_NOK.gif

Nous utilisons OpenPose pour obtenir les coordonnées de l'articulation, calculer l'angle à partir de celle-ci et juger si la pose est comme ça.

À propos d'OpenPose

Méthode de configuration

J'ai utilisé l'estimation de la pose tf, qui est la version Tensorflow d'OpenPose. Mon environnement était Windows10, GTX1070, etc., donc je me suis référé à la page suivante pour l'installation. ** tf pose estimation **

Je suis resté coincé, donc une note ・ Il est plus sûr d'éviter les chemins longs et profonds. (Swig peut ne pas fonctionner correctement.)

Méthode d'exécution

Vous pouvez utiliser votre propre webcam pour fonctionner avec la commande suivante.

python run_webcam.py 

Quittez avec Echap.

Obtenez des coordonnées communes

Les numéros suivants sont attribués à chaque articulation.

Par exemple, si vous voulez avoir l'épaule droite (2): Puisqu'il est possible d'acquérir plusieurs personnes, nous transformons les humains avec pour.

humans = e.inference(image, resize_to_default=(w > 0 and h > 0), upsample_size=args.resize_out_ratio)
height,width = image.shape[0],image.shape[1]
for human in humans:
    body_part = human.body_parts[2]
    x = int(body_part.x * width + 0.5)
    y = int(body_part.y * height + 0.5)
    debug_info = 'x:' + str(x) + ' y:' + str(y)

Code réel

Le code réel. Enregistrez-le sous kamehameha.py et enregistrez-le dans le même dossier que run_webcam.py.

import argparse
import logging
import time
from pprint import pprint
import cv2
import numpy as np
import sys
from tf_pose.estimator import TfPoseEstimator
from tf_pose.networks import get_graph_path, model_wh
import math

logger = logging.getLogger('TfPoseEstimator-WebCam')
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)

fps_time = 0

def find_point(pose, p):
    for point in pose:
        try:
            body_part = point.body_parts[p]
            return (int(body_part.x * width + 0.5), int(body_part.y * height + 0.5))
        except:
            return (0,0)
    return (0,0)
def euclidian( point1, point2):
    return math.sqrt((point1[0]-point2[0])**2 + (point1[1]-point2[1])**2 )
def angle_calc(p0, p1, p2 ):
    '''
        p1 is center point from where we measured angle between p0 and
    '''
    try:
        a = (p1[0]-p0[0])**2 + (p1[1]-p0[1])**2
        b = (p1[0]-p2[0])**2 + (p1[1]-p2[1])**2
        c = (p2[0]-p0[0])**2 + (p2[1]-p0[1])**2
        angle = math.acos( (a+b-c) / math.sqrt(4*a*b) ) * 180/math.pi
    except:
        return 0
    return int(angle)

def accumulate_pose( a, b, c, d):
    '''
        a and b are angle between neck, left shoulder and left wrist
        c and d are angle between neck, right shoulder and right wrist
    '''
    if a in range(70,105) and b in range(100,140) and c in range(70,110) and d in range(120,180):
        return True
    return False

def release_pose( a, b, c, d):
    '''
        a and b are angle between neck, left shoulder and left wrist
        c and d are angle between neck, right shoulder and right wrist
    '''
    if a in range(140,200) and b in range(80,150) and c in range(0,40) and d in range(160,200):
        return True
    return False

def draw_str(dst, xxx_todo_changeme, s, color, scale):
    
    (x, y) = xxx_todo_changeme
    if (color[0]+color[1]+color[2]==255*3):
        cv2.putText(dst, s, (x+1, y+1), cv2.FONT_HERSHEY_PLAIN, scale, (0, 0, 0), thickness = 4, lineType=10)
    else:
        cv2.putText(dst, s, (x+1, y+1), cv2.FONT_HERSHEY_PLAIN, scale, color, thickness = 4, lineType=10)
    #cv2.line    
    cv2.putText(dst, s, (x, y), cv2.FONT_HERSHEY_PLAIN, scale, (255, 255, 255), lineType=11)
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='tf-pose-estimation realtime webcam')
    parser.add_argument('--camera', type=str, default=0)
    parser.add_argument('--resize', type=str, default='432x368',
                        help='if provided, resize images before they are processed. default=432x368, Recommends : 432x368 or 656x368 or 1312x736 ')
    parser.add_argument('--resize-out-ratio', type=float, default=4.0,
                        help='if provided, resize heatmaps before they are post-processed. default=1.0')

    parser.add_argument('--model', type=str, default='cmu', help='cmu / mobilenet_thin')
    parser.add_argument('--show-process', type=bool, default=False,
                        help='for debug purpose, if enabled, speed for inference is dropped.')
    args = parser.parse_args()
    
    print("mode 0: Normal Mode \nmode 1: Debug Mode")
    mode = int(input("Enter a mode : "))
    
    logger.debug('initialization %s : %s' % (args.model, get_graph_path(args.model)))
    w, h = model_wh(args.resize)
    if w > 0 and h > 0:
        e = TfPoseEstimator(get_graph_path(args.model), target_size=(w, h))
    else:
        e = TfPoseEstimator(get_graph_path(args.model), target_size=(432, 368))

    logger.debug('cam read+')
    cam = cv2.VideoCapture(args.camera)
    ret_val, image = cam.read()
    logger.info('cam image=%dx%d' % (image.shape[1], image.shape[0]))
    count = 0
    i = 0
    frm = 0
    y1 = [0,0]
    global height,width
    orange_color = (0,140,255)
    while True:
        ret_val, image = cam.read()
        i =1
        humans = e.inference(image, resize_to_default=(w > 0 and h > 0), upsample_size=args.resize_out_ratio)
        pose = humans
        if mode == 1:
            image = TfPoseEstimator.draw_humans(image, humans, imgcopy=False)
        height,width = image.shape[0],image.shape[1]

        debug_info = ''

        if len(pose) > 0:

            # angle calcucations
            angle_l1 = angle_calc(find_point(pose, 6), find_point(pose, 5), find_point(pose, 1))
            angle_l2 = angle_calc(find_point(pose, 7), find_point(pose, 6), find_point(pose, 5))
            angle_r1 = angle_calc(find_point(pose, 3), find_point(pose, 2), find_point(pose, 1))
            angle_r2 = angle_calc(find_point(pose, 4), find_point(pose, 3), find_point(pose, 2))

            debug_info = str(angle_l1) + ',' + str(angle_l2) + ' : ' + str(angle_r1) + ',' + str(angle_r2)

            if accumulate_pose(angle_l1, angle_l2, angle_r1, angle_r2):
                logger.debug("*** accumulate Pose ***")

                # (1) create a copy of the original:
                overlay = image.copy()
                # (2) draw shapes:
                cv2.circle(overlay, (find_point(pose, 4)[0] - 40, find_point(pose, 4)[1] + 40), 40, (255, 241, 0), -1)
                # (3) blend with the original:
                opacity = 0.4
                cv2.addWeighted(overlay, opacity, image, 1 - opacity, 0, image)

            elif release_pose(angle_l1, angle_l2, angle_r1, angle_r2):
                logger.debug("*** release Pose ***")

                # (1) create a copy of the original:
                overlay = image.copy()
                # (2) draw shapes:
                cv2.circle(overlay, (find_point(pose, 7)[0] + 80 ,find_point(pose, 7)[1] - 40), 80, (255, 241, 0), -1)
                cv2.rectangle(overlay,
                              (find_point(pose, 7)[0] + 80,  find_point(pose, 7)[1] - 70),
                              (image.shape[1], find_point(pose, 7)[1] - 10),
                              (255, 241, 0), -1)
                # (3) blend with the original:
                opacity = 0.4
                cv2.addWeighted(overlay, opacity, image, 1 - opacity, 0, image)

        image= cv2.flip(image, 1)

        if mode == 1:
            draw_str(image, (20, 50), debug_info, orange_color, 2)
            cv2.putText(image,
                        "FPS: %f" % (1.0 / (time.time() - fps_time)),
                        (10, 10),  cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                        (0, 255, 0), 2)

        #image =   cv2.resize(image, (720,720))

        if(frm==0):
            out = cv2.VideoWriter('outpy.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 30, (image.shape[1],image.shape[0]))
            print("Initializing")
            frm+=1
        cv2.imshow('tf-pose-estimation result', image)
        if i != 0:
            out.write(image)
        fps_time = time.time()
        if cv2.waitKey(1) == 27:
            break

    cv2.destroyAllWindows()


Comment exécuter / terminer

Exécutez-le avec la commande suivante.

python kamehameha.py 

Un menu apparaîtra. Si vous spécifiez "Mode de débogage", les informations de ligne et d'angle estimées s'affichent.

Après le traitement initial, la vague de tortue pourra tirer. Quittez avec Echap.

Remarques

―― La détection de l'attitude est une idée approximative. Il peut ne pas être détecté correctement en fonction des conditions telles que la position de la caméra et la façon dont vous faites face à la caméra.

Conditions de détection de la posture

En haut à gauche de l'écran "Debug Mode", les angles de l'épaule droite, du coude droit, de l'épaule gauche et du coude gauche sont alignés.

Si chaque angle remplit les conditions, il est jugé que vous êtes dans cette posture.

«Kamehame» "Vague"
Épaule droite 70 ~ 105 140 ~ 200
Coude droit 100 ~ 140 80 ~ 150
Épaule gauche 70 ~ 110 0 ~ 40
Coude gauche 120 ~ 180 160 ~ 200

S'il ne répond pas bien, veuillez jouer avec les valeurs de jugement de la fonction accumulate_pose et de la fonction release_pose dans votre code.

À la fin

Je voulais faire quelque chose avec OpenPose, donc je suis content de l'avoir fait cette fois. Il semble que vous puissiez créer un rôle d'entraîneur personnel, par exemple si l'entraînement musculaire est effectué dans la bonne posture ou quelque chose qui rend les enfants heureux.

Site de référence

** tf pose estimation **

Recommended Posts

J'ai essayé de photographier une vague de tortue en utilisant OpenPose
J'ai essayé d'utiliser paramétré
J'ai essayé d'utiliser la mimesis
J'ai essayé d'utiliser anytree
J'ai essayé d'utiliser aiomysql
J'ai essayé d'utiliser Summpy
J'ai essayé d'utiliser coturn
J'ai essayé d'utiliser Pipenv
J'ai essayé d'utiliser matplotlib
J'ai essayé d'utiliser "Anvil".
J'ai essayé d'utiliser Hubot
J'ai essayé d'utiliser ESPCN
J'ai essayé d'utiliser openpyxl
J'ai essayé d'utiliser Ipython
J'ai essayé d'utiliser PyCaret
J'ai essayé d'utiliser cron
J'ai essayé d'utiliser ngrok
J'ai essayé d'utiliser face_recognition
J'ai essayé d'utiliser Jupyter
J'ai essayé d'utiliser doctest
J'ai essayé d'utiliser du folium
J'ai essayé d'utiliser jinja2
J'ai essayé d'utiliser du folium
J'ai essayé d'utiliser la fenêtre de temps
J'ai essayé d'utiliser easydict (mémo).
J'ai essayé la reconnaissance faciale avec Face ++
J'ai essayé d'utiliser RandomForest
J'ai essayé d'utiliser BigQuery ML
J'ai essayé d'utiliser Amazon Glacier
J'ai essayé d'utiliser git inspector
J'ai essayé d'utiliser magenta / TensorFlow
J'ai essayé d'utiliser AWS Chalice
J'ai essayé d'utiliser l'émojinateur Slack
J'ai essayé d'utiliser Rotrics Dex Arm # 2
J'ai essayé d'utiliser Rotrics Dex Arm
J'ai essayé d'utiliser GrabCut d'OpenCV
J'ai essayé d'utiliser Thonny (Python / IDE)
J'ai essayé l'apprentissage par renforcement avec PyBrain
J'ai essayé l'apprentissage en profondeur avec Theano
J'ai essayé d'utiliser le notebook jupyter d'une manière ou d'une autre
[Kaggle] J'ai essayé le sous-échantillonnage en utilisant un apprentissage déséquilibré
J'ai essayé d'utiliser l'API checkio
J'ai essayé le traitement asynchrone en utilisant asyncio
J'ai essayé d'utiliser Amazon SQS avec django-celery
J'ai essayé d'utiliser Azure Speech to Text.
J'ai essayé de jouer au jeu ○ ✕ en utilisant TensorFlow
J'ai essayé d'utiliser l'API de données YOUTUBE V3
J'ai essayé d'utiliser du sélénium avec du chrome sans tête
J'ai essayé de dessiner une ligne en utilisant une tortue
[Kaggle] J'ai essayé l'apprentissage d'ensemble avec LightGBM
J'ai essayé d'utiliser PyEZ et JSNAPy. Partie 2: J'ai essayé d'utiliser PyEZ
J'ai essayé d'utiliser l'optimisation bayésienne de Python
J'ai essayé de classer le texte en utilisant TensorFlow
J'ai essayé d'utiliser la recherche sélective comme R-CNN
J'ai essayé d'utiliser l'API UnityCloudBuild de Python
J'ai essayé d'utiliser Headless Chrome de Selenium
J'ai essayé d'utiliser pipenv, alors prenez note