OpenCV Assertion失败错误:( - 1515)scn == 3 ||函数cv :: cvtColor中的scn == 4的工作时间是ALTERNATE

时间:2014-06-19 07:02:40

标签: python opencv computer-vision

我是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错误:断言失败(scn == 3 || scn == 4)在cv :: cvtColor中,文件........ \ opencv \ modules \ imgproc \ src \ color.cpp,第3737行       gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)   cv2.error:........ \ opencv \ modules \ imgproc \ src \ color.cpp:3737:错误:(-215)scn == 3 ||函数cv :: cvtColor中的scn == 4

但它只在每个ALTERNATE运行时发生。可能是什么问题?我从其他帖子中读到,cv2.cvtColor尝试转换没有3或4个通道的空图像时会发生此错误。通常在指定错误路径时会发生这种情况。对于我的情况,由于它在每个替换时间都正常工作,因此源不会出错。请帮忙!!

2 个答案:

答案 0 :(得分:6)

至少我没有在你的代码中发现任何重大问题,即"应该工作"。问题似乎出现在相机驱动程序中。相机是不同的,相机驱动程序是不同的(a.k.a.越野车)。

不幸的是,调试相机驱动程序并不是一件容易的事。奇怪的行为很可能与特定的相机,操作系统,OpenCV和相机驱动程序版本绑定。驱动程序不太可能被修复。尽量保持最新状态。

但是,由于您的相机可以拍摄每一张图像,因此可以做些事情。

首先,通过替换以下内容验证问题是否真的出现在相机驱动程序中:

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

通过

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 Trues的列表,该过程应该需要几秒钟,因为相机应该捕获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.")

当然,驱动程序可能会破坏,您必须偶尔释放并重新打开它。甚至更丑陋但也可行。

总结:"很可能它不能治愈,它不会杀死你,并且有药物可以缓解症状。"

答案 1 :(得分:1)

在输入while循环或time.sleep(2)之前使用cap.read()。这一次将帮助您的相机进行调整。