0

I have written a program that captures images from an usb camera and track object position based on detecting colors in each frame. Intermittent, (this can happen after 1 minute, 10 minutes or half an hour) I get the error message:

OpenCV Error: Assertion failed (depth == CV_8U || depth == CV_16U || depth == CV_32F) in cv::cvtColor, file C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\imgproc\src\color.cpp, line 7343
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 685, in runfile
    execfile(filename, namespace)
  File "C:\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 71, in execfile
    exec(compile(scripttext, filename, 'exec'), glob, loc)
  File "D:/file.py", line 371, in <module>
    hsv_frame = cv2.cvtColor(blur_frame, cv2.COLOR_BGR2HSV)
cv2.error: C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\imgproc\src\color.cpp:7343: error: (-215) depth == CV_8U || depth == CV_16U || depth == CV_32F in function cv::cvtColor

The process I follow is:

  • capture a frame with the camera, cap = cv2.VideoCapture(1) / cap.read()
  • transform geometry, cv2.warpPerspective
  • gaussian blurr filter, cv2.GaussianBlur
  • BGR to HSV conversion, cv2.cvtColor(blur_frame, cv2.COLOR_BGR2HSV)
  • Contour finding and analyzing, cv2.threshold

It works flawless, sometimes. And then I suddenly get the error message that stops the program. I think it is strange that it happens at such a late step in the process. If it was due to the camera driver being corrupted, the error should have occurred earlier?

Any thoughts what might be causing this?

EDIT 1: Can it be that i grab the frame from the global variable holding the frame, while it is being written to from the stream thread?

EDIT 2: Problem occurred due to lack of sync between threads. Moved the capture to the processing loop, and now it works perfect, and at almost the same speed as when in separate threads...

2
  • Likelyhood is your camera hasnt read in an image and you are trying to do some process on an empty one. Add a check that if the image is empty or not as large as you thin kit should be you dont do your processing Commented Jan 13, 2016 at 14:43
  • l already did a test on the return value from cap.read(), and it returns True even when the error occurs. How can I easiest check if it is empty or corrupted in other ways? Commented Jan 13, 2016 at 16:14

2 Answers 2

1

As GPPK commented, it is likely that your camera sometimes does not capture a picture. This may happen due to race conditions, problems in your IO system, high CPU load etc. In the openCV documentation you can see that the method retrieve returns a boolean as well as the image.
cv2.VideoCapture.retrieve([image[, channel]]) → retval, image
When capturing, just check that retval is True and if it is not, try to capture another frame. If capturing fails repeatedly, the connection to your camera broke.

Sign up to request clarification or add additional context in comments.

7 Comments

Hmm. l already added the check of the return value from cap.read(), and it returns True even when the error occurs. The image capturing is done in a separate thread - and it continues to run even though the image processing loop has stopped.
Mh, thats odd. You should wrap tha failing call into a try-except bloc and print the size and type of the image array and if it is None:
From your edit I learn that you access the camera with two different threads? If so, it is crutial to know how you handle synchronisation. Some example code would be nice.
I acess the camera in one thread, and stores the image in a global variable called raw_frame. In the main loop of the program i set process_frame = raw_frame, and do all the image processing on the copy of raw_frame. So I actually have no synchronization. Do you think the problem is that I copy the raw_frame, at the same time as it is been written to? If so, how can I avoid that in a simple way?
I think the simpliest way is to access the camera in the same thread in which you do the processing. By the way: process_frame = raw_frame does not create a copy but will just copy the address of the buffer. To create a copy, use copyOfArray = np.array(arrayToCopy) with import numpy as np. I don't think that you will have a great speedup by using two threads. Anyways, I would try the simple one-thread solution first and if it is to slow, care about speed afterwards.
|
0

As @GPPK commented, it is likely that your camera sometimes does not capture a picture. This may happen due to race conditions, problems in your IO system, high CPU load etc. In the openCV documentation you can see that the method retrieve returns a boolean as well as the image.

cv2.VideoCapture.retrieve([image[, channel]]) → retval, image

When capturing, just check that retval is True and if it is not, try to capture another frame.

If capturing fails repeatedly, the connection to your camera broke.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.