Writing an mp4 video using python opencv

前端 未结 10 685
Happy的楠姐
Happy的楠姐 2021-01-31 07:44

I want to capture video from a webcam and save it to an mp4 file using opencv. I found example code on stackoverflow (below) that works great. The only hitch is that I\'m trying

10条回答
  •  醉梦人生
    2021-01-31 08:26

    This is the default code given to save a video captured by camera

    import numpy as np
    import cv2
    
    cap = cv2.VideoCapture(0)
    
    # Define the codec and create VideoWriter object
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
    
    while(cap.isOpened()):
        ret, frame = cap.read()
        if ret==True:
            frame = cv2.flip(frame,0)
    
            # write the flipped frame
            out.write(frame)
    
            cv2.imshow('frame',frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        else:
            break
    
    # Release everything if job is finished
    cap.release()
    out.release()
    cv2.destroyAllWindows()
    

    For about two minutes of a clip captured that FULL HD

    Using

    cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
    cap.set(3,1920)
    cap.set(4,1080)
    out = cv2.VideoWriter('output.avi',fourcc, 20.0, (1920,1080))
    

    The file saved was more than 150MB

    Then had to use ffmpeg to reduce the size of the file saved, between 30MB to 60MB based on the quality of the video that is required changed using crf lower the crf better the quality of the video and larger the file size generated. You can also change the format avi,mp4,mkv,etc

    Then i found ffmpeg-python

    Here a code to save numpy array of each frame as video using ffmpeg-python

    import numpy as np
    import cv2
    import ffmpeg
    
    def save_video(cap,saving_file_name,fps=33.0):
    
        while cap.isOpened():
            ret, frame = cap.read()
            if ret:
                i_width,i_height = frame.shape[1],frame.shape[0]
                break
    
        process = (
        ffmpeg
            .input('pipe:',format='rawvideo', pix_fmt='rgb24',s='{}x{}'.format(i_width,i_height))
            .output(saved_video_file_name,pix_fmt='yuv420p',vcodec='libx264',r=fps,crf=37)
            .overwrite_output()
            .run_async(pipe_stdin=True)
        )
    
        return process
    
    if __name__=='__main__':
    
        cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
        cap.set(3,1920)
        cap.set(4,1080)
        saved_video_file_name = 'output.avi'
        process = save_video(cap,saved_video_file_name)
    
        while(cap.isOpened()):
            ret, frame = cap.read()
            if ret==True:
                frame = cv2.flip(frame,0)
                process.stdin.write(
                    cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                        .astype(np.uint8)
                        .tobytes()
                        )
    
                cv2.imshow('frame',frame)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    process.stdin.close()
                    process.wait()
                    cap.release()
                    cv2.destroyAllWindows()
                    break
            else:
                process.stdin.close()
                process.wait()
                cap.release()
                cv2.destroyAllWindows()
                break
    

提交回复
热议问题