Image processing: Determine fiber diameter

11 vues (au cours des 30 derniers jours)
Bjorn
Bjorn le 25 Avr 2018
Modifié(e) : Image Analyst le 22 Mai 2021

Dear reader,

A fabricated fiber structure is made visible using a SEM. The fibers in these images needs to be analyzed: I’m especially interested in the fiber thickness. It would be nice to write a Matlab-script that could do the image analysis and provides a histogram of the determined fiber thicknesses. An example of such a SEM-image is found below.

Using image thresholding and morphological opening- and closing, a binarized figure is obtained. This image is used for edge detection and skeletonization. The figure below shows the image that is obtained

The upper figure is obtained using the following code

clear all; close all; clc
I = imread('ZnAcetate.tif');
se1 = strel('disk',4);
se2 = strel('disk',1);
BI = imbinarize(I,0.4);
filter1 = imclose(BI,se1);
filter2 = imopen(filter1,se2);
inverse = imcomplement(filter2);
ED = edge(filter2,'Sobel');
skel = bwmorph(filter2,'skel',Inf);
BP = bwmorph(skel, 'branchpoints');
EP = bwmorph(skel, 'endpoints');
[y,x] = find(EP);
BP_L = find(BP);
Dmask = false(size(skel));
for k = 1:length(x)
    D = bwdistgeodesic(skel,x(k),y(k));
    distanceToBranchPt = min(D(BP_L));
    Dmask(D < distanceToBranchPt) = true;
end
skel = skel - Dmask;
figure(1)
muxing = ED | inverse;
imshowpair(muxing,skel,'blend')

At this stage, the normal distance between two parallel lines needs to be determined. The center line of each fiber should be used to determine the thickness between two real edge lines.

I have been searching the net, but I could not find a real useful example that could be implemented in this particular case. I guess a distance transformation needs to be used to determine the fiber thicknesses.

Does somebody have any suggestion how to tackle this problem?

Thank you in advance!

Kind regards,

Bjorn

Réponses (8)

Felix Ruhnow
Felix Ruhnow le 17 Oct 2018
Try looking at fibermetric() in the image processing toolbox!

JBM
JBM le 15 Août 2018
Try the DiameterJ plugin for ImageJ.
  1 commentaire
Tao Yang
Tao Yang le 22 Mai 2021
DiameterJ is not working now

Connectez-vous pour commenter.


Bjorn
Bjorn le 25 Août 2018
Dear JBM,
yes, I tried DiameterJ. However, this plugin does not allow us to do statistical analysis of any kind of the diameter of the fibers. For this reason, it is tried to write/develop the code ourselves.
Kind regards,
Bjorn

Image Analyst
Image Analyst le 25 Août 2018
Modifié(e) : Image Analyst le 22 Mai 2021
To get a width distribution, use bwdist() and bwmorph().
  1. Compute the Euclidean distance transform with bwdist()
  2. Compute the skeleton with bwmorph()
  3. Multiply them together.
  4. Take the histogram of that product image to get the radius distribution.
  5. Multiply the radius values by 2 to get diameter values.
See attached demos.

Yanan Wang
Yanan Wang le 24 Avr 2019
Have you figure it out? Thanks a lot.

JBM
JBM le 24 Avr 2019
Hi all,
I've developed a script that will help you measure fibre diameters manually. If you supply the script with a 1024 x 768 pixel SEM image of a fibrous filter, the script will present you with 100 x 100 pixel sub-images containing a crosshair. You then use the MATLAB distance measure tool to meaure the diameter of the fibre whose centreline passes closest to the crosshair, and save this as a variable. Measuring about 100 fibres takes 20 minutes or so, and produces a reasonable distribution.

Bjorn
Bjorn le 24 Avr 2019
Dear JBM,
Matlab is giving me this error when I try to run the script:
d_f = [d_f distance1]
Error using eval
Undefined function or variable 'distance1'.
Error in test (line 108)
eval(['d_f = [d_f distance', int2str(i), '];']);
Perhaps it my image does not have the required contrast? I uploaded a SEM image having the required 1024 x 768 pixel size.
Kind regards,
Bjorn
  1 commentaire
Image Analyst
Image Analyst le 25 Avr 2019
You don't want to use eval() anyway.

Connectez-vous pour commenter.


JBM
JBM le 25 Avr 2019
Hi Bjorn,
Before running the section of code "Read in diameters in pixels", you need to run the section "Generate random points" at least twice.
You need to run the section "Generate random points" at least twice because when you first export the measured distance to the MATLAB workspace, the auto-generated variable name is "distance", not "distance1".
When you measure your second sub-image and export the measured distance, the auto-generated variable name is "distance1", and for the third, "distance2", and so on.
I normally try and measure ~100 fibres, and then run the "Read in diameters in pixels" section that puts the values from each auto-generated "distanceN" variable into a single variable. Adjust the value of N in the loop for however many fibres you have measured.
The use of "eval", as Image Analyst rightly points out, should in general be avoided. However in this instance it is a workaround to allow the auto-generated distance values to be read in to a single variable.
  1 commentaire
Image Analyst
Image Analyst le 26 Avr 2019
One possible approach might be a modified version of what I did my Ph.D. dissertation on (vessel tracking using A*). You could drop down random boxes and then start on each of two sides of the box. Then use dynamic programming to find the path to the opposite side that has a low enough intensity standard deviation (meaning you're running along a fiber and it's not interrupted/crossed at all). If you can find such a smooth path running across the box, assume it's a fiber and then start taking perpendicular cross sections to the path and compute the widths, mean width, and width distribution. Sorry, I don't have code for it, and it will take longer than 5 minutes to code up so you're on your own.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by