Подтвердить что ты не робот

Как читать видео mp4 для обработки scikit-image?

Я хотел бы применить функцию scikit-image (в частности, функцию сопоставления шаблонов match_template) к кадрам кодировки mp4, h264. Для моего приложения важно отслеживать время каждого кадра, но я знаю частоту кадров, поэтому я могу легко вычислить из номера кадра.

Обратите внимание, что я работаю на низких ресурсах, и я хотел бы поддерживать зависимость как можно более тонким: numpy все равно, и поскольку я планирую использовать scikit-image, я бы не стал импортировать ( и компиляция) openCV только для чтения видео.

Я вижу внизу эту страницу, что scikit-image может seamleassly обрабатывать видео, хранящиеся как массив numpy, получая таким образом идеальный вариант.

4b9b3361

Ответ 1

Imageio Пакет python должен делать то, что вы хотите. Вот фрагмент python, использующий этот пакет:

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

Вы также можете напрямую перебирать изображения в файле (см. документацию):

for i, im in enumerate(vid):
    print('Mean of frame %i is %1.1f' % (i, im.mean()))

Для установки imageio вы можете использовать pip:

pip install imageio

Другим решением было бы использовать moviepy (которые используют похожий код для чтения видео), но я думаю, что imageio легче и выполняет эту работу.


ответ на первый комментарий

Чтобы проверить, является ли номинальная частота кадров одинаковой для всего файла, вы можете подсчитать количество кадров в итераторе:

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

Чтобы отобразить временную метку каждого кадра:

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

Ответ 2

Вы можете использовать scikit-video, например:

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

Это использует avconv или ffmpeg под капотом. Производительность довольно хорошая, с небольшими накладными расходами, чтобы переместить данные в python по сравнению с просто декодированием видео в avconv.

Преимущество scikit-video в том, что API точно такой же, как API для чтения/записи видео OpenCV; просто замените cv2.VideoCapture на skvideo.io.VideoCapture.

Ответ 3

Простым способом чтения видео на python является использование skviode. Один штрих-код может помочь прочитать все видео.

import skvideo.io  
videodata = skvideo.io.vread("video_file_name")  
print(videodata.shape)

https://wingateacademy.blogspot.in/2018/01/scikit-video-skvideo-tutorial.html