Python 使用OpenCV保存视频时出现错误消息

Python 使用OpenCV保存视频时出现错误消息,python,python-3.x,opencv,Python,Python 3.x,Opencv,当我运行我的代码时,我遇到了一个错误,我不知道发生了什么,但我认为是当程序完成时,因为我得到了我想要的结果,即将现有视频转换为灰度并保存它 cv2.error:OpenCV4.1.0 C:\projects\opencv python\opencv\modules\imgproc\src\color.cpp:182:error:-215:Assertion失败_函数“cv::cvtColor”中的src.empty 谢谢大家! 可能存在视频中至少一帧未正确读入的情况。这就是cv2.cvtColo

当我运行我的代码时,我遇到了一个错误,我不知道发生了什么,但我认为是当程序完成时,因为我得到了我想要的结果,即将现有视频转换为灰度并保存它

cv2.error:OpenCV4.1.0 C:\projects\opencv python\opencv\modules\imgproc\src\color.cpp:182:error:-215:Assertion失败_函数“cv::cvtColor”中的src.empty


谢谢大家!

可能存在视频中至少一帧未正确读入的情况。这就是cv2.cvtColor方法抛出错误的原因,因为您提供的帧数据为空

你应该考虑使用CV2.VeloCopTr.Read的第一个输出来确保视频帧被正确捕获,然后将其写入文件。第一个输出是一个标志,用于确定当前帧是否已成功读入。此外,您还需要处理视频的结尾。在这种情况下,标志将为False,因此我们应该退出循环。最后,如果您打算写入灰度帧,那么cv2.VideoWriter中有一个可选的第五个参数isColor,我们可以将其设置为False,以允许我们直接写入灰度帧。这意味着不再需要调用cv2.cvtColor

我还建议您从视频文件中推断帧的宽度和高度,而不是自己设置。这样,输入和输出分辨率是相同的。最后,完成后不要忘了释放cv2.VideoWriter对象,我为视频文件添加了一个附加检查,以查看它是否已正确打开:

import numpy as np
import cv2
import sys

cap = cv2.VideoCapture('videos/output.avi')

# Check to see if the video has properly opened
if not cap.isOpened():
    print("File could not be opened")
    sys.exit(1)

fourcc = cv2.VideoWriter_fourcc(*'XVID')
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # Get the frame width and height
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) 

# Change
out = cv2.VideoWriter('results/output.avi', fourcc, 20.0, (frame_width, frame_height), isColor=False)

while True:
    ret, frame = cap.read() # New

    if not ret: # New
        break # Get out if we don't read a frame successfully

    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    out.write(frame)

    # Key events
    key = cv2.waitKey(1)
    if key == 27:  # esc
        break

cap.release()
out.release() # New
cv2.destroyAllWindows()

作为一个小提示,您没有显示任何窗口,因此cv2.destroyAllWindows在这里是多余的。考虑从代码中删除它。

,这个答案有另一种方法,你也可以通过改变B、G、R值

前面的相应权重来提取不同的颜色。
import cv2
cap = cv2.VideoCapture('videos/output.avi')
frame_width = int(cap.get(3))  # finds the frame width automatically
frame_height = int(cap.get(4))  # finds the frame height automatically

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('results/outpy.avi', cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), 10, (frame_width, frame_height))

while (cap.isOpened()): # value is true if the file is successfully opened.
    ret, frame = cap.read()
    if ret == True:  # checks if the return value is True or False. False means file ended.
        # grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # the grey matrix has a different shape than the frame matrix
        # that's why the output files were blank
        # to circumvent this RGB2GRAY, I manually added the "NORMALIZED" R,G,B values.

        frame[:,:,0] = 0.114*frame[:,:,0]+0.587*frame[:,:,1]+0.299*frame[:,:,2] #multiplying normalized co-efficients to B,G,R
# for extracting red, make 0.299 as 1.0 and others as 0.0; same goes for other colours.
        frame[:, :, 1]=frame[:,:,0] # making the G and R values same as the B.
        frame[:, :, 2]=frame[:,:,0]
        # now frame is a 3d grayscale matrix. Identical to the cv2.cvtColor method....except it is 3d
        # now frame is grey scaled...R,G,B values for each pixel,holds the same number....
        out.write(frame)
    else:
        break
cap.release()
out.release()
cv2.destroyAllWindows()

rayryeng先生的代码创建了空白的avi文件,所以我修复了它。我已经用avi视频测试了我的代码。它工作了…耶!这是行不通的,因为在添加代码示例时,您弄乱了while循环体的缩进。“请把它修好。”丹玛舍克:是的,我删除了我的答案。这是当你在手机上并且没有彻底测试代码时发生的情况。不幸的是,你试图绕过RGB2GRAY的尝试非常糟糕-原始的灰度转换不是它加权的3个通道的简单平均值,请参阅。因此,您的输出将不同于预期。@DebajyotiMajumder在转换为灰度后,您应该真正使用cv2.cvtColorframe、cv2.COLOR_GRAY2BGR。您的解决方法无法产生正确的结果。我必须对此进行否决,因为即使在您读取视频文件的最后一帧后,cap.isOpened仍将返回true。一旦你到达终点,将会发生的事情是ret将变成失败,框架将变成无。。。。永远由于if not ret:continue位,您的脚本将陷入无限循环。@DanMašek是的,当我不测试代码时就会发生这种情况。@DanMašek我想我已经修复了它。请再给我核实一次。是的,这看起来很合理。我将在while循环之前添加cap.isOpened的单个测试,以检查输入文件是否正确打开。最后3行在这里是不必要的,但它没有伤害。也许可以为numpy和cv2添加导入语句以使其完整。最后,我可能会添加对输入帧形状的验证,因为如果它与打开VideoWriter时指定的640x480不匹配,我似乎只能得到一个5kB的视频,无法播放。不客气,我的+1已经存在。我只是冒昧地去掉了几个神奇的数字,用命名常量代替它们。
import cv2
cap = cv2.VideoCapture('videos/output.avi')
frame_width = int(cap.get(3))  # finds the frame width automatically
frame_height = int(cap.get(4))  # finds the frame height automatically

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('results/outpy.avi', cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), 10, (frame_width, frame_height))

while (cap.isOpened()): # value is true if the file is successfully opened.
    ret, frame = cap.read()
    if ret == True:  # checks if the return value is True or False. False means file ended.
        # grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # the grey matrix has a different shape than the frame matrix
        # that's why the output files were blank
        # to circumvent this RGB2GRAY, I manually added the "NORMALIZED" R,G,B values.

        frame[:,:,0] = 0.114*frame[:,:,0]+0.587*frame[:,:,1]+0.299*frame[:,:,2] #multiplying normalized co-efficients to B,G,R
# for extracting red, make 0.299 as 1.0 and others as 0.0; same goes for other colours.
        frame[:, :, 1]=frame[:,:,0] # making the G and R values same as the B.
        frame[:, :, 2]=frame[:,:,0]
        # now frame is a 3d grayscale matrix. Identical to the cv2.cvtColor method....except it is 3d
        # now frame is grey scaled...R,G,B values for each pixel,holds the same number....
        out.write(frame)
    else:
        break
cap.release()
out.release()
cv2.destroyAllWindows()