web-dev-qa-db-fra.com

Comment lire une vidéo au format MP4 à traiter avec scikit-image?

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.

19
gaggio

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()

enter image description hereenter image description here

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')
42
head7

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.

18
Alex I

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

0
Win GATE ECE