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

5 views (last 30 days)
SNIreaPER
SNIreaPER on 8 Jan 2022
Commented: Image Analyst on 26 Jan 2022
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 Comments
Image Analyst
Image Analyst on 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.

Sign in to comment.

Answers (1)

yanqi liu
yanqi liu on 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 Comment
SNIreaPER
SNIreaPER on 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?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by