Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV Assertion Failed error: (-215) scn == 3 || scn == 4 in function cv::cvtColor works ALTERNATE times

I am a beginner in Python and OpenCV. I am trying out a piece of code which takes an input image from the webcam. The following is the piece of code.

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()

I am using both both Python 2.7 ans Python 3.4 to execute this. In both I face a strange problem. The code gives an assertion Error like this

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor, file ........\opencv\modules\imgproc\src\color.cpp, line 3737 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.error: ........\opencv\modules\imgproc\src\color.cpp:3737: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor

but it happens only on every ALTERNATE time of running. What might be the issue? I read from other posts that this error occurs when cv2.cvtColor tries to convert an empty image which does not have 3 or 4 channels. This happens usually when a wrong path is specified. For my case, since it is working fine EVERY ALTERNATE time, the source cannot be wrong. Please help!!

like image 1000
naiveDeveloper Avatar asked Jun 19 '14 07:06

naiveDeveloper


2 Answers

At least I do not find any major problem in your code, i.e. "should work". The problem seems to be in the camera driver. Cameras are different, and camera drivers are different (a.k.a. buggy).

Unfortunately, debugging the camera driver is not a very easy mission. The odd behaviour is most likely bound to the specific camera, operating system, OpenCV, and camera driver version. It is not very likely the driver can be fixed. Just try to keep everything up to date.

However, as your camera can capture every second image, there are things to do.

First, verify that the problem really is in the camera driver by replacing:

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')

As is probably evident form the code, this forces the camera to be simulated. Function create_capture is only a wrapper around VideoCapture to provide this functionality. If your code runs fine with this, the problem is in the video driver.

After verifying that, you could try to run the following code:

import cv2

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

This should create a list of 100 Trues, and the process should take a few seconds, as the camera should capture 100 consecutive images.

In your code you do not seem to use the first value in the return tuple of cam.read (ret in your code). It is Trueif the image is really captured. Also, cam.read should block until there is an image available, no need to add any delays.

Most probably you will get a list [True, False, True, False, ...] because the video driver does something odd. There is no beautiful way to fix this, but there is an ugly one. Replace your capture line by:

# 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.")

Of course, the driver may be so broken that you have to release and reopen it once in a while. Even uglier but doable, as well.

Summary: "Most probably it cannot be cured, it does not kill you, and there are medicines to alleviate the symptoms."

like image 115
DrV Avatar answered Oct 19 '22 22:10

DrV


Use a time.sleep(2) before entering the while loop or cap.read(). This time will help your camera to spool up.

like image 43
Maddoxx Avatar answered Oct 20 '22 00:10

Maddoxx