My python code doesn't save video frames as images

浪子不回头ぞ 提交于 2019-12-22 09:40:02

问题


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

How can I fix the problem?

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:


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

Output:

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

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

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.

This behavior is in line with this question.

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.



来源:https://stackoverflow.com/questions/51642097/my-python-code-doesnt-save-video-frames-as-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!