Python 和 OpenCV。如何检测图像中的所有(实心)圆形/圆形物体?
我正在尝试编写一个程序来打开图像,扫描它的圆形/圆形形状并返回坐标,以便我可以使用 cv.Circle 函数在检测到的圆上绘制圆。
我的问题是:如何使用 cv.HoughCircles() 获取图像中检测到的圆的坐标/半径?
使用此页面,我找到了如何检测圆圈(这花了我很多时间因为我不理解阈值之类的术语,而且 Python 的 OpenCV 文档非常差,几乎没有)。不幸的是,该页面上没有显示如何提取从创建的 CvMat
中检测到的每个圆的信息。如何提取该信息/是否有其他方法(例如使用 MemoryStorage()
)?
这是我到目前为止的代码:
import cv, opencv
def main():
im = cv.LoadImageM("Proba.jpg")
gray = cv.CreateImage(cv.GetSize(im), 8, 1)
edges = cv.CreateImage(cv.GetSize(im), 8, 1)
cv.CvtColor(im, gray, cv.CV_BGR2GRAY)
cv.Canny(gray, edges, 50, 200, 3)
cv.Smooth(gray, gray, cv.CV_GAUSSIAN, 9, 9)
storage = cv.CreateMat(im.rows, 1, cv.CV_32FC3)
cv.HoughCircles(edges, storage, cv.CV_HOUGH_GRADIENT, 2, gray.height/4, 200, 100)
# Now, supposing it found circles, how do I extract the information?
print storage.r
if __name__ == '__main__':
main()
此外,HoughCircles
的最后两个参数需要具有什么值才能让我检测到非常小的圆圈(例如屏幕上的 3mm)?
感谢大家花时间和精力来帮助我!
我正在使用的图像是这样的:
I am trying to make a program which opens an image, scans it for circles/round shapes and returns the coordinates so that I can use the cv.Circle
function to draw circles over the circle detected.
My question is: How do I get the coordinates/radii of the circles detected in an image using cv.HoughCircles()
?
Using this page, I found out how to detect the circles (which took me a lot of time to find out since I don't understand terms like threshold and the OpenCV documentation for Python is really poor, almost none). Unfortunately, on that page it didn't show how to extract the information of each circle detected from the CvMat
created. How do I extract that information/is there some other way(eg. with MemoryStorage()
) ?
This is my code so far:
import cv, opencv
def main():
im = cv.LoadImageM("Proba.jpg")
gray = cv.CreateImage(cv.GetSize(im), 8, 1)
edges = cv.CreateImage(cv.GetSize(im), 8, 1)
cv.CvtColor(im, gray, cv.CV_BGR2GRAY)
cv.Canny(gray, edges, 50, 200, 3)
cv.Smooth(gray, gray, cv.CV_GAUSSIAN, 9, 9)
storage = cv.CreateMat(im.rows, 1, cv.CV_32FC3)
cv.HoughCircles(edges, storage, cv.CV_HOUGH_GRADIENT, 2, gray.height/4, 200, 100)
# Now, supposing it found circles, how do I extract the information?
print storage.r
if __name__ == '__main__':
main()
Also, what value do the last two parameters of HoughCircles
need to have in order for me to detect really small circles (like 3mm on the screen) ?
Thank you all for your time and effort trying to help me!
The image I'm working with is this:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
最后两个参数似乎是传递给
cv.Canny()
的,这意味着cv.Canny()
是从内部调用的cv.HoughCircles()
。我对此不太确定。至于尺寸,似乎接下来的两个参数(
200, 100 之后)
默认为0
,这可能意味着所有尺寸都是检测到。从 C++ 示例的源代码中,我还可以猜测您不需要进行 Canny 边缘检测:
我认为您正在尝试将此 C++ 代码转换为 Python?
据我所知,
CvMat
对象是可迭代的,就像列表一样:我没有任何测试图像,所以不要相信我说这有效。您的完整代码可能是:
The last two parameters are what seem to be passed to
cv.Canny()
, which implies thatcv.Canny()
is called from withincv.HoughCircles()
. I'm not too sure about that.As for the sizes, it seems like the next two parameters (after
200, 100)
default to0
, which might mean that all sizes are detected.From the C++ example's source, I can also guess that you don't need to do a Canny edge detection:
You're trying to convert this C++ code into Python, I assume?
As far as I can tell,
CvMat
objects are iterable, just like a list:I don't have any test images, so don't take my word that this works. Your complete code would might be:
看看我的回答对这个问题的一些工作源代码(它是C,但我使用了C++编译器,因为它更宽松)。
首先,我裁剪了您的图像(以方便使用)并对图像应用阈值以将前景与背景分开:
然后我直接将源代码应用于阈值图像。这是文本输出:
这是输出图像:
主要问题是已合并的圆圈在一起根本没有被发现。该代码最初是为了检测填充的省略号而编写的,因此您可以通过调整代码来解决此问题。
Have a look at my answer to this question for some working source code (it's C but I used a C++ compiler cause it's more lenient).
First, I cropped your image (to get something convenient to work with) and applied a threshold to your image to separate the foreground from the background:
Then I directly applied the source code to the thresholded image. Here is the text output:
And here is the output image:
The main problem is that circles that have merged together have not been detected at all. The code was originally written for detecting filled ellipses only, so you can probably deal with this issue by tweaking the code.
python 中的类似解决方案。最初,我尝试运行 此处 描述的轮廓检测,但效果不佳。所以首先需要一些阈值。阈值的代码在这里:
这样我得到一个像这样的图像:
在链接中描述的边缘检测之后上面我得到了这个:
如果你检查代码,你会发现计算对象非常容易。唯一的问题是,有些气泡被计数了两次。我想阈值功能也可以改进。但我建议使用 skimage,它很容易使用,并且在其网页上有很好的示例。
A similar solution in python. Originally I tried to run a contour detection described here, but it doesn't worked well. So first some thresholding was necessary. The code for threshold is here:
With this I get an image like this:
And after edge detection described in the link above I got this:
If you check the code, you will find that's really easy to count the objects. The only problem is, that some of the bubbles are counted twice. And I guess the thresholding function can be improved as well. But I suggest to use skimage it's easy to use and has good samples on their web page.