Si vous souhaitez faire quelque chose en fonction des marqueurs et autres objets qui apparaissent dans la vidéo, vous suivrez souvent la procédure de détection et de localisation des objets dans le cadre en utilisant la méthode de détection d'objet / détection de marqueur. Cependant, si vous utilisez également le suivi des objets, vous pourrez peut-être interpoler la détection des marqueurs et des objets dans des cadres où la détection d’objet et la détection de marqueurs ont échoué.
Utilisez le Tracker d'OpenCV pour suivre les objets de votre vidéo.
Puisqu'il n'est pas nécessaire de créer un environnement, nous allons expérimenter sur Google Colaboratory.
Je veux charger la vidéo à analyser à partir de Google Drive, alors montez Google Drive.
from google.colab import drive
drive.mount("/content/gdrive")
fps = 5
Si vous définissez le FPS élevé, la précision du suivi augmentera essentiellement, mais le temps de traitement augmentera également, alors commencez par analyser avec 5 FPS. Faites-en une variable afin de pouvoir la modifier ultérieurement.
!ffmpeg -i "/content/gdrive/My Drive/TrackerExp/src.mp4" -vf fps=$fps "/content/gdrive/My Drive/TrackerExp/src/%06d.jpg "
Utilisez ffmpeg pour extraire des images fixes de vidéos. La destination d'extraction ne doit pas nécessairement être sur Google Drive, mais j'essaie de l'enregistrer sur Google Drive car c'est pratique lors de la vérification du processus plus tard. Si vous n'avez pas besoin de vous y référer, il est préférable d'utiliser un répertoire temporaire au lieu du répertoire sur Google Drive car la file d'attente de synchronisation de Google Drive ne sera pas obstruée.
import glob
import os
files = glob.glob("/content/gdrive/My Drive/TrackerExp/src/*.jpg ")
files.sort() #Trier les fichiers trouvés
print(len(files))
Obtenez une liste d'images du dossier de destination. Il n'y a aucune garantie que les images récupérées seront triées par numéro d'image, alors triez-les.
dst_dir = "/content/gdrive/My Drive/TrackerExp/dst"
if os.path.exists(dst_dir) == False:
os.makedirs(dst_dir)
Cette fois, je vais dessiner le résultat de l'analyse (résultat du suivi) sur l'image d'origine et l'enregistrer en tant qu'image. Créez un répertoire de destination de sauvegarde.
start_sec = 5.0 #Le suivi commence à 5 secondes
end_sec = 15.0 #Le suivi se termine à 15 secondes
start_frame = fps * start_sec
end_frame = fps * end_sec
Spécifiez la plage (durée) de la vidéo que vous souhaitez suivre. Le numéro d'image réel (de quelle image à quelle image) change en fonction du FPS, de sorte que le numéro d'image est calculé en multipliant les secondes par FPS.
tracker = cv2.TrackerMedianFlow_create()
Générez un tracker. Étant donné qu'OpenCV dispose de plusieurs algorithmes de suivi autres que MedianFrow, vous pouvez basculer en fonction des caractéristiques de la vidéo à suivre. Exemple: cv2.TrackerKCF_create ()
Publier ici etc. est facile à comprendre sur le premier et le second de chaque algorithme de suivi.
start_rect = (100, 200, 30, 30) # x: 100, y: 200, width: 30, height: 30
start_img = cv2.imread(files[start_frame])
tracker.init(start_img, start_rect)
Chargez l'image dans la première image et spécifiez la plage d'objets que vous souhaitez suivre dans cette image.
for i in range(start_frame, end_frame):
frame = cv2.imread(files[i])
located, bounds = tracker.update(frame)
if located:
x = bounds[0]
y = bounds[1]
w = bounds[2]
h = bounds[3]
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)
cv2.imwrite(os.path.join(dst_dir, os.path.basename(files[i])), frame)
Après avoir défini la position initiale, le suivi sera effectué image par image. Lisez l'image du cadre avec cv2.imread
et exécutez la [mise à jour] du tracker (https://docs.opencv.org/3.4/d0/d0a/classcv_1_1Tracker.html#a549159bd0553e6a8de356f3866df1f18) pour l'image lue. Aller.
located, bounds = tracker.update(frame)
La première valeur de retour de la méthode de mise à jour est "Avez-vous trouvé la cible?" Exprimée en Vrai / Faux. S'il est trouvé, la position cible (rectangle de plage) est définie dans la deuxième valeur de retour sous la forme (x, y, largeur, hauteur)
.
x = bounds[0]
y = bounds[1]
w = bounds[2]
h = bounds[3]
cv2.rectangle(frame, (int(x), int(y)), (int(x + w), int(y + h)), (255, 255, 0), 2)
Si la cible est trouvée, dessinez un cadre jaune sur l'image d'origine avec cv2.rectangle
. Le dernier argument «2» est l'épaisseur de la ligne.
cv2.imwrite(os.path.join(dst_dir, os.path.basename(files[i])), frame)
Enfin, enregistrez le résultat dans le répertoire de sortie créé ci-dessus.
Recommended Posts