将 HoughCircles 与 3 通道输入一起使用时出错

Error using HoughCircles with 3-channel input

在检测圆圈之前,我将 red 通道替换为 green 通道。更换通道后,我将其通过模糊过滤器,然后进行霍夫变换以检测圆圈。但是当我这样做时,我收到一条糟糕的错误消息:

OpenCV(3.4.1) Error: Assertion failed (!_image.empty() && _image.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) && (_image.isMat() || 

_image.isUMat())) in HoughCircles, file /io/opencv/modules/imgproc/src/hough.cpp, line 1659
Traceback (most recent call last):

  File "circle_light.py", line 44, in <module>
    param1=param1,param2=param2,minRadius=minRadius,maxRadius=maxRadius)

cv2.error: OpenCV(3.4.1) /io/opencv/modules/imgproc/src/hough.cpp:1659: error: (-215) !_image.empty() 

&& _image.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) && (_image.isMat() || _image.isUMat()) in function HoughCircles

我无法从中得到任何意义,因此无法理解我可能做错了什么。这是我所做的片段。

import cv2

img = cv2.imread("images/{}".format("img.png"), 1)

b,g,r = cv2.split(img)
img = cv2.merge([b,g,g])
img = cv2.GaussianBlur(img,(5,5),0)

minDist = 11
param1 = 20
param2 = 20
minRadius = 10
maxRadius = 20

circles = cv2.HoughCircles(
    img, cv2.HOUGH_GRADIENT, 1, minDist,
    param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius
)

调用HoughCircles函数时出现错误。我可能做错了什么?

您只能在单通道(灰度)图像上调用 cv2.HoughCircles(),您的图像有 3 个通道。

Documentation.

关于解释错误。它来自 hough.cpp#L1659:

CV_Assert(!_image.empty() && _image.type() == CV_8UC1 && (_image.isMat() || _image.isUMat()));

将其分解,必须满足以下所有条件:

  • !_image.empty():输入图片不能为空;
  • _image.type() == CV_8UC1:输入图像必须是8U(8位无符号,np.uint8)和C1(单通道);
  • _image.isMat() || _image.isUMat():检查输入是Mat还是UMat(在Python中,必须是numpy数组);

关于您的特定错误消息 (error: (-215) !_image.empty() && _image.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) && (_image.isMat() || _image.isUMat())):


我会尝试补充 @Mark Setchell 的答案,只是因为我很好奇并且想分享:)

如果您查看文档,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)。在论文中,作者评论:

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. [...]

后来,他们写道:

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 [...]

因此,如果你想坚持21HT,你基本上需要边缘和边缘方向信息。例如,您可以通过 Sobel(例如 dxdy)获取边缘方向信息,并使用这些已经计算出的 dxdy 来获得使用 Canny 的边缘。事实上,这就是 OpenCV 实现所做的。如果您导航到 modules/imgproc/src/hough.cpp, you can see the Sobel+Sobel+Canny operations here.

那么,什么?嗯,这意味着如果你有另一种方法(或者你想提出一个新方法,为什么不呢?)能够 return 更适合你的情况的边缘和边缘方向信息(也许 colors 在你的情况下有不同的含义),那么你可以用你的方法替换这 3 行(Sobel+Sobel+Canny)并重新使用其余的实现(很酷,是吧? ).如果你有灵感:),你可以看看“A Short History of Color Edge Detection”然后从那里开始。

那么,为什么我们需要单通道输入?好吧,主要是因为我们需要边缘,它们通常表示为 单通道图像 。另外,implementation目前只支持单通道的边缘和边缘方向信息。然而,这些概念中的大多数都可以扩展到多通道输入。我认为,因为没有通用的解决方案(可能这些概念会根据具体情况而改变)并且很少有人会从中受益,所以到目前为止还没有人费心提供任何实施。

抱歉回答太长了。我知道 TL;DR "the method requires single-channel input" 就足够了。我很好奇,想分享 =]