OpenCV VideoCapture для больших файлов, возвращающихся к начальному кадру после 4000+ кадров - PullRequest
0 голосов
/ 11 июня 2018
import matplotlib.pyploy as plt
import cv2
def getFrame(cap):
    frameRate = 25
    frameId = cap.get(cv2.CAP_PROP_POS_FRAMES)
    ret, frame = cap.read()
    if not ret:
        return None
    print frameId
    if frameId < 0:
        return None
    if not (frameId % int(frameRate)):
        cap.set(cv2.CAP_PROP_POS_FRAMES, frameId + frameRate)
        return frame
    return None

videoFile = 'filename.webm'
cap = cv2.VideoCapture(videoFile,cv2.CAP_FFMPEG)

image = getFrame(cap)
plt.imshow(image)

cap.set(cv2.CAP_PROP_POS_FRAMES,4000.0)
image = getFrame(cap)
while(image is not None):
    plt.imshow(image)
    image = getFrame(cap)
cap.release()

Я запускаю вышеуказанный код в цикле while и отображаю изображение.Кажется, что после примерно 4250 кадров возвращаемый кадр будет таким же, как кадр в начале.Этот цикл продолжается после 4250 кадров.

Файл, который я читаю, - это mp4 и файл webm.Поведение одинаково для обоих типов файлов.videoCapture использует бэкэнд FFMPEG.Версия Opencv = 3.4.1, python 2.7.

Еще одним заметным поведением является то, что чтение кадра замедляется при увеличении кадра, а затем снова возвращается к быстрому после 4250 кадров.

Редактировать:
Я редактировал код.Я думаю, вы можете попробовать запустить это с файлом mp4 / webm дольше 5 минут.Я не могу загрузить видео по причине конфиденциальности, потому что оно записано в офисе.

Когда я модифицировал код только с помощью cap.read (), ошибка исчезла.Я подозреваю, что это как-то связано с cap.set ()

Ответы [ 2 ]

0 голосов
/ 12 июня 2018
def getNextFrame(cap):
    frameRate = 25
    for i in range(frameRate-1):
        cap.grab()
    ret, frame = cap.read()
    return ret, frame

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

Я не уверен, что это лучший подход, но я выложу его здесь.Я все еще буду принимать другие ответы.

0 голосов
/ 11 июня 2018

Используйте cap.set (cv2.cv.CV_CAP_PROP_FPS, 25) вместо пропуска кадров и установки номера кадра в коде.

Ваш код не проверяет размер видео перед настройкой cv2.CAP_PROP_POS_FRAMES,frameId + frameRate.

Вы можете проверить размер в кадрах с cap.get (cv2.CAP_PROP_FRAME_COUNT).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...