我的python代码没有将视频帧保存为图像

时间:2018-08-01 20:53:16

标签: python python-3.x opencv video cv2

我正在尝试获取视频中的特定帧(例如,帧0、10、20等),并使用Python和CV2将其另存为图像。由于某些原因,我的代码仅保存第一帧。创建了所有其他框架,但是大小为0(它们已损坏)。

如何解决此问题?

import cv2
from numpy import integer

number = 10;
filename = "18s.mp4";

def uniform():
    cap = cv2.VideoCapture(filename);
    frame_count= int(cap.get(cv2.CAP_PROP_FRAME_COUNT));
    print(frame_count)

    for x in range(0, number):
            frame_no = 1*(x/number)
            frame_no_int=int(frame_no*frame_count)

            cap.set(2,frame_no);
            ret, frame = cap.read()
            cv2.imwrite(filename+'_frame_'+str(frame_no_int)+'.jpg', frame);

    # When everything done, release the capture
    cap.release()

if __name__ == '__main__':
    uniform()

1 个答案:

答案 0 :(得分:2)

显然,CAP_PROP_POS_AVI_RATIO(常数2,您在cap.set()中使用的常数)不能很好地工作。查看修改后的脚本的输出:

import cv2
from numpy import integer

number = 10
filename = 'chaplin.mp4'

def uniform():
    cap = cv2.VideoCapture(filename)
    frame_count= int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    print(frame_count)

    for x in range(0, number):
        frame_pos_ratio = 1.0*x/number
        frame_no_int=int(frame_pos_ratio*frame_count)
        cap.set(cv2.CAP_PROP_POS_FRAMES, frame_no_int)
        print (frame_no_int, cap.get(cv2.CAP_PROP_POS_AVI_RATIO))
        ret, frame = cap.read()
        cv2.imwrite('_frame_'+str(frame_no_int)+'.jpg', frame)

    # Attempt to go the end of film
    cap.set(cv2.CAP_PROP_POS_AVI_RATIO, 1)
    print (cap.get(cv2.CAP_PROP_POS_FRAMES))

    # When everything done, release the capture
    cap.release()

if __name__ == '__main__':
    uniform()

输出:

172
(0, 6.510416666666667e-05)
(17, 6.510416666666667e-05)
(34, 6.510416666666667e-05)
(51, 6.510416666666667e-05)
(68, 6.510416666666667e-05)
(86, 6.510416666666667e-05)
(103, 6.510416666666667e-05)
(120, 6.510416666666667e-05)
(137, 6.510416666666667e-05)
(154, 6.510416666666667e-05)
150.0

如您所见,循环内的cap.get(cv2.CAP_PROP_POS_AVI_RATIO)仅返回常数6.51e-05

即使有174帧,cap.set(cv2.CAP_PROP_POS_AVI_RATIO, 1)也只能带您到150帧,这绝对是一个错误。

此行为符合this question

P.S。有趣的是,即使cv2.CAP_PROP_FRAME_COUNT也无法正常工作。显然,我的视频文件仅包含150帧,但是从ffprobe -show_frames chaplin.mp4 | grep coded_picture_number可以看出,它们的编号从22到171。因此,CAP_PROP_FRAME_COUNT的输出仅为max(frame_no)+1。