在Python中使用CV2的填充圆检测? [英] Filled circle detection using CV2 in Python?

查看:2972
本文介绍了在Python中使用CV2的填充圆检测?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要检测这样的图片中的所有圈子。

我有许多不同的图像,但在所有的圆圈将是黑色(或几乎黑色)和相同的大小(+/-几个像素) 。我相信每个图像中都有2943个圆圈。这些条件从不改变。我可能无法控制图片中的圆圈尺寸(通常为半径在15-45像素之间 - 上面提供的示例图片的半径为20-21像素)。

I have many different images like this but in all the circles will be black (or almost black) and of the same size (+/- a couple of pixels). I believe there are exactly 2943 circles in each image. These conditions never change. I may not be able to control the sizes of the circles across images (usually ranges between 15-45 pixels in radii - the example image provided above has radii of 20-21 pixels).

我需要能够尽可能准确,精确地检测这些圆的中心的确切位置(如果可能,也可以检测半径)。

I need to be able to detect the exact locations of the centers of these circles as accurately and precisely as possible (if possible, the radii too).

我尝试使用 cv2.HoughCircles 函数这样做,但得到非常不一致和不可靠的结果。这里是我使用的代码:

I tried using the cv2.HoughCircles function to do so, but got very inconsistent and unreliable results. Here is the code that I used:

from pylab import *
import sys, cv2

filename = sys.argv[1];
img = cv2.imread(filename,0);
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR);
circles = cv2.HoughCircles(img,cv2.cv.CV_HOUGH_GRADIENT,2,15,param1=100,param2=30,minRadius=15,maxRadius=25);
circles = np.uint16(np.around(circles));
for i in circles[0,:]:
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),1);
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3);
cv2.imwrite('1-%s'%(filename),cimg)
print "%d circles found."%(len(circles[0]));

结果是此图片和此输出:找到2806个圈子。

有许多假的圈子,许多真正的圈子被错过/忽略。

There are many false circles and many of the true circles have been missed/ignored.

我开始相信 HoughCircle 方法不是最好的方法,如果我的所有圈子在一个单一的图像是相同的,并且可能有一些更好的对象检测方法可用。

I am starting to believe that the HoughCircle method is not the most optimal way to go if all my circles are identical in a single image, and there might be some better object detection method available.

如果我能够足够精确地控制圈子的属性,你建议我使用什么来准确,精确地检测每个圈子?

What do you suggest I use to detect every circle precisely and accurately across thousands of images if I can control the properties of the circles tightly enough?

推荐答案

我想出了这个代码,它调整到您提供的确切的图像,发现2943个圆与半径估计,假设所有的圆有相同的半径。这是它生成的(裁剪,原来太大):

I came up with this code, it is tuned to the exact image you have supplied, finds 2943 circles with the radius estimate as well, assuming all circles have the same radius. This is what it produces (cropped, original was too big):

您可以看到它不完全理想(角圈是有点偏离)。

You can see that its not completely ideal (the corner circle is a bit off).

它是基于阈值处理,然后轮廓操作而不是hough圈。

It is based around thresholding and then contour operations rather than hough circles.

import cv2
import numpy as np

original = cv2.imread("test.jpg", cv2.CV_LOAD_IMAGE_GRAYSCALE)
retval, image = cv2.threshold(original, 50, 255, cv2.cv.CV_THRESH_BINARY)

el = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
image = cv2.dilate(image, el, iterations=6)

cv2.imwrite("dilated.png", image)

contours, hierarchy = cv2.findContours(
    image,
    cv2.cv.CV_RETR_LIST,
    cv2.cv.CV_CHAIN_APPROX_SIMPLE
)

drawing = cv2.imread("test.jpg")

centers = []
radii = []
for contour in contours:
    area = cv2.contourArea(contour)

    # there is one contour that contains all others, filter it out
    if area > 500:
        continue

    br = cv2.boundingRect(contour)
    radii.append(br[2])

    m = cv2.moments(contour)
    center = (int(m['m10'] / m['m00']), int(m['m01'] / m['m00']))
    centers.append(center)

print("There are {} circles".format(len(centers)))

radius = int(np.average(radii)) + 5

for center in centers:
    cv2.circle(drawing, center, 3, (255, 0, 0), -1)
    cv2.circle(drawing, center, radius, (0, 255, 0), 1)

cv2.imwrite("drawing.png", drawing)

希望它有助于

这篇关于在Python中使用CV2的填充圆检测?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆