在python中保存openCV视频

时间:2015-03-28 12:40:38

标签: python opencv

我正在尝试保存视频,但它无法正常工作。 我按照openCV文档中的说明进行操作。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

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)


        out.write(frame)

        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cap.release()

out.release()

cv2.destroyAllWindows()

有什么问题?

14 个答案:

答案 0 :(得分:14)

试试这个。它对我有用。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
#fourcc = cv2.cv.CV_FOURCC(*'DIVX')
#out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
out = cv2.VideoWriter('output.avi', -1, 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()

答案 1 :(得分:7)

就我而言,我发现Writer的大小必须与相机或文件的帧大小相匹配。这样我首先读取帧大小并应用于编写器设置如下。

(grabbed, frame) = camera.read()
fshape = frame.shape
fheight = fshape[0]
fwidth = fshape[1]
print fwidth , fheight
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (fwidth,fheight))

答案 2 :(得分:3)

我也面临同样的问题但是当我使用 ' MJPG&#39> 而不是 ' XVID'

我用过

fourcc = cv2.VideoWriter_fourcc(*'MJPG')

而不是

fourcc = cv2.VideoWriter_fourcc(*'XVID')

答案 3 :(得分:3)

请确保设置正确的宽度和高度。您可以像下面这样设置它

cv2.VideoWriter('output.avi', fourcc, 20.0, (int(cap.get(3)), int(cap.get(4))))

答案 4 :(得分:2)

我有同样的问题,然后我尝试了这个:

frame = cv2.flip(frame,180) 

而不是

frame= cv2.flip(frame,0) 

它正在工作。

答案 5 :(得分:2)

您需要像这样获取捕获的确切大小:

def areYouPlayingBanjo(name):
return name + (' plays' if (name[0]=='r') | (name[0]=='R' else ' does not play') + " banjo"

答案 6 :(得分:1)

https://github.com/ContinuumIO/anaconda-issues/issues/223的jveitchmichaelis提供了一个彻底的答案。我在这里复制了他的答案:

  

OpenCV中的文档说(隐藏)你只能写   使用OpenCV3进行avi。无论这是否真实,我都无法做到   确定,但我无法写任何其他内容。

     

然而,OpenCV主要是一个计算机视觉库,而不是视频流,编解码器和写一个。因此,开发人员试图保持   这部分尽可能简单。由于这个OpenCV视频   container仅支持avi扩展,即它的第一个版本。

     

来自:http://docs.opencv.org/3.1.0/d7/d9e/tutorial_video_write.html

     

我的设置:我使用MSVC 2015从源代码构建了OpenCV 3,包括   ffmpeg的。我还从中下载并安装了XVID和openh264   思科,我加入了我的PATH。我正在运行Anaconda Python 3.我也是   下载了最新版本的ffmpeg并将bin文件夹添加到我的   路径,虽然它不应该因为它被烘焙而产生影响   OpenCV的。

     

我在Win 10 64位中运行。

     

此代码似乎在我的计算机上正常工作。它会生成一个视频   包含随机静态:

writer = cv2.VideoWriter("output.avi",
cv2.VideoWriter_fourcc(*"MJPG"), 30,(640,480))

for frame in range(1000):
    writer.write(np.random.randint(0, 255, (480,640,3)).astype('uint8'))

writer.release()
     

我通过反复试验得到的一些事情:

     
      
  • 只使用' .avi',它只是一个容器,编解码器是重要的。
  •   
  • 指定帧大小时要小心。在构造函数中,您需要将帧大小传递为(列,行),例如640×480。然而   传入的数组,索引为(行,列)。见上文   它是如何切换的?

  •   
  • 如果您的输入图片与VideoWriter的大小不同,则会失败(通常是静默的)

  •   
  • 只传入8位图片,如果必须,手动投射阵列(.astype(' uint8'))
  •   
  • 事实上,没关系,只是总是演员。即使您使用cv2.imread加载图像,也需要转换为uint8 ...
  •   
  • 如果您没有传入3通道,8位图像,MJPG将会失败。至少我得到了一个断言失败。
  •   
  • XVID也需要一个3通道图像,但如果你不这样做,就会无声地失败。
  •   
  • H264似乎没有单通道图像
  •   
  • 如果您需要原始输出,例如从机器视觉相机,您可以使用' DIB'。 ' RAW'或者空编解码器有时会起作用。奇怪的是,如果我使用   DIB,我收到一个ffmpeg错误,但视频保存得很好。如果我使用RAW,   没有错误,但Windows视频播放器不会打开它。全部是   在VLC中很好。
  •   
     

最后,我认为关键点是OpenCV不是设计的   一个视频捕获库 - 它甚至不支持声音。 VideoWriter   是有用的,但99%的时间你最好保存所有你的   将图像放入文件夹并使用ffmpeg将它们变成有用的   视频。

答案 7 :(得分:1)

此答案涵盖了变量的含义,重要的是,输入帧和视频大小的输出大小应相同。

import cv2

save_name = "output.mp4"
fps = 10
width = 600
height = 480
output_size = (width, height)
out = cv2.VideoWriter(save_name,cv2.VideoWriter_fourcc('M','J','P','G'), fps , output_size )

cap = cv2.VideoCapture(0) # 0 for webcam or you can put in videopath
while(True):
    _, frame = cap.read()
    cv2.imshow('Video Frame', frame)
    out.write(cv2.resize(frame, output_size ))
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
out.release()
cv2.destroyAllWindows()

答案 8 :(得分:0)

Nuru的回答确实有效,但只有在frame = cv2.flip(frame,0)循环下删除此行if ret==True:才能输出视频文件而不会翻转

答案 9 :(得分:0)

举个例子:

fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out_corner = cv2.VideoWriter('img_corner_1.avi',fourcc, 20.0, (640, 480))

在那个地方,必须将X,Y定义为宽度和高度

但是,当您创建图像(例如空白图像)时,您必须将Y,X定义为高度和宽度:

    img_corner = np.zeros((480, 640, 3), np.uint8)

答案 10 :(得分:0)

正如@ปรีดาตั้งนภากร所说:Writer的大小必须与相机或文件中的帧相匹配。

您可以使用以下代码来检查您的相机是否为(640,480):

print(int(cap.get(3)), int(cap.get(4)))

对于我自己,我发现我的相机是(1280,720),然后用(1280,720)代替了(640,480)。然后可以保存视频。

答案 11 :(得分:0)

这是一个答案,仅在MacOS上进行了测试,但在Linux和Windows上也可能适用。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# Get the Default resolutions
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))

# Define the codec and filename.
out = cv2.VideoWriter('output.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:

        # write the  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()

答案 12 :(得分:0)

我没有上面提到的编解码器问题或尺寸问题。相反,我的问题是因为我的输出帧是灰度的。

我必须创建一个参数为isColor = False的VideoWriter

out = cv2.VideoWriter(output_path,
                      cv2.VideoWriter_fourcc(*'mp4v'),
                      30,
                      (INPUT_VIDEO_WIDTH,INPUT_VIDEO_HEIGHT),
                      isColor=False
                      )

API Docs中,错误指出该标志仅在Windows上受支持。我已经在Ubuntu 20.04上使用opencv-python == 4.2.0.34进行了测试,最终它可以正确地写出文件。

答案 13 :(得分:0)

import cv2

cap = cv2.VideoCapture(0)

fourcc = cv2.VideoWriter_fourcc('X','V','I','D')
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))

out = cv2.VideoWriter('output.mp4', fourcc, 20,(frame_width,frame_height),True )
print(int(cap.get(3)))
print(int(cap.get(4)))
while(cap.isOpened()):
    ret,frame = cap.read()
    if ret == True:
        print(frame.shape)
        out.write(frame)
        cv2.imshow('Frame', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cap.release()
out.release()`enter code here`

cv2.destroyAllWindows()

这可以正常工作,但是视频大小相对较小的问题意味着什么也无法捕获。因此,请确保视频和要录制的图像的高度和宽度相同。如果在捕获视频后使用某种操作,则必须确认大小(前后)。 希望可以节省一个小时