J'aimerais appliquer une fonction scikit-image
(en particulier la fonction de correspondance de modèle match_template
) aux images d'une vidéo mp4
, d'un encodage h264
. Il est important pour mon application de suivre l'heure de chaque image, mais je connais le nombre d'images par seconde afin que je puisse facilement calculer à partir du numéro de l'image.
Veuillez noter que je ne dispose que de peu de ressources et que je souhaite que les dépendances soient aussi minces que possible: numpy
est de toute façon nécessaire, et comme je prévois d’utiliser scikit-image
, j’éviterais d’importer (et de compiler) openCV
juste pour le lire la vidéo.
Je vois au bas de this page que scikit-image
peut traiter de manière professionnelle la vidéo stockée sous forme de tableau numpy
, obtenant ainsi l’idéal.
Le paquet imageio python devrait faire ce que vous voulez. Voici un extrait de code python utilisant ce package:
import pylab
import imageio
filename = '/tmp/file.mp4'
vid = imageio.get_reader(filename, 'ffmpeg')
nums = [10, 287]
for num in nums:
image = vid.get_data(num)
fig = pylab.figure()
fig.suptitle('image #{}'.format(num), fontsize=20)
pylab.imshow(image)
pylab.show()
Vous pouvez également parcourir directement les images du fichier ( voir la documentation ):
for i, im in enumerate(vid):
print('Mean of frame %i is %1.1f' % (i, im.mean()))
Pour installer imageio, vous pouvez utiliser pip:
pip install imageio
Une autre solution serait d’utiliser moviepy (qui utilise un code similaire pour lire les vidéos), mais je pense que imageio est plus léger et fait le travail.
réponse au premier commentaire
Afin de vérifier si la cadence d'images nominale est la même sur l'ensemble du fichier, vous pouvez compter le nombre d'images dans l'itérateur:
count = 0
try:
for _ in vid:
count += 1
except RuntimeError:
print('something went wront in iterating, maybee wrong fps number')
finally:
print('number of frames counted {}, number of frames in metada {}'.format(count, vid.get_meta_data()['nframes']))
In [10]: something went wront in iterating, maybee wrong fps number
number of frames counted 454, number of frames in metada 461
Pour afficher l'horodatage de chaque image:
try:
for num, image in enumerate(vid.iter_data()):
if num % int(vid._meta['fps']):
continue
else:
fig = pylab.figure()
pylab.imshow(image)
timestamp = float(num)/ vid.get_meta_data()['fps']
print(timestamp)
fig.suptitle('image #{}, timestamp={}'.format(num, timestamp), fontsize=20)
pylab.show()
except RuntimeError:
print('something went wrong')
Vous pouvez utiliser scikit-video , comme ceci:
from skvideo.io import VideoCapture
cap = VideoCapture(filename)
cap.open()
while True:
retval, image = cap.read()
# image is a numpy array containing the next frame
# do something with image here
if not retval:
break
Ceci utilise avconv ou ffmpeg sous le capot. Les performances sont plutôt bonnes, avec une petite charge pour déplacer les données en python par rapport au simple décodage de la vidéo dans avconv.
Scikit-video a pour avantage que l’API est exactement identique à l’API de lecture/écriture de vidéos OpenCV; il suffit de remplacer cv2.VideoCapture par skvideo.io.VideoCapture.
Un moyen facile de lire une vidéo en python consiste à utiliser skviode. Un code à une seule ligne peut aider à lire une vidéo entière.
import skvideo.io
videodata = skvideo.io.vread("video_file_name")
print(videodata.shape)
http://mllearners.blogspot.in/2018/01/scikit-video-skvideo-tutorial-for.html