Cet article a été publié le 22e jour du calendrier de l'avent 2019 de Fujitsu Systems Web Technology. Le contenu de l'article est l'opinion personnelle, et le contenu de l'écriture est la responsabilité de l'auteur. Peu importe à quelle organisation vous appartenez. (Oyakusoku)
J'aime jouer du violon comme passe-temps, mais jouer du violon est difficile. Il est bien connu qu'il est difficile de jouer, grâce à Shizuka-chan, mais il y a d'autres difficultés en plus de jouer.
Quand je joue du violon, j'ai une certaine chose à faire avant de jouer une chanson. Cela s'appelle Boeing, et c'est une tâche de décider de jouer avec un arc montant ou un arc tombant un par un tout en regardant le score.
--V → Upbow (de bas en haut) --Ï → Arc bas (de haut en bas)
J'écris Boeing sur la partition en tenant compte de la sensation de phrase de la chanson et de la facilité de jouer, mais ce travail est assez laborieux. Boeing n'a pas la seule bonne réponse, elle révèle également les sensibilités du joueur. De plus, lorsque vous jouez dans un quatuor ou un orchestre, il sera nécessaire de le faire correspondre avec d'autres instruments tels que l'alto et le violoncelle. Il n'est pas exagéré de dire que le développement d'une machine automatique Boeing est le rêve d'un joueur de cordes.
Alors, pouvons-nous réduire le temps et les efforts en lisant Boeing à partir des vidéos de performance d'autres personnes et en s'y référant sans passer à la machine d'attachement automatique Boeing? J'ai pensé.
La stratégie est la suivante.
Avec cela, vous devriez être en mesure de comprendre parfaitement le Boeing de la vidéo de performance! La bibliothèque utilisée est une estimation open source tf-pose qui implémente OpenPose pour Tensorflow.
OpenPose est une technologie annoncée par la CMU (Carnegie Melon University) à CVPR2017, une conférence internationale sur la vision par ordinateur, qui détecte les points clés et évalue la relation entre les points clés. Avec OpenPose, vous pouvez voir les coordonnées des points caractéristiques dans le corps humain, comme la position des articulations, comme indiqué ci-dessous.
https://github.com/CMU-Perceptual-Computing-Lab/openpose
tf-pose-estimation est une implémentation du même réseau neuronal qu'OpenPose pour Tensorflow. J'ai décidé de l'utiliser cette fois parce que l'extension tf-pose-estimation d'errno-mmd me semblait utile. Nous avons ajouté une option pour afficher les informations de position d'articulation bidimensionnelle estimée de la pose dans un fichier au format JSON, et nous voulions l'utiliser.
Je n'avais aucune idée des vidéos de performance de violon gratuites, alors j'ai utilisé un enregistrement de ma performance pour l'analyse. La chanson jouée est les 10 premières mesures du mouvement Aine Kleine Nachtmusik 1 de Mozart. J'ai joué à un tempo constant en utilisant le métronom.
Par défaut, tf-pose-estimation marque divers points caractéristiques tels que les yeux, les épaules, les coudes, les poignets et les chevilles, et les relie avec des lignes. Cette fois, j'ai un peu modifié le code pour ne marquer que le poignet droit.
tf-pose-estimation/tf_pose/estimator.py
440 #Dessinez une image circulaire uniquement sur le poignet droit
441 if i == CocoPart.RWrist.value:
442 cv2.circle(npimg, center, 8, common.CocoColors[i], thickness=3, lineType=8, shift=0)
449 #Désactiver le dessin au trait reliant les points caractéristiques
450 # cv2.line(npimg, centers[pair[0]], centers[pair[1]], common.CocoColors[pair_order], 3)
L'environnement d'exécution a utilisé Google Colaboratory. https://github.com/errno-mmd/tf-pose-estimation Exécutez la commande suivante après avoir exécuté la commande de configuration selon Read.md de.
%run -i run_video.py --video "/content/drive/My Drive/violin_playing/EineKleineNachtmusik_20191226.mp4" --model mobilenet_v2_large --write_json "/content/drive/My Drive/violin_playing/json" --no_display --number_people_max 1 --write_video "/content/drive/My Drive/violin_playing/EineKleine_keypoints_20191226.mp4"
En utilisant la vidéo de performance téléchargée à l'avance sur Google Drive comme entrée, une vidéo représentant le point d'articulation du poignet droit et un fichier JSON dans lequel les coordonnées du point d'articulation pour chaque image sont écrites sont générés.
Voici la vidéo de sortie coupée à des intervalles de quelques secondes et transformée en gif.
En regardant cela, il semble qu'il trace le point d'articulation du poignet droit avec une précision raisonnable.
Un fichier JSON contenant les coordonnées des points caractéristiques est généré à chaque image (1/60 seconde). Voici le fichier JSON de la 10e image.
000000000010_keypoints.json
{
"version": 1.2,
"people": [
{
"pose_keypoints_2d": [
265.5925925925926,
113.04347826086956,
0.7988795638084412,
244.55555555555557,
147.82608695652175,
0.762155294418335,
197.22222222222223,
149.56521739130434,
0.6929810643196106,
165.66666666666669,
189.56521739130434,
0.7044630646705627,
220.88888888888889,
166.95652173913044,
0.690696656703949,
289.2592592592593,
146.08695652173913,
0.5453883409500122,
299.77777777777777,
212.17391304347825,
0.6319900751113892,
339.22222222222223,
177.3913043478261,
0.6045356392860413,
213,
253.91304347826087,
0.23064623773097992,
0,
0,
0,
0,
0,
0,
268.22222222222223,
276.52173913043475,
0.2685505151748657,
0,
0,
0,
0,
0,
0,
257.7037037037037,
106.08695652173913,
0.8110038042068481,
270.85185185185185,
107.82608695652173,
0.7383710741996765,
231.4074074074074,
107.82608695652173,
0.7740614414215088,
0,
0,
0
]
}
],
"face_keypoints_2d": [],
"hand_left_keypoints_2d": [],
"hand_right_keypoints_2d": [],
"pose_keypoints_3d": [],
"face_keypoints_3d": [],
"hand_left_keypoints_3d": [],
"hand_right_keypoints_3d": []
}
En lisant le code, il semble que le 13e élément (tremblant à partir de 0) de pose_keypoints_2d est la valeur de coordonnée y du poignet droit. Dans l'exemple de la 10e image ci-dessus, ce serait «166,95652173913044».
Je voudrais faire un graphique avec matplotlib. Commencez par collecter les valeurs cibles à partir de la sortie du fichier JSON pour chaque image.
import json
import pprint
import os
import glob
import numpy as np
files = glob.glob('/content/drive/My Drive/violin_playing/json/*')
x = list(range(len(files)))
y = []
for file in files:
with open(file) as f:
df = json.load(f)
y.append(df['people'][0]['pose_keypoints_2d'][13])
La variable x stocke le nombre d'images et la variable y stocke la valeur de la coordonnée y du point d'articulation du poignet droit.
Puis graphe avec matplotlib. La mémoire de coordonnées x est distante de 30 images. Parce que j'ai joué Ainek à un tempo de 4 parties = 120, 30 images équivaut exactement à 1 noire, ce qui permet de voir plus facilement la correspondance avec la partition.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
fig = plt.figure(figsize=(120, 10))
ax = fig.add_subplot(1, 1, 1)
ax.xaxis.set_major_locator(ticker.MultipleLocator(30))
ax.plot(x, y, "red", linestyle='solid')
Le graphique de sortie est ici.
Voici le résultat de la superposition avec la partition. La superposition a été faite manuellement.
Quand c'est un arc descendant, il devrait se diriger vers le bas, et quand c'est un arc montant, il devrait se diriger vers le haut, mais ... C'est comme ça.
Pour être honnête, je ne peux pas vraiment atteindre le niveau d'utilisation tel qu'il est. Il semble difficile d'identifier l'inclinaison de petits passages tels que les doubles croches avec cette méthode. Si c'est une chanson plus détendue, elle peut être utile dans une certaine mesure.
Cependant, les problèmes suivants persistent en termes de correspondance avec la partition musicale.
――La largeur d'une mesure n'est pas la même sur la partition
Si l'appariement avec la partition musicale ne peut pas être fait automatiquement, le travail de fixation de l'archet ne sera pas efficace, donc les problèmes ci-dessus doivent être surmontés. Reconnaître la hauteur et la mettre en correspondance avec la partition musicale peut être une solution. La difficulté semble élevée (^ _ ^;)
Cette fois, je me suis concentré sur l'amélioration de l'efficacité du travail d'attache de Boeing, mais l'approche consistant à visualiser la différence dans la façon de gérer les arcs pour les expérimentés et les débutants et à se faire remarquer semble intéressante. J'ai senti que la technique d'estimation des poses de cette vidéo est une technique merveilleuse avec diverses applications potentielles.