How to extract randomly shaped foreground objects from a non-uniformt background image?

10 vues (au cours des 30 derniers jours)
I want to extract the brighter foreground objects (mostly small and circular, although some are larger and triangular) from the background, and I am using the following code:
clc
clear all
close all
npixels=1000;
l=50;
% import image
I=imread("testA.png");
size(I)
figure
imshow(I);
% approximate background using morphological opening
se = strel('disk',35);
background=imopen(I,se);
figure
imshow(background);
% subtract background
I2=I-background;
% figure
% imshow(I2);
% increase contrast
I3 = imadjust(I2);
figure
imshow(I3);
% binarize image and remove background noise
bw = imbinarize(I3,0.30);
bw = bwareaopen(bw,10);
figure
imshow(bw);
% count number of objects
cc = bwconncomp(bw,8)
cc.NumObjects
%view extracted objects
figure
final_im=imoverlay(I, bw, 'r');
imshow(final_im);
hold on
c = regionprops(cc,'centroid');
centroids = cat(1,c.Centroid);
plot(centroids(:,1),centroids(:,2),'b.')
hold off
I have followed the example here
The problem I am facing is that background regions have the same grayscale value as some foreground objects, hence, if I set a low threshold for binarizing, it is taking in the unwanted background regions, and if I set a high threshold, it is missing some wanted foreground objects. (images showcasing the issue attached)
Visibily, the foreground objects are pretty clear (I don't know what is the property that will help the code to detect that). Could anyone help modify my code / suggest an alternative way to extract all the foreground objects?
  4 commentaires
SNIreaPER
SNIreaPER le 26 Jan 2022
I can use different parameters to get smaller droplets, but that is also including the background regions having the same intensity. I need a way to include only the ones that locally have a different intensity from its surrounding. Is there a way I can do that?
I can also possibly use different threshold values (one for small spots and one for large spots; is there a way to combine them?
Also, could detecting the edges and taking regions within that enclose a closed polygon be an alternative approach?
Image Analyst
Image Analyst le 26 Jan 2022
Possible - try it. But I would not be surprised if some of the smaller, fainter droplets don't have edges strong enough to be detected.
You do not need to have two separate thresholds. A single threshold that is low enough to pick up the faint droplets will also get the brighter ones.
You can try imtophat() or imbothat(), but like imopen() these filters all depend on the filter window size. One size might pick up small droplets while a bigger window size might pick up the larger droplets. Perhaps you can then combine them.

Connectez-vous pour commenter.

Réponses (1)

yanqi liu
yanqi liu le 10 Jan 2022
clc
clear all
close all
npixels=1000;
l=50;
% import image
I=imread("https://ww2.mathworks.cn/matlabcentral/answers/uploaded_files/857395/testA.png");
size(I)
ans = 1×2
600 600
figure
imshow(I);
% approximate background using morphological opening
se = strel('disk',35);
background=imopen(I,se);
figure
imshow(background);
% subtract background
I2=I-background;
% figure
% imshow(I2);
% increase contrast
I3 = imadjust(I2);
figure
imshow(I3);
% binarize image and remove background noise
bw = imbinarize(I3,0.30);
bw = bwareaopen(bw,10);
[L,num] = bwlabel(bw);
stats = regionprops(L);
rects = cat(1, stats.BoundingBox);
ind = find(rects(:,2)<2);
for k = 1: length(ind)
bw(L==ind(k)) = 0;
end
figure
imshow(bw);
% count number of objects
cc = bwconncomp(bw,8)
cc = struct with fields:
Connectivity: 8 ImageSize: [600 600] NumObjects: 197 PixelIdxList: {1×197 cell}
cc.NumObjects
ans = 197
%view extracted objects
figure
final_im=imoverlay(I, bw, 'r');
imshow(final_im);
hold on
c = regionprops(cc,'centroid');
centroids = cat(1,c.Centroid);
plot(centroids(:,1),centroids(:,2),'b.')
hold off
  1 commentaire
SNIreaPER
SNIreaPER le 10 Jan 2022
I guess you added this (unless I've missed something):
[L,num] = bwlabel(bw);
stats = regionprops(L);
rects = cat(1, stats.BoundingBox);
ind = find(rects(:,2)<2);
for k = 1: length(ind)
bw(L==ind(k)) = 0;
end
figure
imshow(bw);
  1. Could you please explain briefly what this is doing?
  2. Some of the smaller foreground objects (small circles) are still not included, is there a way I can include those as well?

Connectez-vous pour commenter.

Produits


Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by