Suh*_*pta 5 python opencv image-processing computer-vision hough-transform
在检测圆圈之前,我正在用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
Run Code Online (Sandbox Code Playgroud)
我无法理解它,因此无法理解我可能做错了什么。这是我所做的事情的片段。
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
)
Run Code Online (Sandbox Code Playgroud)
当我调用HoughCircles函数时发生错误。我可能做错了什么?
关于解释错误。它来自hough.cpp#L1659:
CV_Assert(!_image.empty() && _image.type() == CV_8UC1 && (_image.isMat() || _image.isUMat()));
Run Code Online (Sandbox Code Playgroud)
分解一下,以下所有条件都必须成立:
!_image.empty():输入图像不能为空;_image.type() == CV_8UC1:输入图像必须是8U(8位无符号,np.uint8)和C1(单通道);_image.isMat() || _image.isUMat():检查输入是否为Mator UMat(在 Python 中,它必须是 numpy 数组);关于您的具体错误消息(error: (-215) !_image.empty() && _image.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) && (_image.isMat() || _image.isUMat())):
CV_StsAssert;CV_8UC1。您想知道为什么吗?你应该:)我们开始吧:
CV_8UC1CV_MAKETYPE(CV_8U,1):: 从#define CV_8UC1 CV_MAKETYPE(CV_8U,1)CV_MAKETYPE(0,1):: 从#define CV_8U 0(CV_MAT_DEPTH(0) + (((1)-1) << CV_CN_SHIFT)):: 从#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))(((0) & CV_MAT_DEPTH_MASK) + (((1)-1) << CV_CN_SHIFT)):: 从#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK)(((0) & (CV_DEPTH_MAX - 1)) + (((1)-1) << CV_CN_SHIFT)):: 从#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1)(((0) & ((1 << CV_CN_SHIFT) - 1)) + (((1)-1) << CV_CN_SHIFT)):: 从#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)(((0) & ((1 << 3) - 1)) + (((1)-1) << 3)):: 从#define CV_CN_SHIFT 3我会尝试补充@Mark Setchell的答案,只是因为我很好奇并且想分享:)
如果您查看文档,它是imgproccv2.HoughCircle()模块的一部分(在功能检测“子模块”下)。文档说唯一实现的方法是HOUGH_GRADIENT(又名21HT,即两阶段霍夫变换),并且他们指出了参考论文“用于圆查找的霍夫变换方法的比较研究”(1990):)。如果您因付费墙而无法访问,您可以免费访问 1989 年的版本)。在论文中,作者评论道:
形状分析的 HT 方法使用将特征空间中的点与搜索形状的可能参数值相关联的约束方程。对于每个特征点,总是边缘点,为满足约束的所有参数组合累积投票。[...]
后来,他们写道:
如果边缘方向信息可用,那么减少圆查找的存储和计算需求的一种方法是将问题分解为两个阶段 [...]
因此,如果你想坚持使用21HT,你基本上需要边缘和边缘方向信息。例如,您可以通过Sobel(例如,dx和dy)获取边缘方向信息,并使用这些已经计算出的dx和dy来使用 获取边缘Canny。事实上,这就是 OpenCV 实现的作用。如果您导航至,您可以在此处modules/imgproc/src/hough.cpp看到 Sobel+Sobel+Canny 操作。
所以呢?好吧,这意味着如果您有另一种方法(或者您想提出一种新方法,为什么不呢?),它能够返回更适合您的情况的边缘和边缘方向信息(也许颜色在你的情况),然后你可以用你的方法替换这 3 行(Sobel+Sobel+Canny)并重新使用其余的实现(很酷,是吧?)。如果您受到启发:),您可以看一下“颜色边缘检测简史”并从那里开始。
那么,为什么需要单通道输入呢?嗯,基本上是因为我们需要边缘,并且它们通常表示为单通道图像。此外,到目前为止,该实现仅支持单通道边缘和边缘方向信息。然而,这些概念中的大多数都可以扩展到多通道输入。我认为,由于没有通用的解决方案(可能这些概念会根据具体情况而变化)并且很少有人会从中受益,因此到目前为止没有人愿意提供任何实现。
抱歉回答太长。我知道 TL;DR“该方法需要单通道输入”就足够了。我很好奇并想分享=]