如何在Python中访问OpenCV的HoughCircles结果?
我正在开发一个与虹膜相关的生物识别算法的概念验证。我想在一系列图像上测试这个算法,但为了做到这一点,我需要知道虹膜的边界。根据这里的方法,我对图像进行了过滤和智能阈值处理(使用了Otsu的方法),这样我就只剩下了黑色的瞳孔圆圈。我尝试使用OpenCV的HoughCircles
方法,但关于非C(++)的文档很少。以下是我目前在这一部分的代码:
# Convert PIL to openCV type
cvImage = cv.CreateImageHeader(inputImage.size, cv.IPL_DEPTH_8U, 1)
cv.SetData(cvImage, inputImage.tostring())
self.cvSize = cv.GetSize(cvImage)
# Create storage for circles (there should only be one)
storage = cv.CreateMat(50, 1, cv.CV_32FC3)
# Get circles (why doesn't this work?)
circles = cv.HoughCircles(cvImage,storage,cv.CV_HOUGH_GRADIENT,2,(self.cvSize[0])/4,200,100);
最后一行是我想问的地方。我在网上找了好几篇帖子(大多数是关于C/C++的,或者是5年以上的旧帖子),最终写出了这一行。它没有返回任何错误。那么我该如何访问结果呢?我应该访问circles
还是storage
?我该怎么访问它们?我试过这个问题中的建议,但正如提问者所说,cvMat
类型是不可迭代的,所以这行不通。看起来写我自己的圆形霍夫变换会比处理这个库稀少的文档要简单,但我觉得我可能遗漏了一些简单的东西。
顺便问一下,我该如何优化参数,以便在合理的时间内总是返回一个适合瞳孔的圆?
3 个回答
一些解决方案:
grayImage = cv2.cvtColor(circleImage, cv.CV_BGR2GRAY)
circles = cv2.HoughCircles(grayImage, cv.CV_HOUGH_GRADIENT, 2, 80, None, 100, 100, 50, 150)
还有:
all_circles = circles[0]
for circle in all_circles:
#circle[0] - x
#circle[1] - y
#circle[2] - radius
你在用 OpenCV 2.3.x 吗?它的说明文档好像建议你可以这样做:
circles = cv2.HoughCircles(circleImage, cv.CV_HOUGH_GRADIENT, 2, 32, 200, 100);
for (x, y, radius) in circles:
# do something with circle
注意: cv.HoughCircles 可能没有返回任何圆(这可能是因为参数设置太严格),所以你可以检查一下 circles 是否为空。
希望这能帮到你!
这里提到的 cv.HoughLines2
的例子完全不同,因为它的内存存储方式是这样的:
storage2 = cv.CreateMemStorage(0)
而 HoughCircles
可不行。HoughCircles
只能处理 cvMat
类型的存储,比如:
storage = cv.CreateMat(image.width, 1, cv.CV_32FC3)
需要注意的是,它只能有一行,并且表示方式应该是32位浮点数,且有3个通道。
比如,你有以下这行代码:
circles=cv.HoughCircles(image,storage, cv.CV_HOUGH_GRADIENT, 100, 300,100,50)
由于使用了 cvMat
,这个函数的返回值是 NULL
,在Python中这意味着没有返回值(在C语言中也是一样,当存储是 cvMat
时没有返回)。
这意味着,唯一的输出就是存储的内容。你可以用numpy来解码这个结构:
np.asarray(storage)
这是我用来绘制圆圈的代码,圆心和半径是 HoughCircles
的结果。
for i in range(0,len(np.asarray(storage))):
cv.Circle(image, ( int(np.asarray(storage)[i][0][0]), int(np.asarray(storage)[i][0][1]) ), int(np.asarray(storage)[i][0][2]), cv.CV_RGB(255, 0, 0), 2, 8, 0 )
不过我还有一个问题没解决:圆心的X、Y坐标和半径完全不准确,我不知道哪里出了问题,也许你能找到答案。