how can i detect round objects and remove other objects in an image using matlab?
9 views (last 30 days)
Show older comments
noha maabreh
on 30 Mar 2015
Commented: Image Analyst
on 12 Feb 2022
IMAGES{i} = imread(sprintf(Fimage,i));
result = cell(1,N);
result{i} = rgb2gray(IMAGES{i});
BW = im2bw(result{i}, .4);
se = strel('disk',11);
erodedBW = imdilate(BW,se);
imagesc(erodedBW)
bw=bwareaopen(erodedBW,50000);
%imshow(bw)
%hold
[B,L] = bwboundaries(bw,'noholes');
for k = 1:length(B)
boundary = B{k};
xr(i,k)=round(mean((boundary(:,2))));
yr(i,k)=round(mean((boundary(:,1))));
imgindex(i)=i;
end
st=regionprops( ~bw,'area','centroid','PixelIdxList');
0 Comments
Accepted Answer
Image Analyst
on 30 Mar 2015
It seemed to work for me:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
rgbImage = imread('005.png');
grayImage = rgb2gray(rgbImage);
subplot(2,2,1);
imshow(grayImage);
title('Original Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Threshold the image.
binaryImage = im2bw(grayImage, .4);
% Display the image.
subplot(2,2,2);
imshow(binaryImage)
title('Initial Binary Image', 'FontSize', fontSize);
% Dilate the image to enlarge the small blobs.
se = strel('disk',11);
binaryImage = imdilate(binaryImage,se);
subplot(2,2,3);
imshow(binaryImage)
title('Dilated Image', 'FontSize', fontSize);
% Label the blobs.
labeledImage = bwlabel(binaryImage);
measurements = regionprops(labeledImage,'Area','Perimeter');
% Do size filtering and roundness filtering.
% Get areas and perimeters of all the regions into single arrays.
allAreas = [measurements.Area]
allPerimeters = [measurements.Perimeter]
% Compute circularities.
circularities = allPerimeters.^2 ./ (4*pi*allAreas)
% Find objects that have "round" values of circularities.
maxAllowableArea = 50000;
keeperBlobs = circularities < 3 & allAreas < maxAllowableArea; % Whatever values you want.
% Get actual index numbers instead of a logical vector
% so we can use ismember to extract those blob numbers.
roundObjects = find(keeperBlobs);
% Compute new binary image with only the small, round objects in it.
binaryImage = ismember(labeledImage, roundObjects) > 0;
subplot(2,2,4);
imshow(binaryImage);
title('Final Image', 'FontSize', fontSize);
% Remeasure with this new segmentation.
% Label the blobs.
labeledImage = bwlabel(binaryImage);
measurements = regionprops(labeledImage,'Area','Perimeter', 'Centroid');
% Get areas and perimeters of all the regions into single arrays.
allAreas = [measurements.Area]
allPerimeters = [measurements.Perimeter]
allCentroids = [measurements.Centroid]
centroidX = allCentroids(1:2:end);
centroidY = allCentroids(2:2:end);
% Plot circles around them
hold on;
for k = 1 : length(centroidX);
plot(centroidX(k), centroidY(k), ...
'ro', 'MarkerSize', 20, 'LineWidth', 2);
end
What does "not working well" mean to you? What exactly do you want as an output of this routine? The size, location, what?????
14 Comments
Image Analyst
on 30 Mar 2015
Why not check if the light is on by attaching an Arduino to the LED leads rather than by using image analysis?
More Answers (2)
Image Analyst
on 30 Mar 2015
Calculate the circularities and filter based on that.
labeledImage = bwlabel(~bw);
st=regionprops(labeledImage,'area','Perimeter');
% Get areas and perimeters of all the regions into single arrays.
allAreas = [st.Area];
allPerimeters = [st.Perimeter];
% Compute circularities.
circularities = allPerimeters.^2 ./ (4*pi*allAreas);
% Find objects that have "round" values of circularities.
roundObjects = find(circularities < 4); % Whatever value you want.
% Compute new binary image with only the round objects in it.
binaryImage = ismember(labeledImage, roundObjects) > 0;
imshow(binaryImage);
Alexandra Holland
on 11 Feb 2022
I adapted the code above. May not be too elegant but it worked for me (I am looking at mouse cells).
circ_thresh = 1.15; %default circularity of 1.2 is OK, 1.05 is very stringent
%try to exclude weird shapes based on circularity
mask_conn= bwconncomp(mask_bs,8); % you need this as input for function 'regionprops'
mask_RP=regionprops(mask_conn,'area','Perimeter','PixelIdxList');
allAreas = [mask_RP.Area];
allPerimeters = [mask_RP.Perimeter];
circularities = allPerimeters.^2 ./ (4*pi*allAreas);
roundObjectsIndex = find(circularities < circ_thresh); % Whatever value you want.
mask_bsTEMP = false(size(DAPI_flat, 1), size(DAPI_flat, 2)); % initialize the mask as black
mask_RP_sort = mask_RP(roundObjectsIndex,:);
for k = 1:numel(mask_RP_sort)
idx = mask_RP_sort(k).PixelIdxList;
mask_bsTEMP(idx) = true;
end
mask_bs5=mask_bsTEMP; %test circularity threshold circ_thresh
imshow(mask_bs5);
1 Comment
Image Analyst
on 12 Feb 2022
There is now a 'Circularity' option to ask regionprops() for so you don't have to compute it yourself, though it's the inverse of what we computed. It's
(4*Area*pi)./(Perimeter^2)
See Also
Categories
Find more on Image Processing and Computer Vision 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!