1 ## Copyright (C) 2008 Soren Hauberg
3 ## This program is free software; you can redistribute it and/or modify
4 ## it under the terms of the GNU General Public License as published by
5 ## the Free Software Foundation; either version 3 of the License, or
6 ## (at your option) any later version.
8 ## This program is distributed in the hope that it will be useful,
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 ## GNU General Public License for more details.
13 ## You should have received a copy of the GNU General Public License
14 ## along with this program; if not, write to the Free Software
15 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 ## @deftypefn {Function File} @var{accum}= hough_circle (@var{bw}, @var{r})
19 ## Perform the Hough transform for circles with radius @var{r} on the
20 ## black-and-white image @var{bw}.
22 ## As an example, the following shows how to compute the Hough transform for circles
23 ## with radius 3 or 7 in the image @var{im}
26 ## accum = hough_circle(bw, [3, 7]);
28 ## If @var{im} is an NxM image @var{accum} will be an NxMx2 array, where
29 ## @var{accum}(:,:,1) will contain the Hough transform for circles with
30 ## radius 3, and @var{accum}(:,:,2) for radius 7. To find good circles you
31 ## now need to find local maximas in @var{accum}, which can be a hard problem.
32 ## If you find a local maxima in @var{accum}(row, col, 1) it means that a
33 ## good circle exists with center (row,col) and radius 3.
38 function accum = hough_circle(bw, r)
39 ## Check input arguments
41 error("hough_circle: wrong number of input arguments");
44 if (!ismatrix(bw) || ndims(bw) != 2)
45 error("hough_circle: first arguments must be a 2-dimensional matrix");
48 if (!isvector(r) || !isreal(r) || any(r<0))
49 error("hough_circle: radius arguments must be a positive vector or scalar");
52 ## Create the accumulator array.
53 accum = zeros(size(bw,1), size(bw,2), length(r));
55 ## Find the pixels we need to look at
58 ## Iterate over different radius
62 ## Compute a filter containing the circle we're looking for.
65 ## Iterate over all interesting image points
70 ## Compute indices for the accumulator array
71 a_rows = max(row-rad,1) : min(row+rad, size(accum,1));
72 a_cols = max(col-rad,1) : min(col+rad, size(accum,2));
74 ## Compute indices for the circle array (the filter)
75 c_rows = max(rad-row+2,1) : min(rad-row+1+size(accum,1), size(circ,1));
76 c_cols = max(rad-col+2,1) : min(rad-col+1+size(accum,2), size(circ,2));
78 ## Update the accumulator array
79 accum( a_rows, a_cols, j ) += circ ( c_rows, c_cols );
84 ## Small auxilary function that creates an (2r+1)x(2r+1) image containing
85 ## a circle with radius r and center (r+1, r+1).
86 function circ = circle(r)
87 circ = zeros(round(2*r+1));
89 for row=1:size(circ,1)
90 tmp = (row-(r+1)).^2 + (col-(r+1)).^2;
91 circ(row,col) = (tmp <= r^2);
93 circ = bwmorph(circ, 'remove');