Hough Circle Transform

An example using the Hough circle detector.

This program demonstrates circle finding with the Hough transform. We show how to use the OpenCV function cv.HoughCircles to detect circles in an image.

Sources:

Contents

Theory

The Hough Circle Transform works in a roughly analogous way to the Hough Line Transform.

In the line detection case, a line was defined by two parameters $(r, \theta)$. In the circle case, we need three parameters to define a circle:

$$C : ( x_{center}, y_{center}, r )$$

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

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:

For more details, please check the book Learning OpenCV or your favorite Computer Vision bibliography.

Code

This program:

Input image

if ~mexopencv.isOctave() && mexopencv.require('images')
    fname = which('coins.png');
else
    fname = fullfile(mexopencv.root(), 'test', 'detect_blob.png');
end
assert(~isempty(fname) && exist(fname,'file')==2, 'Image not found');
img = cv.imread(fname, 'Color',true);
figure, imshow(img), title('source')

convert it to grayscale, and reduce noise to avoid false circles detection

gray = cv.cvtColor(img, 'RGB2GRAY');
if true
    gray = cv.medianBlur(gray, 'KSize',5);
else
    gray = cv.GaussianBlur(gray, 'KSize',[7,7], 'SigmaX',0.9, 'SigmaY',0.9);
end

Hough Circle Transform

tic
circles = cv.HoughCircles(gray, 'Method','Gradient', 'DP',2, ...
    'MinDist',size(gray,1)/8, 'Param1',200, 'Param2',100, ...
    'MinRadius',20, 'MaxRadius',80);
toc
Elapsed time is 0.023248 seconds.

draw detected circles (outlines and centers), and display the result

circles = cat(1, circles{:});
center = round(circles(:,1:2));
radius = round(circles(:,3));
out = cv.circle(img, center, radius, 'Color',[0 0 255], ...
    'Thickness',2, 'LineType','AA');
out = cv.circle(out, center, 3, 'Color',[0 255 0], ...
    'Thickness','Filled', 'LineType','AA');
figure, imshow(out), title('detected circles')