简体   繁体   中英

How to detect circle in a binary image

It is the original image: 在此处输入图片说明

And the after pre-processing the image

  • to gray
  • do canny edge
  • dilate
  • erode
  • bitwise_not

The result become as below:

在此处输入图片说明

Now I want to detect all the filled circle in the above image, the result which I want:

在此处输入图片说明

I have tried something like this:

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

And the result is like this: Which is not something I want

在此处输入图片说明

Update: (includes more sample image)

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

UPDATE: updating my solution using contours. you can find the solution using Hough circles below this.


Using Contours method.

I tried finding contours to mark pipes again today. Results I got with contour. I have filtered the results based on the contour length and area. But you can apply more constraints based on the images you have. It seems like I have overfitted the solution to this one image, but that is the only image I have access to. You can also play with laplacian/canny in place of adaptive threshold. Hope this helps :)

管道使用轮廓

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)

Hough Circles method

I tried taking your image and applied hough circles(opencv). I do not have Java setup, hence I used python. Here is the code and corresponding results I got.

Before that some tips to fine tune this.

  • Important is preprocessing, a simple Gaussianblur got me very good improvement, so play with gaussian filter size.
  • Since you already know the pipe radius/diameter, exploit that information. That is, play with minradius and maxradius param in Houghcircles.
  • You can also play with mindist param if you know the minimum distance between the pipes.
  • If you know the region where pipes could be present you can ignore false positive pipes detected in region other than that.

Hope this helps :)

Code I used

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)

And here is the result I got.

霍夫圈子的结果

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM