Code of function performing accumulation in [a, b] space
Gradient: Direction map. Calculated with 'atan(Ix./Iy)' where Ix is horizontal and Iy is vertical.
function [A] = accumulation(minr, maxr, magnitude, gradient)
[rows, cols, ~] = size(magnitude);
A = zeros(rows, cols, maxr);
for row = 1:rows
for col = 1:cols
for r = minr:maxr
a = row - r * cos(gradient(row, col));
b = col - r * sin(gradient(row, col));
a = round(a);
b = round(b);
if (a > 0 && a <= rows && b > 0 && b <= cols)
A(a, b, r) = A(a, b, r) + (magnitude(row, col)/r);
end
end
end
end
end
Output
Although, I am using 3 dimensional array, following image is in 2D just to show the issue.
Steps performed before accumulation in [a, b] space
Source I am using Circle Detection Using Hough Transforms Documentation by Jaroslav Borovicka for guidance.
One issue I see in you code is that you set only one point per r
. You need two. Note that the gradient gives you the orientation of the edge, but you don't know the direction towards the center -- unless you're computing the gradient of an image with solid disks, and you know the contrast with the background (i.e it's always black in white or white on black). Typically one sets a point at distance r
in direction theta
and another in direction theta + pi
.
Another problem you might be having is inaccuracy in the computation of the gradient. If you compute this on a binarized image, the direction of the gradient will be off by a lot. Smithing your grey-value image before computing the gradient might help (or better, use Gaussian gradients).
"Smoothing using 3x3 Gaussian filter" is wrong by definition. See the link above.
"Thresholding and thinning" -- try not thresholding. Your code is set up to accumulate using gradient magnitude as weights. Use those, they'll help.
Finally, don't use atan
, use atan2
instead.