"Motion template" est une méthode efficace d'extraction de mouvement développée par MIT Media Lab (lien 1, [lien] 2](http://alumni.media.mit.edu/~jdavis/Publications/motiontemplategradient.pdf)). Il convient au calcul en temps réel avec une petite quantité de calcul. Il a un large éventail d'applications et peut afficher visuellement les mouvements des joueurs, les trajectoires de balle, de batte, de club et de raquette grâce à la reconnaissance des gestes et aux émissions sportives. Cette fois, j'essaierai l'analyse de modèle de mouvement en utilisant OpenCV 3.
OpenCV OpenCV (Open Source Computer Vision Library) est une collection de bibliothèques de traitement vidéo / image sous licence BSD. Il existe de nombreux algorithmes tels que le filtrage d'image, la correspondance de modèles, la reconnaissance d'objets, l'analyse vidéo et l'apprentissage automatique.
■ Exemple de suivi de mouvement avec OpenCV (OpenCV Google Summer of Code 2015) https://www.youtube.com/watch?v=OUbUFn71S4s
■ Cliquez ici pour une installation et une utilisation facile Installer OpenCV 3 (core + contrib) dans l'environnement Python 3 & Différence entre OpenCV 2 et OpenCV 3 & Easy operation check ★ Veuillez installer core + opencv_contrib pour exécuter le modèle de mouvement.
■ Cliquez ici pour filtrer les images fixes Essayez la détection des bords avec OpenCV Effectuer divers filtres avec OpenCV (Gradient, Highpass, Laplacian, Gaussian) Extraire des points caractéristiques avec OpenCV (AgastFeature, FAST, GFTT, MSER, AKAZE, BRISK, KAZE, ORB, SimpleBlob)
■ Cliquez ici pour le traitement des fichiers vidéo Essayez de convertir des vidéos en temps réel avec OpenCV Essayez de convertir des vidéos de caméra Web / caméra vidéo en temps réel avec OpenCV Dessinez un flux optique en temps réel avec OpenCV (méthode Shi-Tomasi, méthode Lucas-Kanade) Suivi d'objets à l'aide d'OpenCV (suivi des points caractéristiques spécifiés par la souris par la méthode Lucas-Kanade
Le "modèle de mouvement" peut également être facilement réalisé en utilisant OpenCV. Voici un bref résumé des méthodes OpenCV utilisées cette fois.
ID | Méthode | Aperçu |
---|---|---|
(a) | cv2.motempl.updateMotionHistory() | Mettre à jour l'image animée |
(b) | cv2.motempl.calcMotionGradient() | Calculez la direction de chaque coordonnée à partir de l'image animée |
(c) | cv2.motempl.calcGlobalOrientation() | Calculez l'orientation globale de l'image animée |
Cette fois, nous allons créer un programme qui utilise tous les éléments (a), (b) et (c), mais il est également possible de sélectionner uniquement ceux nécessaires. Par exemple, si vous ne voulez que des images animées, vous n'avez pas besoin de (b) (c).
Les principales fonctions de ce programme sont les suivantes.
Environnement d'exploitation
Données vidéo Le programme utilise l'exemple de vidéo fourni avec OpenCV. OpenCV\opencv\sources\samples\data\768x576.avi
motion.py
import time
import math
import cv2
import numpy as np
#Données vidéo
VIDEO_DATA = "768x576.avi"
#Touche Echap
ESC_KEY = 0x1b
#Période de mouvement restante(sec)
DURATION = 1.0
#La longueur de la ligne qui affiche la direction générale
LINE_LENGTH_ALL = 60
#La longueur de la ligne qui affiche la direction de chaque coordonnée
LINE_LENGTH_GRID = 20
#Intervalle pour calculer la direction de chaque coordonnée
GRID_WIDTH = 40
#Le rayon du cercle de la ligne indiquant la direction
CIRCLE_RADIUS = 2
#Initialisation de la fenêtre d'affichage
cv2.namedWindow("motion")
#Chargement des données vidéo
video = cv2.VideoCapture(VIDEO_DATA)
#Chargement de la première image
end_flag, frame_next = video.read()
height, width, channels = frame_next.shape
motion_history = np.zeros((height, width), np.float32)
frame_pre = frame_next.copy()
while(end_flag):
#Calcul de la différence entre les cadres
color_diff = cv2.absdiff(frame_next, frame_pre)
#Conversion de l'échelle de gris
gray_diff = cv2.cvtColor(color_diff, cv2.COLOR_BGR2GRAY)
#Binarisation
retval, black_diff = cv2.threshold(gray_diff, 30, 1, cv2.THRESH_BINARY)
#Temps de traitement du processeur(sec)Avoir
proc_time = time.clock()
#Mettre à jour l'image de l'historique des mouvements
cv2.motempl.updateMotionHistory(black_diff, motion_history, proc_time, DURATION)
#Gradation de l'affichage des anciens mouvements au fil du temps
hist_color = np.array(np.clip((motion_history - (proc_time - DURATION)) / DURATION, 0, 1) * 255, np.uint8)
#Conversion de l'échelle de gris
hist_gray = cv2.cvtColor(hist_color, cv2.COLOR_GRAY2BGR)
#Calcul de la direction de changement de l'image de l'historique des mouvements
#* L'orientation stocke la valeur (deg) dans le sens du changement pour chaque coordonnée.
mask, orientation = cv2.motempl.calcMotionGradient(motion_history, 0.25, 0.05, apertureSize = 5)
#Dessinez le mouvement de chaque coordonnée avec une ligne verte
width_i = GRID_WIDTH
while width_i < width:
height_i = GRID_WIDTH
while height_i < height:
cv2.circle(hist_gray, \
(width_i, height_i), \
CIRCLE_RADIUS, \
(0, 255, 0), \
2, \
16, \
0)
angle_deg = orientation[height_i - 1][width_i - 1]
if angle_deg > 0:
angle_rad = math.radians(angle_deg)
cv2.line(hist_gray, \
(width_i, height_i), \
(int(width_i + math.cos(angle_rad) * LINE_LENGTH_GRID), int(height_i + math.sin(angle_rad) * LINE_LENGTH_GRID)), \
(0, 255, 0), \
2, \
16, \
0)
height_i += GRID_WIDTH
width_i += GRID_WIDTH
#Calculer la direction générale du mouvement
angle_deg = cv2.motempl.calcGlobalOrientation(orientation, mask, motion_history, proc_time, DURATION)
#Dessinez tout le mouvement avec une ligne jaune
cv2.circle(hist_gray, \
(int(width / 2), int(height / 2)), \
CIRCLE_RADIUS, \
(0, 215, 255), \
2, \
16, \
0)
angle_rad = math.radians(angle_deg)
cv2.line(hist_gray, \
(int(width / 2), int(height / 2)), \
(int(width / 2 + math.cos(angle_rad) * LINE_LENGTH_ALL), int(height / 2 + math.sin(angle_rad) * LINE_LENGTH_ALL)), \
(0, 215, 255), \
2, \
16, \
0)
#Afficher une image animée
cv2.imshow("motion", hist_gray)
#Appuyez sur la touche Echap pour terminer
if cv2.waitKey(20) == ESC_KEY:
break
#Chargez l'image suivante
frame_pre = frame_next.copy()
end_flag, frame_next = video.read()
#Terminer le traitement
cv2.destroyAllWindows()
video.release()
Il est un peu difficile de comprendre la direction générale, mais s'il s'agit d'un cadre fixe, cela montre dans quelle direction les objets à l'écran se déplacent dans leur ensemble. Dans les cas où le cadre entier se déplace, il représente la direction dans laquelle le cadre se déplace.
À titre d'exemple pour analyser un mouvement à l'aide d'un modèle de mouvement, analysons le moment d'une prise de vue de Kei Nishikiori. Effectuez une analyse à l'aide des informations de direction calculées à partir des informations du modèle de mouvement. Exécutons le programme de modèle de mouvement sur l'image d'origine. Dans l'image animée, vous pouvez voir la trajectoire de la balle pour chaque image (image animée 1, image animée 2). En comptant le nombre de balles, l'image Motion 2 a 3 images d'avance sur l'image Motion 1.
Si vous analysez la direction de chaque grille pour l'image animée 1 et l'image animée 2, vous pouvez lire les mouvements suivants.
--L'épaule droite, qui a été arrêtée dans l'image Motion 1, se déplace vers le coin supérieur droit de l'image Motion 2.
Lorsque vous le regardez à la télévision, il semble que vous sautiez avec tout votre corps et frappiez la balle, mais au moment où vous frappez réellement la balle dans cette vidéo, après avoir fait un axe solide avec la moitié gauche du corps, utilisez le ressort de la moitié droite du corps. Vous pouvez voir que vous frappez.
** Image originale **
** Image animée 1 **
** Image Motion 2 **
Pour ceux qui font du sport, il serait intéressant d'analyser les mouvements des professionnels et la différence entre les mouvements quand ils réussissent et quand ils échouent.
Recommended Posts