Writing an mp4 video using python opencv

前端 未结 10 684
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:25

    There are some things to change in your code:

    1. Change the name of your output to 'output.mp4' (change to .mp4)
    2. I had the the same issues that people have in the comments, so I changed the fourcc to 0x7634706d: out = cv2.VideoWriter('output.mp4',0x7634706d , 20.0, (640,480))
    0 讨论(0)
  • 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
    
    0 讨论(0)
  • 2021-01-31 08:28

    This worked for me, I added images.sort() to keep the sequence order:

    import cv2
    import numpy as np
    import os
    
    image_folder = 'data-set-race-01'
    video_file = 'race-01.mp4'
    image_size = (160, 120)
    fps = 24
    
    images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")]
    images.sort()
    
    out = cv2.VideoWriter(video_file, cv2.VideoWriter_fourcc(*'MP4V'), fps, image_size)
    
    img_array = []
    for filename in images:
        img = cv2.imread(os.path.join(image_folder, filename))
        img_array.append(img)
        out.write(img)
    
    out.release()
    
    0 讨论(0)
  • 2021-01-31 08:33

    What worked for me was to make sure the input 'frame' size is equal to output video's size (in this case, (680, 480) ).

    http://answers.opencv.org/question/27902/how-to-record-video-using-opencv-and-python/

    Here is my working code (Mac OSX Sierra 10.12.6):

    cap = cv2.VideoCapture(0)
    cap.set(3,640)
    cap.set(4,480)
    
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    out = cv2.VideoWriter('output.mp4', fourcc, 20.0, (640,480))
    
    while(True):
        ret, frame = cap.read()
        out.write(frame)
        cv2.imshow('frame', frame)
        c = cv2.waitKey(1)
        if c & 0xFF == ord('q'):
            break
    
    cap.release()
    out.release()
    cv2.destroyAllWindows()
    

    Note: I installed openh264 as suggested by @10SecTom but I'm not sure if that was relevant to the problem.

    Just in case:

    brew install openh264
    
    0 讨论(0)
  • 2021-01-31 08:35

    just change the codec to "DIVX". This codec works with all formats.

    fourcc = cv2.VideoWriter_fourcc(*'DIVX')
    

    i hope this works for you!

    0 讨论(0)
  • 2021-01-31 08:37

    This worked for me.

    self._name = name + '.mp4'
    self._cap = VideoCapture(0)
    self._fourcc = VideoWriter_fourcc(*'MP4V')
    self._out = VideoWriter(self._name, self._fourcc, 20.0, (640,480))
    
    0 讨论(0)
提交回复
热议问题