OpenCV - захват произвольного кадра из видеофайла

Я использую следующий код для извлечения определенного кадра из видеофайла. В этом примере я просто получаю средний кадр:

import cv2
video_path = '/tmp/wonderwall.mp4'
vidcap = cv2.VideoCapture(video_path)
middle_frame = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT) / 2)
success, image = vidcap.read()
count = 0
success = True
while success:
    success, image = vidcap.read()
    if count == middle_frame:
        temp_file = tempfile.NamedTemporaryFile(suffix='.jpg', delete=False)
        cv2.imwrite(temp_file.name, image)
    count += 1

Однако при использовании этого метода захват среднего кадра в очень большом файле может занять некоторое время.

Очевидно, в старом модуле cv можно было сделать:

import cv
img = cv.QueryFrame(capture)

Есть ли в cv2 аналогичный способ захвата определенного кадра в видеофайле без необходимости перебирать все кадры?


person Dirty Penguin    schedule 08.05.2017    source источник


Ответы (1)


Вы можете сделать это таким же образом на C++ (преобразование python должно быть более чем простым).

cv::VideoCapture cap("file.avi");
double number_of_frame = cap.get(CV_CAP_PROP_FRAME_COUNT);
cap.set(CV_CAP_PROP_POS_FRAMES, IndexOfTheFrameYouWant);
cv::Mat frameIwant = cap.read();

Для справки:

VideoCapture::get(int propId)

Можно использовать различные флаги, возвращающие почти все, что вы можете пожелать (http://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html и найдите get() ).

 VideoCapture::set(int propId, double value)

Set будет делать то, что вы хотите (тот же документ ищет set), если вы используете propID 1 и индекс желаемого кадра. Вы должны отметить, что если индекс, который вы используете в качестве параметра, превосходит максимальный кадр, код захватит последний кадр видео, если вам повезет, или произойдет сбой во время выполнения.

person Ebya    schedule 08.05.2017