Extract non-touching regions from image

2 views (last 30 days)
GIONA CANEVER
GIONA CANEVER on 6 Apr 2021
Edited: DGM on 6 Apr 2021
I've got the following BW image of a flower. I want to extract the non-touching area so for example the isolated region on the right of the image is a separate area from the others.
If I use bwconncomp or bwlabel I obtain 142 regions but there are some regions separated by some white pixels which are considered unite. I can see this by plotting the different area's centroid; as you can see in the second image, the separated area on the right does not have it's own centroid because this area is considered to belong to another.
How can I obtain the separated area and then eventually not consider the regions with dimensions under a certain value?
this is my code
flower = imread('flower.png');
figure
imshow(sestoBW);
flowerGR = im2gray(flower);
flowerBW = imbinarize(flowerGR);
CC = bwconncomp(flowerBW);
stats = regionprops(flowerBW,'Centroid');
centroids = cat(1,stats.Centroid);
hold on
plot(centroids(:,1),centroids(:,2),'b*')
thank you in advance for your help
  3 Comments
GIONA CANEVER
GIONA CANEVER on 6 Apr 2021
Edited: GIONA CANEVER on 6 Apr 2021
Yes, thank you very much, this is what I was looking for.
Now that I've found all the separated regions, how can I individually extract them? So for example, considering this region on the right, I obtain a new image of the same dimensions of the original one all white except in this area on the right?
something like this
DGM
DGM on 6 Apr 2021
Edited: DGM on 6 Apr 2021
something like this:
inpict=rgb2gray(imread('flower.png'))>0.5;
L=bwlabel(~inpict,8);
% that particular spot is label #90
thisobject=(L==90);
Once you have the label array from the image, you'll have to find the label associated with a particular object. I just did imshow(L) and used the datatip tool.
Once you know what the label is, you can just do a logical test on the label array.

Sign in to comment.

Answers (1)

LO
LO on 6 Apr 2021
Edited: LO on 6 Apr 2021
You can try using imerode on the blobs.
eroded_image = imerode(binary_image,[1 0 1; 1 0 1; 1 0 1]); % this will "shrink" the image on the vertical axis, you can reshape the matrix of ones to set a different rule for erosion: [1 1 1],[1 0 1],[1 1 1] this would be a circular erosion for example
Alternatively you can impose constraints on the distances that centroids should have (all center points having euclidean distance higher than a certain value, are excluded).
Alternatively you could "erode" the image (or threshold the binary image) before using regionprops (if it is not important you conserve the precise sizing of the blobs).
These are some snippets of some code I have been using, perhaps they can help you:
to remove blobs smaller than a certain threshold and if you know the N of blobs you want
CC = bwconncomp(binary_image); % connected shapes in your binary
objects = CC.NumObjects; % number of blobs
while objects > 2; % let's say you expect 2 blobs maximum
numPixels = cellfun(@numel,CC.PixelIdxList);
[smallest,idx] = min(numPixels);
binary_image(CC.PixelIdxList{idx}) = 0;
CC = bwconncomp(binary_image);
objects = CC.NumObjects;
end
to find the coordinates of the points of a given blob, you can use the following code
for i = 1:objects
cc = bwconncomp(binary_image); % find connected components in the image (it should find 2 blobs)
index = cc.PixelIdxList{i}; % indexes of pixels in blob1
[ovlogic,ovidx]=ismember(pixel_idx,index); % find ovarlapping indices in the matrix containing al pixels of all blobs
blob = pixels(ovlogic,:); % pixel coordinates of blob, save this somewhere if you need
end

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!