OpenCV 中用于虹膜检测的 HoughCircles 的正确用法/参数值是啥?

Posted

技术标签:

【中文标题】OpenCV 中用于虹膜检测的 HoughCircles 的正确用法/参数值是啥?【英文标题】:What are the correct usage/parameter values for HoughCircles in OpenCV for Iris detection?OpenCV 中用于虹膜检测的 HoughCircles 的正确用法/参数值是什么? 【发布时间】:2012-05-29 19:06:14 【问题描述】:

我一直在阅读有关该主题的文章,但无法以“简单的英语”了解HoughCircles(特别是CV_HOUGH_GRADIENT 之后的那些)的用法和参数。

什么是累加器阈值? 100“票”是正确的值吗?

我可以找到并“掩盖”学生,并通过Canny 函数工作,但我正在努力超越,我的问题是HoughCircles 函数。似乎无法找到 Iris 的圈子,我不知道为什么。

这是我正在处理的功能:

def getRadius(area):
    r = 1.0
    r = math.sqrt(area/3.14)
    return (r)

def getIris(frame):
    grayImg = cv.CreateImage(cv.GetSize(frame), 8, 1)
    cv.CvtColor(frame,grayImg,cv.CV_BGR2GRAY)
    cv.Smooth(grayImg,grayImg,cv.CV_GAUSSIAN,9,9)
    cv.Canny(grayImg, grayImg, 32, 2)
    storage = cv.CreateMat(grayImg.width, 1, cv.CV_32FC3)
    minRad = int(getRadius(pupilArea))
    circles = cv.HoughCircles(grayImg, storage, cv.CV_HOUGH_GRADIENT, 2, 10,32,200,minRad, minRad*2)
    cv.ShowImage("output", grayImg)
    while circles:
        cv.DrawContours(frame, circles, (0,0,0), (0,0,0), 2)
        # this message is never shown, therefore I'm not detecting circles
        print "circle!"
        circles = circles.h_next()
    return (frame)

【问题讨论】:

【参考方案1】:

HoughCircles 可能有点棘手,我建议查看this thread。包括我在内的一群人;),讨论如何使用它。关键参数是param2,即所谓的accumulator threshold。基本上,它越高,你得到的圈子就越少。而且这些圆圈有更高的正确概率。每个图像的最佳价值都不同。我认为最好的方法是在param2 上使用参数搜索。 IE。继续尝试值,直到满足您的条件(例如:有 2 个圆圈,或不重叠的最大圆圈数等)。我有一些对“param2”进行二进制搜索的代码,所以它很快就满足了条件。

另一个关键因素是预处理,尽量减少噪点并简化图像。模糊/阈值/canny的某种组合对此有好处。

无论如何,我明白了:

从您上传的图片中,使用以下代码:

import cv
import numpy as np

def draw_circles(storage, output):
    circles = np.asarray(storage)
    for circle in circles:
        Radius, x, y = int(circle[0][3]), int(circle[0][0]), int(circle[0][4])
        cv.Circle(output, (x, y), 1, cv.CV_RGB(0, 255, 0), -1, 8, 0)
        cv.Circle(output, (x, y), Radius, cv.CV_RGB(255, 0, 0), 3, 8, 0)    

orig = cv.LoadImage('eyez.png')
processed = cv.LoadImage('eyez.png',cv.CV_LOAD_IMAGE_GRAYSCALE)
storage = cv.CreateMat(orig.width, 1, cv.CV_32FC3)
#use canny, as HoughCircles seems to prefer ring like circles to filled ones.
cv.Canny(processed, processed, 5, 70, 3)
#smooth to reduce noise a bit more
cv.Smooth(processed, processed, cv.CV_GAUSSIAN, 7, 7)

cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 32.0, 30, 550)
draw_circles(storage, orig)

cv.ShowImage("original with circles", orig)
cv.WaitKey(0)

更新

我意识到我有点看错了你的问题!您实际上想要找到 iris 边缘。他们没有像学生那样明确定义。所以我们需要尽可能地帮助HoughCircles。我们可以这样做:

    指定虹膜的大小范围(我们可以根据瞳孔大小计算出一个合理的范围)。 增加圆心之间的最小距离(我们知道两个虹膜永远不会重叠,因此我们可以安全地将其设置为我们的最小虹膜尺寸)

然后我们需要再次对param2 进行参数搜索。将上述代码中的“HoughCircles”行替换为:

cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 100.0, 30, 150,100,140)

告诉我们这个:

这还不错。

【讨论】:

谢谢飞梭。寻找 Iris 的外部边界的过程是否相同?如您所见,我的问题不是瞳孔,而是外眼圈。我使用常规颜色隔离得到了质心,可以在这里看到bit.ly/Lqaz4J 下班回来后我会试试你的代码 =) 再次感谢。 @pctroll - 对不起,我想念你的问题!我已经更正了我的答案以做你所追求的:)。您可能可以使用您的质心信息来更好地定位圆圈。 @flaxel - 谢谢!是的,我可以更好地锻炼中心。然而,尽管有噪音,该函数如何找到圆是非常有趣的(我读过霍夫变换,但我非常直观,我有反序的 Canny 和 Smooth)。【参考方案2】:

我的替代建议是使用阈值和 Blob 分析。虹膜检测比使用 canny edge 和 hough 变换更简单。

我的方法是...首先你设置阈值。选取任何阈值,直到黑白图像仅产生(黑色)虹膜和睫毛。

然后通过在 XX 处输入 blob 分析值最小长度和 YY 处最小宽度来分离虹膜和睫毛。 XX 和 YY 值是虹膜长度和宽度的值。

【讨论】:

+1 用于使用 Blob 分析而不是霍夫圆检测。我倾向于使用 OpenCV 的 Circle Hough 变换得到非常不精确的结果,好像参数空间搜索的步长太大了。我可以清楚地定义完整的圆圈,只需将中心点调整到一侧或两个像素就会使检测到的圆圈更精确地适合图像中的对比度变化(如在接受答案的图像中可见,也是)。斑点往往会给我一个更精确的中心点和半径。

以上是关于OpenCV 中用于虹膜检测的 HoughCircles 的正确用法/参数值是啥?的主要内容,如果未能解决你的问题,请参考以下文章

虹膜识别基于形态学实现虹膜检测matlab源码

霍夫圆没有检测到眼睛虹膜

虹膜识别基于matlab GUI形态学虹膜检测含Matlab源码 959期

Hough 变换检测圆----Matlab实现(以虹膜检测为例)

图像检测基于Hough变换的人眼虹膜定位matlab源码

用于行李检测的 OpenCV 和 SVM 训练