使用python opencv编写mp4视频

Gad*_*s34 25 python video opencv

我想从网络摄像头捕获视频并使用opencv将其保存到mp4文件.我在stackoverflow(下面)上找到了很好的示例代码.唯一的障碍是我试图将其保存为mp4,而不是avi.我没有得到的一部分是传递给FOURCC作家的'XVID'论证应该是一个mp4编解码器(来自这个链接).如果我将文件名更改为'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()
Run Code Online (Sandbox Code Playgroud)

10S*_*Tom 44

这对我有用.

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

  • 我有错误编解码器 ID 12 而不是 @BahramdunAdil 的 13 并将编解码器从“*'mp4v'”更改为“*'MP4V”为我修复了它。 (13认同)
  • 它不起作用,并说下面的错误:`OpenCV:FFMPEG:标签0x5634504d /'MP4V'不支持编解码器ID 13和格式'mp4/MP4(MPEG-4 Part 14)'OpenCV:FFMPEG:回退使用tag 0x00000020 /'???'` (8认同)
  • 已经两年了!你没想到这个赞,是吧?:PI 使用 H264 写入 mp4 文件。它在寻找时创建了滞后的视频,这个建议对我有帮助。MP4V 编解码器解决了这个问题!:) (2认同)
  • @varun ha 没有看到它的到来:) .. 很高兴它帮助了你。 (2认同)
  • @BahramdunAdil 输出文件的名称必须以“.mp4”结尾,这就是您遇到该错误的原因 (2认同)

lin*_*ing 15

对我有用的是确保输入“帧”大小等于输出视频的大小(在本例中为 (680, 480) )。

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

这是我的工作代码(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()
Run Code Online (Sandbox Code Playgroud)

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

以防万一:

brew install openh264
Run Code Online (Sandbox Code Playgroud)


San*_*nth 10

这是用于保存相机捕获的视频的默认代码

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()
Run Code Online (Sandbox Code Playgroud)

大约两分钟的剪辑捕捉到了 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))
Run Code Online (Sandbox Code Playgroud)

保存的文件超过 150MB

然后不得不用ffmpeg降低保存的文件的大小,之间30MB60MB根据所需使用改变了视频质量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
Run Code Online (Sandbox Code Playgroud)


Ala*_*der 8

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

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

  • `0x7634706d` 与使用 fourcc 的 `mp4v` (小写)相同 (3认同)

小智 6

fourcc = cv2.VideoWriter_fourcc(*'mp4v')

与 fourcc 内部定义的“MP4V”不同,“mp4v”不会返回错误

对于错误:

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