Hough transform of opencv: circle

1. Introduction to Hough Transform

The classic Hough transform is used to recognize lines in images, but later the Hough transform was extended to recognize locations of arbitrary shapes, most commonly circles or ellipses.
"In many cases, an edge detector can be used as a preprocessing stage to obtain image points or image pixels on a desired curve in image space. However, due to imperfections in the image data or in the edge detector, the desired curve may exist Missing points or pixels, and spatial deviations between ideal lines/circles/ellipses and noisy edge points are obtained from edge detectors. For these reasons, grouping the extracted edge features into an appropriate set of lines, circles or ellipses is usually Very important. The purpose of the Hough Transform is to solve this problem by performing an explicit voting process on a parameterized set of image objects, so that edge points can be grouped as object candidates." - Wiki-Hough Transform .

2. Hough transform parameterization

A circle can be fully defined with three parameters: center coordinates (A, b) and radius (R):

x = a + Rcosθ
y = b + Rsinθ

As theta varies from 0 to 360, a full circle of radius R is created.
So, using the Circle Hough transform, we want to find triplets of (x, y, R) from the image. In other words, our purpose is to find these three parameters.
Therefore, we need to construct a 3D accumulator for the Hough transform, which will be very inefficient. Therefore, OpenCV uses a more sophisticated method, the Hough Gradient method using edge gradient information.

3. Hough transform source code

The function we are using here is cv2.HoughCircles(). It has a lot of arguments, which are well explained in the docs. So we go straight to the code:

import cv2
import numpy as np
from matplotlib import pyplot as plt

bgr_img = cv2.imread('hg.jpg') # read as it is

if bgr_img.shape[-1] == 3:           # color image
    b,g,r = cv2.split(bgr_img)       # get b,g,r
    rgb_img = cv2.merge([r,g,b])     # switch it to rgb
    gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)
else:
    gray_img = bgr_img

img = cv2.medianBlur(gray_img, 5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,20,
                            param1=50,param2=30,minRadius=0,maxRadius=0)

circles = np.uint16(np.around(circles))

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

plt.subplot(121),plt.imshow(rgb_img)
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(cimg)
plt.title('Hough Transform'), plt.xticks([]), plt.yticks([])
plt.show()

4. Case analysis:

4.1 False circles

So far, it's been working fine:

1
2
3

4.2 A circle should not be considered as a hidden circle in the following cases

insert image description here
5

4.3 Make the effect better by blurring more content

img = cv2.medianBlur(gray_img, 25);

6

4.4 Preprocessing is crucial

In general, algorithms tend to extract too many circular features without blurring. So, to be more successful, preprocessing seems to be crucial:
7

4.5 Set a more appropriate fuzzy value

Use fuzzy value 51:

img = cv2.medianBlur(gray_img, 51);

8

Guess you like

Origin blog.csdn.net/m0_37383484/article/details/127462396