OpenCV断言失败错误:(-215)scn == 3 || scn == 4在函数cv::cvtColor中的替代时间工作。

8

我是Python和OpenCV的初学者。我正在尝试一段从网络摄像头获取输入图像的代码。以下是代码片段。

cam = create_capture(video_src, fallback='synth:bg=../cpp/lena.jpg:noise=0.05')    
while True:
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = cv2.equalizeHist(gray)

    rects = detect(gray, cascade)
    vis = img.copy()
    draw_rects(vis, rects, (0, 255, 0))
    for x1, y1, x2, y2 in rects:
        roi = gray[y1:y2, x1:x2]
        vis_roi = vis[y1:y2, x1:x2]
        subrects = detect(roi.copy(), nested)
        draw_rects(vis_roi, subrects, (255, 0, 0))
    dt = clock() - t

    draw_str(vis, (20, 20), 'time: %.1f ms' % (dt*1000))

    cv2.imshow('facedetect', vis)
    if 0xFF & cv2.waitKey(5) == 27:
        break

    cv2.setMouseCallback('facedetect',capture_image)

cv2.destroyAllWindows()

我同时使用Python 2.7和Python 3.4来执行此操作。在两个版本中都遇到了一个奇怪的问题。代码会出现一个断言错误,像这样:
OpenCV错误:在cv :: cvtColor的文件……\ opencv \ modules \ imgproc \ src \ color.cpp第3737行中断言失败(scn == 3 || scn == 4) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.error: ........\opencv\modules\imgproc\src\color.cpp:3737: error: (-215) scn == 3 || scn == 4在函数cv :: cvtColor中
但它仅在每次运行的每个ALTERNATE时间发生。可能是什么问题?我从其他帖子中了解到,当cv2.cvtColor尝试转换没有3或4个通道的空图像时,会发生此错误。通常情况下,这是因为指定了错误的路径。对于我的情况,由于每隔一段时间就可以正常工作,因此源应该不会有问题。请帮忙!!

你的代码中有一行调试语句 "print ...",它输出了什么?为了确保,你甚至可以打印 img.dtype - DrV
1
您传递给 waitKey() 的参数可能太小了。如果相机在 5ms 内不能准备好新的帧,则可能返回空帧。请尝试传递更大的时间增量。 - Aurelius
@DrV - 打印调试行每隔一段时间就会输出图像矩阵...程序失败时,则输出空矩阵。 - naiveDeveloper
@Aurelius 至少原则上 cam.read 的调用应该在新帧可用之前阻塞。 - DrV
2个回答

6

我发现你的代码没有显著问题,也就是说“应该能运行”。问题似乎出现在相机驱动程序中。不同的相机和相机驱动程序(即有错误的程序)不同。

不幸的是,调试相机驱动程序并不是一项非常容易的任务。奇怪的行为很可能与特定相机、操作系统、OpenCV和相机驱动程序版本有关。很不可能修复驱动程序。只需尝试保持一切都更新。

然而,由于您的相机可以捕获每秒的图像,还有事情需要做。

首先,请通过替换以下内容来验证问题确实存在于相机驱动程序中:

cam = create_capture(video_src, fallback='synth:bg=../cpp/lena.jpg:noise=0.05')

by

cam = create_capture('synth:bg=../cpp/lena.jpg:noise=0.05')

很显然,这段代码强制模拟相机。函数create_capture只是对VideoCapture的包装,以提供此功能。如果您的代码使用此功能正常运行,则问题可能出在视频驱动程序上。

在验证后,您可以尝试运行以下代码:

import cv2

cam = cv2.VideoCapture(0)
cam.open(0)
results = [ cam.read()[0] for i in range(100) ]
print results

这应该创建一个包含100个True的列表,整个过程应该只需要几秒钟,因为相机应该会捕捉到100个连续的图像。
在你的代码中,似乎没有使用cam.read返回元组的第一个值(也就是你的代码中的ret)。如果图像真的被捕获,则它应该是True。另外,cam.read应该阻塞直到有可用的图像,不需要添加任何延迟。
很可能你会得到一个列表[True,False,True,False,...],因为视频驱动程序会做一些奇怪的事情。没有很好的修复方法,但有一个丑陋的解决办法。将捕获行替换为:
# max. 10 retries
for i in range (10):
    ret, img = cam.read()
    if ret:
        break
else:
    # capture failed even after 10 tries
    raise MyExceptiom("Video driver does not like me.")

当然,驱动程序可能会崩溃,你需要偶尔释放并重新打开它。这看起来很丑陋,但是可以实现。

总结:“最有可能无法治愈,但不会致命,并且有药物可以缓解症状。”


嘿,这是因为我在虚拟机中运行Ubuntu16.0.4吗?raise MyException("Video driver does not like me.") NameError: name 'MyException' is not defined - Mona Jalal

2

在进入while循环或cap.read()之前,请使用time.sleep(2)。这段时间将有助于您的摄像机启动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接