Image correction to find circles
Show older comments

I have this image and I want to find circle using imfindcircle, this image is from my camera, sometimes because of ambient light the blue circle gets a bit darker and imfindcircle don't work, is there anyway that i could correct this image to get a brighter circle so imfindcircle won't fail!
Accepted Answer
More Answers (3)
Image Analyst
on 12 Jan 2017
5 votes
Why not use the color? If the thing is always blue, simply use color segmentation like I show you in my demos: http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862
3 Comments
Adem Kikaj
on 12 Jan 2017
Image Analyst
on 12 Jan 2017
OK, you didn't say that before but it's not a problem. Do we at least know it's not black? If so, just get the max of all channels and threshold. Then depending on if this is your entire image or if you just snipped out a small part to show us, you can threshold and call either bwareafilt() to extract the largest blob, or call regionprops asking for areas and perimeters and comuting circularities and taking only round regions.
grayImage = max(rgbImage, [], 3);
binaryImage = grayImage > someThreshold; % like 20 or whatever.
binaryImage = bwareafilt(binaryImage, 1); % Extract largest blob.
or
labeledImage = bwlabel(binaryImage);
props = regionprops(labeledImage, 'Area', 'Perimeter');
allAreas = [props.Area]
allPerimeters = [props.Perimeter]
circularities = allPerimeters .^2 ./ (4*pi*allAreas)
roundObjectIndexes = find(circularities < 4); % Adjust 4 if necessary.
boundBlobsImage = ismember(labeledImage, roundObjectIndexes);
Adem Kikaj
on 15 Jan 2017
John Chilleri
on 12 Jan 2017
Hello,
I would suggest trying to use some of the name-value pair arguments, the ones that seemed potentially useful for your problem are:
- 'ObjectPolarity' - specify if circle is darker or lighter than background
- 'Sensitivity' - increasing sensitivity increases circle detection (risk of false detection)
- 'EdgeThreshold' - for weaker or stronger edges, detects more circles with low threshold value
I would suggest starting with:
imfindcircles(A, radius, 'ObjectPolarity', 'bright', 'Sensitivity', 1, 'EdgeThreshold', 0)
It wouldn't be surprising if this detects additional circles - if that is the case, then play with the Sensitivity and EdgeThreshold values until it works. Also, I haven't looked deeply into ObjectPolarity, so I'm not sure how those four bright lines will interact with the search - you might consider leaving out that option if it won't work for any Sensitivity and EdgeThreshold values.
Adem
imfindcircles works fine if you change the parameter Sensitivity from the default 0.85 to 0.95
Follow these steps:
1.
Capture
A=imread('im1.jpg');title('initial image');
ColorList={'Red' 'Green' 'Blue'};
N=256;
gr=0:1/(N-1):1;
figure(1);imshow(A);
2.
split RGB
N=255;
cMap=zeros(N,3);cMap(:,1)=gr;
figure(2);hr=imshow(ind2rgb(A(:,:,1),cMap));title(ColorList{1});
% filtering greens
cMap=zeros(N,3);cMap(:,2)=gr;
figure(3);hg=imshow(ind2rgb(A(:,:,2),cMap));title(ColorList{2});
% filtering blues
cMap=zeros(N,3);cMap(:,3)=gr;
figure(4);hb=imshow(ind2rgb(A(:,:,3),cMap));title(ColorList{3});

.
3.
Keep the Blues
B=hb.CData;
B1=B(:,:,1);B2=B(:,:,2);B3=B(:,:,3);
nonzeros(B1) % check it's null
nonzeros(B2) % check it's null
4.
Extreme contrast with the right threshold of 0.2
If you try theshold 0.1 the area of interest is too large. With threshold above 0.3 N would turn pitch black.
N=B3
N(N>0.2)=255
N(N<0.2)=0
figure(5);imshow(N)

.
5.
Apply imfindcircles to the extreme contrast image N, not the initial image.
A bit of manual trimming is needed:
With too wide range of radii [1 40] only small circles are caught, not the big one you want:
[centers, radii, m] = imfindcircles(N,[1 40],'Sensitivity',0.95);
viscircles(centers, radii,'EdgeColor','b');
with radii range [10 40] the camera circle is successfully caught, but there are 2 additional undesired circles.
[centers, radii, m] = imfindcircles(N,[10 40],'Sensitivity',0.95);
viscircles(centers, radii,'EdgeColor','r');
the best set of parameters is:
[centers, radii, m] = imfindcircles(N,[15 40],'Sensitivity',0.95);
viscircles(centers, radii,'EdgeColor','g');

.
if you find these lines useful would you please mark my answer as Accepted Answer?
To any other reader, if you find this answer of any help please click on the thumbs-up vote link,
thanks in advance for time and attention
John BG
2 Comments
Adem Kikaj
on 12 Jan 2017
Image Analyst
on 12 Jan 2017
Attach some problematic images of low brightnesses and different colors if you need help with them. Also attach the full image, unless you know you will always be starting with this low res field of view.
Categories
Find more on Image Processing Toolbox in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

