** 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. ** **
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.
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.
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.
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.
Ç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.
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.
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.
Maintenant que je sais qu'il peut être utilisé, je vais l'appliquer à ma vidéo 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.
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.
Squats Part 1: Fold-Ability and Proportions
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).
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!