我有一个视频,其中记录了汽车的前视图。该文件是一个.mp4文件,我想处理单个图像,以便提取更多信息(对象,车道线等)。问题是,当我想从处理后的文件中创建视频时,出现错误。这是我到目前为止所做的:

使用cv2.VideoCapture()打开了视频-运行正常

使用cv2.imwrite()保存了视频的单帧-工作正常

使用cv2.VideoWriter()从单个帧创建视频-工作正常

使用cv2.cvtColor(),cv2.GaussianBlur()和cv2.Canny()对视频进行后处理-工作正常

用已处理的图像创建视频-不起作用。

这是我使用的代码:

enter code here
def process_image(image):
gray = functions.grayscale(image)
blur_gray = functions.gaussian_blur(gray, 5)
canny_blur = functions.canny(blur_gray, 100, 200)
return canny_blur
process_on =0
count =0
video= cv2.VideoWriter("output.avi", cv2.VideoWriter_fourcc(*"MJPG"), 10, (1600, 1200))
vidcap = cv2.VideoCapture('input.mp4')
success,image = vidcap.read()
success = True
while success:
processed = process_image(image)
video.write(processed)

这是我得到的错误:

OpenCV错误:cv :: mjpeg :: MotionJpegWriter :: write,file D:\ Build \ OpenCV \ opencv-3.2.0 \ modules \中的声明失败(img.cols == width && img.rows == height * 3) videoio \ src \ cap_mjpeg_encoder.cpp,第834行回溯(最近一次通话最近):文件“ W:/Roborace/03_Information/10_Data/01_Montreal/camera/right_front_camera/01_Processed/Roborace_CAMERA_create_video.py”,第30行,在video.write(已处理)cv2.error:D:\ Build \ OpenCV \ opencv-3.2.0 \ modules \ videoio \ src \ cap_mjpeg_encoder.cpp:834:error:(-215)img.cols == width && img.rows == height * 3在函数cv :: mjpeg :: MotionJpegWriter :: write中

我的建议是:由于RGB颜色字段,普通图像具有3个维度。处理的图像仅具有一维。我如何在cv2.VideoWriter函数中进行调整。

谢谢你的帮助

解决方案

该VideoWriter()班只写彩色图像,而不是灰度图像,除非你是在Windows上,它看起来就像你可能会从你的输出路径来判断。在Windows上,可以将可选参数isColor=0或isColor=False传递给VideoWriter()构造函数来编写单通道图像。否则,简单的解决方案是将您的灰度帧堆叠到三通道图像中(您可以使用cv2.merge([gray, gray, gray])并编写该图像。

参数:

isColor–如果不为零,则编码器将期望并编码彩色框架,否则它将与灰度框架一起使用(仅Windows当前支持该标志)。

因此,默认情况下,isColor=True该标志不能在非Windows系统上更改。所以简单地做:

video.write(cv2.merge([processed, processed, processed])

应该修补你。即使Windows变体允许编写灰度框架,也最好使用第二种方法来实现平台独立性。

同样,正如Zindarod在下面的注释中提到的那样,此处的代码还有许多其他可能的问题。我假设您粘贴的修改后的代码实际上并未在此处运行,否则您将进行修改...如果是这种情况,请仅发布最少,完整且可验证的代码示例。

首先,您的循环没有结束条件,因此它是不确定的。其次,您要对帧大小进行硬编码,而VideoWriter()不是简单地将图像调整为该大小。您必须提供将传递到中的框架的大小VideoWriter()。请确保在写入之前将框架的大小调整为相同的大小,或者VideoWriter使用VideoCapture()设备中定义的框架大小(使用框架大小属性的.get()方法)来创建框架。

此外,您只读取循环外的第一帧。也许这是故意的,但如果要处理视频的每一帧,则当然需要循环读取它们,进行处理,然后再编写。

Lastly you should have some better error catching in your code. For e.g., see the OpenCV "Getting Started with Video" Python tutorial. The "Saving a Video" section has the proper checks and balances: run the loop while the video capture device is opened, and process and write the frame only if the frame was read properly; then once it is out of frames, the .read() method will return False, which will allow you to break out of the loop and then close the capture and writer devices. Note the ordering here---the VideoCapture() device will still be "opened" even when you've read the last frame, so you need to close out of the loop by checking the contents of the frame.