我的python代码没有将视频帧另存为图像 [英] My python code doesn't save video frames as images

查看:249
本文介绍了我的python代码没有将视频帧另存为图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to grab specific frames (e.g. frame 0, 10, 20, ...) within a video and save them as images using Python and CV2. For some reasons, my code only saves the first frame. All other frames are created, but with size 0 (they are corrupt).

如何解决该问题?

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

推荐答案

显然,CAP_PROP_POS_AVI_RATIO(您在cap.set()中使用的常数2)效果不佳.查看修改后的脚本的输出:

Apparently, CAP_PROP_POS_AVI_RATIO (constant 2, which you were using in cap.set()) doesn't work well. Take a look at the output of your modified script:

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.

As you can see, cap.get(cv2.CAP_PROP_POS_AVI_RATIO) inside the cycle just returns a constant 6.51e-05.

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

And even though there are 174 frames, cap.set(cv2.CAP_PROP_POS_AVI_RATIO, 1) takes you only to frame 150, which is definitely a bug.

此行为与 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.

P.S. Interestingly, even cv2.CAP_PROP_FRAME_COUNT doesn't work properly. Apparently, my video file contained only 150 frames, but they were numbered from 22 to 171, as evidenced by ffprobe -show_frames chaplin.mp4 | grep coded_picture_number. So the output of CAP_PROP_FRAME_COUNT is just max(frame_no)+1.

这篇关于我的python代码没有将视频帧另存为图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆