File: hough_circle.markdown

package info (click to toggle)
opencv 4.6.0%2Bdfsg-12
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 276,172 kB
  • sloc: cpp: 1,079,020; xml: 682,526; python: 43,885; lisp: 30,943; java: 25,642; ansic: 7,968; javascript: 5,956; objc: 2,039; sh: 1,017; cs: 601; perl: 494; makefile: 179
file content (182 lines) | stat: -rw-r--r-- 6,120 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
Hough Circle Transform {#tutorial_hough_circle}
======================

@tableofcontents

@prev_tutorial{tutorial_hough_lines}
@next_tutorial{tutorial_remap}

|    |    |
| -: | :- |
| Original author | Ana Huamán |
| Compatibility | OpenCV >= 3.0 |

Goal
----

In this tutorial you will learn how to:

-   Use the OpenCV function **HoughCircles()** to detect circles in an image.

Theory
------

### Hough Circle Transform

-   The Hough Circle Transform works in a *roughly* analogous way to the Hough Line Transform
    explained in the previous tutorial.
-   In the line detection case, a line was defined by two parameters \f$(r, \theta)\f$. In the circle
    case, we need three parameters to define a circle:

    \f[C : ( x_{center}, y_{center}, r )\f]

    where \f$(x_{center}, y_{center})\f$ define the center position (green point) and \f$r\f$ is the radius,
    which allows us to completely define a circle, as it can be seen below:

    ![](images/Hough_Circle_Tutorial_Theory_0.jpg)

-   For sake of efficiency, OpenCV implements a detection method slightly trickier than the standard
    Hough Transform: *The Hough gradient method*, which is made up of two main stages. The first
    stage involves edge detection and finding the possible circle centers and the second stage finds
    the best radius for each candidate center. For more details, please check the book *Learning
    OpenCV* or your favorite Computer Vision bibliography

####  What does this program do?
-   Loads an image and blur it to reduce the noise
-   Applies the *Hough Circle Transform* to the blurred image .
-   Display the detected circle in a window.

Code
----

@add_toggle_cpp
The sample code that we will explain can be downloaded from
[here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp).
A slightly fancier version (which shows trackbars for changing the threshold values) can be found
[here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/cpp/tutorial_code/ImgTrans/HoughCircle_Demo.cpp).
@include samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp
@end_toggle

@add_toggle_java
The sample code that we will explain can be downloaded from
[here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/java/tutorial_code/ImgTrans/HoughCircle/HoughCircles.java).
@include samples/java/tutorial_code/ImgTrans/HoughCircle/HoughCircles.java
@end_toggle

@add_toggle_python
The sample code that we will explain can be downloaded from
[here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py).
@include samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py
@end_toggle

Explanation
-----------

The image we used can be found [here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/data/smarties.png)

####  Load an image:

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp load
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/ImgTrans/HoughCircle/HoughCircles.java load
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py load
@end_toggle

####  Convert it to grayscale:

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp convert_to_gray
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/ImgTrans/HoughCircle/HoughCircles.java convert_to_gray
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py convert_to_gray
@end_toggle

#### Apply a Median blur to reduce noise and avoid false circle detection:

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp reduce_noise
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/ImgTrans/HoughCircle/HoughCircles.java reduce_noise
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py reduce_noise
@end_toggle

#### Proceed to apply Hough Circle Transform:

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp houghcircles
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/ImgTrans/HoughCircle/HoughCircles.java houghcircles
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py houghcircles
@end_toggle

-   with the arguments:

    -   *gray*: Input image (grayscale).
    -   *circles*: A vector that stores sets of 3 values: \f$x_{c}, y_{c}, r\f$ for each detected
        circle.
    -   *HOUGH_GRADIENT*: Define the detection method. Currently this is the only one available in
        OpenCV.
    -   *dp = 1*: The inverse ratio of resolution.
    -   *min_dist = gray.rows/16*: Minimum distance between detected centers.
    -   *param_1 = 200*: Upper threshold for the internal Canny edge detector.
    -   *param_2* = 100\*: Threshold for center detection.
    -   *min_radius = 0*: Minimum radius to be detected. If unknown, put zero as default.
    -   *max_radius = 0*: Maximum radius to be detected. If unknown, put zero as default.

####  Draw the detected circles:

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp draw
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/ImgTrans/HoughCircle/HoughCircles.java draw
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py draw
@end_toggle

You can see that we will draw the circle(s) on red and the center(s) with a small green dot

####  Display the detected circle(s) and wait for the user to exit the program:

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp display
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/ImgTrans/HoughCircle/HoughCircles.java display
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/ImgTrans/HoughCircle/hough_circle.py display
@end_toggle

Result
------

The result of running the code above with a test image is shown below:

![](images/Hough_Circle_Tutorial_Result.png)