[PYTHON] Vérifiez la forme de squat avec l'apprentissage en profondeur

** La vidéo utilisée dans cet article a été enregistrée il y a longtemps et s'abstient actuellement de s'entraîner au gymnase. ** **

introduction

C'est le deuxième "Muscle Training x Deep-Learning". Le premier est ici (L'apprentissage en profondeur a permis de voir plus facilement le laps de temps des changements physiques de façon spectaculaire). La «vérification de formulaire» est une habitude de nombreux stagiaires (personnes qui aiment l'entraînement musculaire). En réparant votre smartphone pendant l'entraînement, en prenant un autoportrait et en y repensant plus tard, vous pourrez connaître vos propres habitudes de forme et améliorer la qualité de l'entraînement ultérieur! Cet article se concentre sur "Squat (King of Muscle Training)" parmi l'entraînement musculaire, et écrit une histoire de vérification de la forme en utilisant l'apprentissage en profondeur.

D'abord du résultat

ezgif.com-optimize.gif

Le code source est publié dans le notebook Google Colab. https://colab.research.google.com/drive/18bFHGZ415T6emBoPHacrMyEckPGW9VCv Vous pouvez également l'exécuter en utilisant votre propre vidéo, alors essayez-le.

table des matières

1. Estimation d'attitude

L'estimation de la posture est une technique permettant d'estimer la posture d'un corps humain ou d'un animal. Par exemple, dans le cas du corps humain, la posture peut être exprimée en détectant le cou, les fesses, le genou, etc. et en les reliant. OpenPose est bien connu.

https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/media/dance_foot.gif?raw=true

1-1. Essayez de bouger

Cette fois, j'ai fait référence à "[Apprendre en créant! Développement en profondeur par PyTorch](https://www.amazon.co.jp/%E3%81%A4%E3%81%8F%E3%82%8A" % E3% 81% AA% E3% 81% 8C% E3% 82% 89% E5% AD% A6% E3% 81% B6% EF% BC% 81PyTorch% E3% 81% AB% E3% 82% 88% E3 % 82% 8B% E7% 99% BA% E5% B1% 95% E3% 83% 87% E3% 82% A3% E3% 83% BC% E3% 83% 97% E3% 83% A9% E3% 83 % BC% E3% 83% 8B% E3% 83% B3% E3% 82% B0-% E5% B0% 8F% E5% B7% 9D-% E9% 9B% 84% E5% A4% AA% E9% 83 % 8E-ebook / dp / B07VPDVNKW /) "page GitHub. Je voulais l'implémenter avec PyTorch x Google Colab, donc l'implémentation ci-dessus a été très utile.

Pour le moment, je vais essayer d'estimer la posture à partir d'une seule image en utilisant du matériel libre. La source est une version schématique. Consultez le bloc-notes Google Colab pour plus d'informations.


def create_model(weight_path):
  """
Créez un modèle.
Le nom de la couche réseau est différent entre le modèle entraîné et OpenPoseNet
  (Par exemple, module.model0.0.poids et modèle0.model.0.weight)Alors
Correspondre et charger
  """

  #Définition du modèle
  model = OpenPoseNet()

  #Charger les paramètres appris
  net_weights = torch.load(
      weights_path, map_location={'cuda:0': 'cpu'})
  keys = list(net_weights.keys())

  weights_load = {}

  #Le contenu chargé peut être affiché sur OpenPoseNet.
  #Modèle de nom de paramètre.state_dict().keys()Copier
  for i in range(len(keys)):
    weights_load[list(model.state_dict().keys())[i]
                 ] = net_weights[list(keys)[i]]

  #Donnez au modèle ce que vous avez copié
  state = model.state_dict()
  state.update(weights_load)
  model.load_state_dict(state)
  return model

model = create_model(weights_path)
model.to(device)

model.eval()
with torch.no_grad():
  predicted_outputs, _ = model(img.to(device))
  pafs = predicted_outputs[0][0].cpu().detach().numpy().transpose(1, 2, 0)
  heatmaps = predicted_outputs[1][0].cpu().detach().numpy().transpose(1, 2, 0)

pafs = cv2.resize(
    pafs, (test_img.shape[1], test_img.shape[0]), interpolation=cv2.INTER_CUBIC)
heatmaps = cv2.resize(
    heatmaps, (test_img.shape[1], test_img.shape[0]), interpolation=cv2.INTER_CUBIC)

_, result_img, _, _ = decode_pose(test_img, heatmaps, pafs)

cv2_imshow(result_img)

Les résultats sont les suivants. image.png

Ça fait du bien. Si vous faites cela pour chaque image de la vidéo, vous pourrez vérifier le formulaire. Cependant, je ne veux pas de toute cette partie commune, seule la partie minimale nécessaire est correcte. Cette fois,

Je vais me concentrer sur cela.

1-2. Carte thermique

Dans le modèle à utiliser, l'attitude est estimée en sortant la carte thermique et en en extrayant chaque partie. Tout d'abord, dessinons une carte thermique de la pièce cible.

# 1:Cou, 8:Cul (à droite), 9:Genou (droit), 10:Cheville (droite)
necessary_parts=[1,8,9,10] 
fig, ax = plt.subplots(2, 2, figsize=(16, 10))

for i, part in enumerate(necessary_parts):
    heat_map = heatmaps[:, :, part]
    heat_map = np.uint8(cm.jet(heat_map)*255)
    heat_map = cv2.cvtColor(heat_map, cv2.COLOR_RGBA2RGB)
    blend_img = cv2.addWeighted(test_img, 0.5, heat_map, 0.5, 0)
    ax[int(i/2), i%2].imshow(blend_img)

plt.show()

Les résultats sont les suivants. J'ai pu extraire correctement une pièce spécifique.

image.png

1-3. Estimation d'attitude

La position du joint est spécifiée à partir de la carte thermique de sortie de la pièce spécifique. Cette fois, en partant du principe qu'une seule personne peut être vue sur une feuille, il ne reste qu'un seul point pour chaque pièce et les pièces spécifiées sont connectées.

def find_joint_coords(heatmaps, necessary_parts, param = {'thre1': 0.1, 'thre2': 0.05, 'thre3': 0.5}):
  """
Détecter les coordonnées des articulations
  """
  
  joints = []
  for part in necessary_parts:
      heat_map = heatmaps[:, :, part]
      peaks = find_peaks(param, heat_map)
      if len(peaks) == 0:
        joints.append(img, [np.nan, np.nan], [np.nan, np.nan])
      #S'il y a deux ou plusieurs pics, ne laissez que l'emplacement le plus fort
      if peaks.shape[0]>1:
        max_peak = None
        for peak in peaks: 
          val = heat_map[peak[1], peak[0]]
          if max_peak is None or heat_map[max_peak[1], max_peak[0]] < val:
            max_peak = peak
      else:
        max_peak = peaks[0]
      joints.append(max_peak)

  return joints

img = test_img.copy()
joints = find_joint_coords(heatmaps, necessary_parts)
for i in range(len(joints)-1):
  img = cv2.line(img,tuple(joints[i].astype(int)),tuple(joints[i+1].astype(int)),(255,0,0),3)

cv2_imshow(img)

Les résultats sont les suivants. se sentir bien.

image.png

2. Demande de vérification du formulaire squat

Maintenant que je sais qu'il peut être utilisé, je vais l'appliquer à ma vidéo squat.

2-1. Facteurs importants du squat

Le squelette qui forme le tibia, la cuisse et le tronc varie d'une personne à l'autre, de sorte que la forme optimale varie d'une personne à l'autre. Je pense que ce sera plus facile à imaginer dans la figure ci-dessous.

image.png

En d'autres termes, la forme qui convient à la personne est davantage due aux proportions du squelette qu'à la flexibilité et à l'équilibre des forces. Par conséquent, si vous pouvez saisir cette proportion squelettique par vous-même, cela aidera à prévenir les blessures et vous pourrez augmenter en toute sécurité le poids du squat. Pour plus d'informations, consultez YouTube et un certain nombre d'autres pages Web intéressantes ci-dessous.

IMAGE ALT TEXT HERE Squats Part 1: Fold-Ability and Proportions

2-2. Faire ressembler à une vérification de formulaire

Puisque les coordonnées des articulations peuvent être prises, trouvez l'angle de l'articulation et du bras de moment et organisez-les par ordre chronologique. L'angle du joint est l'angle des deux vecteurs qui prennent en sandwich le joint. Le bras de moment simule le centre de gravité idéal (milieu du pied) et l'utilise comme la distance de la ligne perpendiculaire passant par l'articulation par rapport à sa ligne droite verticale. Calculez cela pour chaque cadre et connectez-les pour terminer. Enfin, tracez l'angle et le bras de moment produits dans chaque image avec matplotlib, collez-le en haut de l'écran et ajoutez un graphique qui semble être bien analysé.

** * Le code source sera long, je vais donc l'omettre. Veuillez consulter le cahier. ** **

L'exemple terminé est le suivant (le cadre est sélectionné de manière appropriée).

image.png

Résumé

Nous avons appliqué l'estimation de la posture à l'aide de l'apprentissage en profondeur pour effectuer une vérification de forme squat. Je pense que j'ai pu détecter les articulations avec une grande précision. À partir de ce résultat, vous pourrez peut-être améliorer encore la qualité du squat en trouvant un joueur avec un squelette proche de vous ou en comparant la forme avec ce joueur.

Les défis sont les suivants.

Comme mentionné ci-dessus, l'entraînement musculaire qui peut être fait à la maison ne consiste pas seulement à bouger votre corps! Amusez-vous bien à l'entraînement musculaire!

Recommended Posts

Vérifiez la forme de squat avec l'apprentissage en profondeur
Essayez l'apprentissage en profondeur avec TensorFlow
Apprentissage profond du noyau avec Pyro
Générez des Pokémon avec Deep Learning
Essayez le Deep Learning avec les concombres FPGA-Select
Identification de la race de chat avec Deep Learning
Faites de l'art ASCII avec l'apprentissage en profondeur
Catégoriser les articles de presse grâce au Deep Learning
Prévisions des ventes de collations avec apprentissage en profondeur
L'apprentissage en profondeur
Faites sourire les gens avec le Deep Learning
Classez les visages d'anime avec l'apprentissage en profondeur avec Chainer
Essayez les prévisions de prix Bitcoin avec Deep Learning
Essayez avec Chainer Deep Q Learning - Lancement
Essayez l'apprentissage profond de la génomique avec Kipoi
Mémorandum d'apprentissage profond
Apprentissage en profondeur Python
Apprentissage profond × Python
99,78% de précision avec apprentissage en profondeur en reconnaissant les hiragana manuscrits
Premier apprentissage profond ~ Lutte ~
Apprendre Python avec ChemTHEATER 03
"Orienté objet" appris avec python
Une histoire de prédiction du taux de change avec Deep Learning
Apprendre Python avec ChemTHEATER 05-1
Python: pratique du Deep Learning
Fonctions d'apprentissage en profondeur / d'activation
Apprentissage profond à partir de zéro
Analyse d'images par apprentissage profond à partir de Kaggle et Keras
Deep learning 1 Pratique du deep learning
Apprentissage profond / entropie croisée
Premier apprentissage profond ~ Préparation ~
Première solution d'apprentissage en profondeur ~
Apprendre Python avec ChemTHEATER 02
J'ai essayé le deep learning
Prédire les tags en extrayant des fonctionnalités musicales avec Deep Learning
Vérification de domaine avec Python
Technologie d'apprentissage en profondeur à grande échelle
Vérifier la version avec python
Fonction d'apprentissage profond / softmax
[Evangelion] Essayez de générer automatiquement des lignes de type Asuka avec Deep Learning
Créez un environnement pour "Deep Learning from scratch" avec Docker
(Maintenant) Construisez un environnement GPU Deep Learning avec GeForce GTX 960
[Apprentissage en profondeur] Classification d'images avec un réseau neuronal convolutif [DW jour 4]
J'ai capturé le projet Toho avec Deep Learning ... je le voulais.
Apprentissage en profondeur avec Shogi AI sur Mac et Google Colab
J'ai essayé d'écrire dans un modèle de langage profondément appris
HIKAKIN et Max Murai avec vidéo de jeu en direct et apprentissage en profondeur
Estimation de la courbe des signes avec module d'apprentissage en profondeur (python) + LSTM
L'apprentissage automatique appris avec Pokemon
Apprentissage profond à partir de zéro 1 à 3 chapitres
Deep Learning Gaiden ~ Programmation GPU ~
Vérifiez la couverture de python avec pytest-cov
Reconnaissance d'image par apprentissage profond 1 théorie
Deep running 2 Réglage de l'apprentissage profond
Apprentissage amélioré à partir de Python
À propos de l'apprentissage avec Google Colab
Apprentissage profond / code de travail LSTM