About interpreting the error. It comes from hough.cpp#L1659:
CV_Assert(!_image.empty() && _image.type() == CV_8UC1 && (_image.isMat() || _image.isUMat()));
Breaking it down, all the following conditions have to be true:
!_image.empty()
: the input image should not be empty;
_image.type() == CV_8UC1
: the input image must be 8U
(8-bit unsigned, np.uint8
) and C1
(single-channel);
_image.isMat() || _image.isUMat()
: check if the input is Mat
or UMat
(in Python, it has to be a numpy array);
Regarding your specific error message (error: (-215) !_image.empty() && _image.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) && (_image.isMat() || _image.isUMat())
):
I'll try to complement @Mark Setchell's answer, simply because I was curious and I want to share :)
If you look at the documentation, cv2.HoughCircle()
is part of the imgproc module (under the Feature Detection "submodule"). The documentation says that the only implemented method is the HOUGH_GRADIENT (aka 21HT, i.e., Two stage Hough Transform), and they point out to the reference paper "Comparative study of Hough Transform methods for circle finding" (1990) :). If you cannot access because of the paywall, you can access the 1989's version for free). In the paper, the authors comment:
The HT method of shape analysis uses a constraint equation relating points in a feature space to possible parameter values of the searched for shape. For each
feature point, invariably edge points, votes are accumulated for all parameter combinations which satisfy the constraint. [...]
Later, they write:
If edge direction information is available, then one way to reduce the storage and computational demands of circle finding is to decompose the problem into two
stages [...]
Therefore, if you want to stick to the 21HT, you basically need both edges and edge direction information. For instance, you could get the edge direction information via Sobel
(e.g., dx
and dy
), and use these already computed dx
and dy
to get the edges using Canny
. In fact, this is what the OpenCV implementation does. If you navigate to modules/imgproc/src/hough.cpp
, you can see the Sobel+Sobel+Canny operations here.
So, what? Well, it means that if you have another method (or you want to propose a new one, why not?) that is able to return edges and edge direction information that are better suited for your case (maybe the colors have a different meaning in your case), then you can just replace these 3 lines (Sobel+Sobel+Canny) with your method and re-use the rest of the implementation (cool, huh?). If you are feeling inspired :), you can take a look at "A Short History of Color Edge Detection" and start from there.
Then, why do we need single-channel inputs? Well, basically because we need edges, and they are usually represented as single-channel images. In addition, the implementation only supports single-channel edges and edge direction information so far. However, most of these concepts could be extended to multi-channel inputs. I think that, because there are no generic solutions (probably these concepts change in a case-by-case basis) and very few people would benefit from, no one bothered to provide any implementation so far.
Sorry for the long answer. I know the TL;DR "the method requires single-channel input" is enough. I got curious and wanted to share =]
cv2.HoughCircles()
uses single-channel inputs. The answer is long, but it is your fault: your question made me curious :) – Nonintervention