如何检测二进制图像中的圆圈

Bah*_*dil 1 c++ java opencv image-processing

这是原始图像: 在此输入图像描述

并且经过预处理后的图像

  • 灰色
  • 干得好
  • 膨胀
  • 侵蚀
  • bitwise_not

结果如下:

在此输入图像描述

现在我想检测上图中所有填充的圆圈,我想要的结果:

在此输入图像描述

我尝试过这样的事情:

MatOfPoint2f approxCurve = new MatOfPoint2f();
matOfPoint2f.fromList(contour.toList());
Imgproc.approxPolyDP(matOfPoint2f, approxCurve, Imgproc.arcLength(matOfPoint2f, true) * 0.02, true);
long total = approxCurve.total();
// now check the total if it was greater than 6, then it can be a circle
Run Code Online (Sandbox Code Playgroud)

结果是这样的:哪个不是我想要的东西

在此输入图像描述

更新:( 包括更多样本图片)

在此输入图像描述 在此输入图像描述在此输入图像描述

har*_*hkn 5

更新:使用轮廓更新我的解决方案.您可以在此下方使用Hough圆圈找到解决方案.


使用轮廓方法.

我今天尝试再次找到轮廓来标记管道.结果我得到了轮廓.我根据轮廓长度和面积过滤了结果.但您可以根据您拥有的图像应用更多约束.似乎我已经为这一个图像配备了解决方案,但这是我可以访问的唯一图像.您也可以使用laplacian/canny代替自适应阈值.希望这可以帮助 :)

使用轮廓的管道

import cv2 as cv2

img_color = cv2.imread('yNxlz.jpg')
img_gray = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)

image = cv2.GaussianBlur(img_gray, (5, 5), 0)

thresh = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY_INV,11,2)

contours,hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours

contour_list = []
for contour in contours:
    approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
    area = cv2.contourArea(contour)
    # Filter based on length and area
    if (7 < len(approx) < 18) & (900 >area > 200):
        # print area
        contour_list.append(contour)

cv2.drawContours(img_color, contour_list,  -1, (255,0,0), 2)
cv2.imshow('Objects Detected',img_color)
cv2.waitKey(5000)
Run Code Online (Sandbox Code Playgroud)

Hough Circles方法

我尝试拍摄你的图像并应用hough圈(opencv).我没有Java设置,因此我使用了python.这是我得到的代码和相应的结果.

在此之前,一些提示可以对此进行微调.

  • 重要的是预处理,一个简单的Gaussianblur给我带来了很好的改进,所以玩高斯滤波器的大小.
  • 由于您已经知道管道半径/直径,因此利用该信息.也就是说,在Houghcircles中玩minradius和maxradius param.
  • 如果你知道管道之间的最小距离,你也可以玩mindist param.
  • 如果您知道可能存在管道的区域,则可以忽略在除此之外的区域中检测到的误报管道.

希望这可以帮助 :)

我用的代码

import cv2 as cv2

img_color = cv2.imread('yNxlz.jpg')
img_gray = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)

img_gray = cv2.GaussianBlur(img_gray, (7, 7), 0)

#Hough circle
circles = cv2.HoughCircles(img_gray, cv2.cv.CV_HOUGH_GRADIENT, 1, minDist=15,
                     param1=50, param2=18, minRadius=12, maxRadius=22)

if circles is not None:
    for i in circles[0, :]:
        # draw the outer circle
        cv2.circle(img_color, (i[0], i[1]), i[2], (0, 255, 0), 2)
        # draw the center of the circle
        cv2.circle(img_color, (i[0], i[1]), 2, (0, 0, 255), 3)

cv2.imwrite('with_circles.png', img_color)

cv2.imshow('circles', img_color)
cv2.waitKey(5000)
Run Code Online (Sandbox Code Playgroud)

这是我得到的结果.

霍夫圈的结果