Reputation: 1092
Whats the fastest way to detect these circular shapes in a image?
The radius is always between(80-100mm). Background is always white. And the circle will always be in center.
I have tried Hough Transform but I couldn't really get it to work. I am new to this, and I get a feeling like Hough Transform is a overkill for this. Kindly suggest me the right approach to do this.
UPDATE
Here is what I got after applying hough transform.
I have used the algorithm mentioned here.
Following is the relevant code from the bigger algorithm
% applying Hough Below
[accum, circen, cirrad] = ...
CircularHough_Grd(gR, [89 93],...
17.4, 13, 1); % this executes in 0.72 sec
% Lets see what we got
imshow(gR);
hold on;
plot(circen(:,1), circen(:,2), 'r+');
for ii = 1 : size(circen, 1)
rectangle('Position',[circen(ii,1) - cirrad(ii), circen(ii,2) - cirrad(ii), 2*cirrad(ii), 2*cirrad(ii)],...
'Curvature', [1,1], 'edgecolor', 'b', 'linewidth', 1.5);
end
hold off;
The meaningful circle is the one in the middle.
Upvotes: 3
Views: 14093
Reputation: 12689
If your matlab version is R2012a or later, the image processing tool box includes the function imfindcircles
that is used to detect circles in the image.
filen='https://i.sstatic.net/pmBp1.jpg'; % your original image
I=imread(filen);
I=im2bw(I(:,:,3)); % convert to gray scale
Rmin=50;Rmax=100; % circle radius range
[centersDark, radiiDark] = imfindcircles(I, [Rmin Rmax], ...
'ObjectPolarity','dark','sensitivity',0.93)
imagesc(I),hold on
viscircles(centersDark, radiiDark,'LineStyle','--');hold off
The result:
Actually this function also applies Hough transform, I think it's similar with yours. One thing you may need to note is, the threshold corresponding to the sensitivity in Hough has great impact on the detecting result. Too high sensitivity leads to detecting more circles, including weak or partially obscured ones, at the risk of a higher false detection rate, which was exactly what you obtained.
Upvotes: 4
Reputation: 114786
Here's what I propose:
1. convert to gray image, enhancing the "difference from white"
gimg = min( img, [], 3 );
2. Threshold to remove white area
BW = im2bw( gimg, .4 );
3. Get area and centroid porperties of image regions
st = regionprops( ~BW, 'Area', 'Centroid', 'PixelIdxList' );
4. select only large enough regions
sel = [st.Area] > numel(BW)*0.025; % at least 2.5% of image size
st = st(sel);
5. compute region distance to center of image
cntr = .5 * [size(BW,2) size(BW,1)]; % X-Y coordinates and NOT Row/Col
d = sqrt( sum( bsxfun(@minus,vertcat( st.Centroid ), cntr ).^2, 2 ) );
6. pick the region closest to center
[mn idx] = min(d);
7. Create a mask
res = false(size(BW));
res( st(idx).PixelIdxList ) = true;
You might also consider using other region properties (e.g., 'Eccentricity'
) to better reject regions that are not circular.
Upvotes: 6