使用python opencv编写mp4视频

时间:2015-05-28 14:32:01

标签: python opencv video

我想从网络摄像头捕获视频并使用opencv将其保存到mp4文件。我在stackoverflow(下面)上找到了很好的示例代码。唯一的障碍是我试图将其保存为mp4,而不是avi。我不能得到的部分是' XVID'传递给FOURCC作家的论点应该是,我认为是一个mp4编解码器(来自this link)。如果我将文件名更改为' output.mp4'它告诉我标签无效,所以我不得不相信XVID编解码器实际上是在创建一个avi文件。这是一个愚蠢的问题吗?我怎么写mp4?

我发现链接显示如何在事后将avi转换为mp4,但这似乎效率低下。好像我应该能够在最初的写作中做到这一点。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
fourcc = cv2.cv.CV_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()

10 个答案:

答案 0 :(得分:33)

这对我有用。

self._name = name + '.mp4'
self._cap = VideoCapture(0)
self._fourcc = VideoWriter_fourcc(*'MP4V')
self._out = VideoWriter(self._name, self._fourcc, 20.0, (640,480))

答案 1 :(得分:6)

您的代码中有些事情需要更改:

  1. 将输出名称更改为“ output.mp4”(更改为.mp4)
  2. 我在评论中遇到了与人们相同的问题,因此我将fourcc更改为0x7634706dout = cv2.VideoWriter('output.mp4',0x7634706d , 20.0, (640,480))

答案 2 :(得分:2)

对我有用的是确保输入“帧”的大小等于输出视频的大小(在这种情况下为(680,480))。

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

这是我的工作代码(Mac OSX Sierra 10.12.6):

brew install openh264

注意:我按照@ 10SecTom的建议安装了openh264,但不确定是否与问题有关。

以防万一:

node_modules

答案 3 :(得分:2)

这对我有用,我添加了images.sort()来保持顺序顺序:

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

答案 4 :(得分:1)

这是default code用于保存摄像机拍摄的视频

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

捕获了FULL HD

的剪辑大约两分钟

使用

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

保存的文件超过150MB

然后必须使用ffmpeg来减少保存的文件的大小,具体取决于使用30MB更改的视频质量,60MBcrf CRF越低,视频质量越好,生成的文件越大。您还可以更改格式avimp4mkv

然后我发现了ffmpeg-python

以下代码使用numpy array将每个帧的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

答案 5 :(得分:1)

任何正在寻找使用OpenCV或FFmpeg编写MP4文件的最方便,最可靠的方法的人,可以看到我最新的VidGear视频处理Python库的WriteGear API可以同时使用OpenCV backendFFmpeg backend甚至supports GPU encoders。这是在带有FFmpeg后端的WriteGear中使用H264编码器进行编码的示例:

# import required libraries
from vidgear.gears import WriteGear
import cv2

# define suitable (Codec,CRF,preset) FFmpeg parameters for writer
output_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast"}

# Open suitable video stream, such as webcam on first index(i.e. 0)
stream = cv2.VideoCapture(0) 

# Define writer with defined parameters and suitable output filename for e.g. `Output.mp4`
writer = WriteGear(output_filename = 'Output.mp4', logging = True, **output_params)

# loop over
while True:

    # read frames from stream
    (grabbed, frame) = stream.read()

    # check for frame if not grabbed
    if not grabbed:
      break

    # {do something with the frame here}
    # lets convert frame to gray for this example
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # write gray frame to writer
    writer.write(gray)

    # Show output window
    cv2.imshow("Output Gray Frame", gray)

    # check for 'q' key if pressed
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break

# close output window
cv2.destroyAllWindows()

# safely close video stream
stream.release()

# safely close writer
writer.close() 

答案 6 :(得分:0)

诸如OpenCV: FFMPEG: tag 0x5634504d/'MP4V' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)' OpenCV: FFMPEG: fallback to use tag 0x00000020/' ???'之类的问题可能是您输出的视频大小与原始视频不同。您可以先查看视频的帧大小。

答案 7 :(得分:0)

对于仍在解决问题的人。根据{{​​3}},我使用了此示例,它对我有用:

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'X264')
out = cv2.VideoWriter('output.mp4',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()

所以我不得不使用cv2.VideoWriter_fourcc(*'X264')编解码器。使用从源代码编译的OpenCV 3.4.3进行测试。

答案 8 :(得分:0)

fourcc = cv2.VideoWriter_fourcc(*' mp4v ')

与在fourcc中定义的“ MP4V”不同,“ mp4v”不会返回任何错误

对于错误“ OpenCV:FFMPEG:标签0x5634504d /'MP4V',编解码器ID 13和格式'mp4 / MP4(MPEG-4 Part 14)'不支持'OpenCV:FFMPEG:回退以使用标签0x00000020 /”? ??'“

答案 9 :(得分:0)

只需将编解码器更改为"DIVX"。该编解码器适用于所有格式。

fourcc = cv2.VideoWriter_fourcc(*'DIVX')

我希望这对您有用!