Cleaning background for binarizing an image

4 views (last 30 days)
I am trying to isolate wool fibers from a background on scanning electron microscopy images using thresholding and binarizing. However, I can't seem to isolate the fibers well on a background that's not completely plain (see attached image for instance and final binarized image where I cannot get rid of the features in the background.) I have tried multiple closing steps, cleaning steps etc and I am running out of ideas unfortunately. I am attaching my code and additional files required to run it (along with the original image). Any idea on how to clean the image further?
%% Initial Setup %%
clearvars, clc, close all
[file, p] = uigetfile('*.*');
R=['File name:', file];
disp(R)
I = imread(fullfile(p,file));
% I = imread('C:\Users\Leo\Documents\MATLAB\Large_Fiber_Images\LX1000.jpg');
warning off
ftitle = 'Converstion Ratio Question';
quest = '\fontsize{10}Do you know the pixel converstion ratio (\mum/pixel)?';
btn1 = 'Yes'; btn2 = 'No, but I want to measure it'; btn3 = 'There is no scale bar';
opts.Interpreter = 'tex'; opts.Default = 'Yes';
answer = questdlg(quest,ftitle,btn1,btn2,btn3,opts);
switch answer
case 'Yes'
dessert = 2;
case 'No, but I want to measure it'
dessert = 1;
case 'There is no scale bar'
dessert = 0;
end
if dessert == 2
prompt = {'\fontsize{10}What is the pixel converstion ratio (\mum/pixel)?'};
dlgtitle = 'Input';
dims = [1 65];
definput = {''};
opts.Interpreter = 'tex';
conv = inputdlg(prompt,dlgtitle,dims,definput,opts);
conv = string(conv);
conv = str2double(conv);
elseif dessert == 1
conv = 0;
while conv == 0
togglefig('Original Image')
imshow(I)
h = imdistline;
fcn = makeConstrainToRectFcn('imline',get(gca,'XLim'),get(gca,'YLim'));
setDragConstraintFcn(h,fcn);
prompt = {'\fontsize{10}What is the length of the scale (\mum)? This will be the number next to the scale.','\fontsize{10}What is the pixel length of the scale bar? Use the distance tool over the image.'};
dlgtitle = 'Input';
dims = [1 58];
definput = {'',''};
opts.WindowStyle = 'normal';
opts.Interpreter = 'tex';
answer = inputdlg(prompt,dlgtitle,dims,definput,opts);
scale = answer(1); scale = string (scale); scale = str2double(scale);
measure = answer(2); measure = string (measure); measure = str2double(measure);
conv = scale / measure;
end
close all
elseif dessert == 0
conv = 0;
end
% % temporary shortcut for writing code
% I = imread('/Users/serafinafrancetribe/Desktop/research/textiles/URI 2023/cecile sem images/SEM_NU/merino_wool_os_9nm/20221102_21.TIF');
% conv = 0.04;
I = I(1:end-90,:,1);
%Removes SEM information (e.g. scale bar, magnification, etc)
togglefig('Original Image')
imshow(I)
drawnow
%% Imaging %%
% Ihist = adapthisteq(I);
% togglefig('Hist Eq')
% imshow(Ihist);
% skipping adapthisteq turns whole fiber pale with dark background in this
% case
Ihist = histeq(I);
togglefig('Hist Eq')
imshow(Ihist);
%% Imaging Continued %%
%level = graythresh(I) + 0.1;
level = adaptthresh(I, 0.1 ,'Statistic', 'gaussian');
BW = imbinarize(Ihist,level);
togglefig('Binarized Image');
imshow(BW);
BW = bwareaopen(BW, 500);
togglefig('remove tiny guys Image');
imshow(BW);
BW = imclose(BW, strel('disk', 1));
togglefig('Closed Image');
imshow(BW);
BW = bwmorph(BW, 'clean', 100000);
togglefig('cleaned Image');
imshow(BW);
% No noticeable difference with this morph
% BW = bwmorph(BW, 'fill', 5000000);
% togglefig('Filled Image');
% imshow(BW);
BW = bwmorph(BW, 'majority', 500);
togglefig('Majority Image');
imshow(BW);
BW = bwmorph(BW, 'thin', 5);
togglefig('Thinned Image');
imshow(BW);
% % repeat closing image to remove some remaining spots
% BW = imclose(BW, strel('disk', 5));
% togglefig('Closed Image');
% imshow(BW);
BWf = medfilt2(BW);
i = 0;
while sum(sum(BWf)) ~= sum(sum(BW))
i = i + 1;
BW = BWf;
BWf = medfilt2(BW);
end
togglefig('Filtered Image');
imshow(BW);
BW = bwmorph(BW, 'thicken', 5);
togglefig('Thickened Image');
imshow(BW);

Answers (1)

Image Analyst
Image Analyst on 20 Jan 2023
Will you always be analyzing just a single fiber in focus?
Why don't you try stdfilt? Within the fiber the StDev should be high but in the smoother background it should be lower so you can jsut threshold it and fill it in. Here's a start
sdImage = stdfilt(grayImage, windowSize);
mask = sdImage > someThresholdValue;
mask = imfill(mask, 'holes');
  1 Comment
Cecile Chazot
Cecile Chazot on 20 Jan 2023
I will always be analyzing a single fiber in focus. I did not know stdfilt, so I'll look into this. Thanks so much!

Sign in to comment.

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!