Image correction to find circles
3 views (last 30 days)
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!
0 Comments
Accepted Answer
John BG
on 12 Jan 2017
Edited: John BG
on 12 Jan 2017
Adem
My solution works without any particular color.
I opted to work on blue because (wrongly) assumed the images you work on would be mostly blue.
But there is no need to use colors at all
look:
1.
Capture image
A=imread('im1.jpg');title('initial image');
figure(1);imshow(A);
2.
Ignore colors, just black and white
A2=A(:,:,1)+A(:,:,2)+A(:,:,3);
figure(2);h2=imshow(A2);
.
3.
get the extreme contrast image, experts also call this type of image binary image. I tried different thresholds between 10 and 250 and all seem to work ok
N=h2.CData
N(N>10)=255
N(N<10)=0
figure(3);imshow(N)
4.
Like before, my solution works with the right Sensitivity of 0.95 that I found for you
[centers, radii, m] = imfindcircles(N,[15 40],'Sensitivity',0.95);
viscircles(centers, radii,'EdgeColor','g');
.
5.
Applying found circle on initial figure, checking there is no offset
figure(1);viscircles(centers, radii,'EdgeColor','g');
.
no colors, yet we get the sought circle.
would you please be so kind to mark my answer as accepted answer
appreciating time and attention
awaiting answer
John BG
More Answers (3)
Image Analyst
on 12 Jan 2017
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
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);
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.
0 Comments
John BG
on 12 Jan 2017
Edited: John BG
on 12 Jan 2017
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
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.
See Also
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!