Layer Thickness measurement (in pixels) on images

I want to determine the average thickness (in pixels) of a layer I have segmented, such as shown in the figure below:
What I would prefer is to:
  1. Determine boundary pixels (this would be boundaries = bwboundaries(bwImage) or bwperim(bwImage) which gives you the binary of just the boundary pixels)
  2. Determine the pixels of the outer (or inner) edge
  3. Select a number of evenly spaced boundary pixels of the outer (or inner) edge
  4. Determine in each of these pixels the slope of the edge by using a minimum number of nearest neighbor pixels belonging to the edge and making a linear fit.
  5. Determine the distance between the corresponding pixel and the nearest neighbor along the normal (perpendicular) of the slope in each of the pixels of step 3.
  6. Average all distances and plot the tangents constituting the measured distances on the image (~ 50 measurements)
I've tried to explain the steps in the image given below:
But I don't how to translate this to code (espesially step 2).

1 Comment

In the second figure it should of course ne "Nearest neighbor normal to slope" and not tangent

Sign in to comment.

Answers (1)

One way to do it is to call bwperim(). Then erase the pixels on the top row or right column. Then erase below whatever line you want to erase the slightly wavy bottom edge of the thing. Something like
edgeImage = bwperim(mask);
% Erase top row
edgeImage(1, :) = false;
% Erase right column
edgeImage(:, end) = false;
% Erase below some line
edgeImage(bottomRow : end, :) = false; % You need to define bottomRow in advance.
% Now label each curve
labeledImage = bwlabel(edgeImage, 4);
% Extract left/top edge
leftEdge = ismember(labeledImage, 1);
% Extract right/bottom edge
rightEdge = ismember(labeledImage, 2);
% Then use find to get the coordinates of each
[y1, x1] = find(leftEdge);
[y2, x2] = find(rightEdge);
% Get distances to each
distances = pdist2([x1, y1], [x2, y2]);
% Find the min distance to curve 2 from curve 1
minDistances = min(distances, 2);
% Get average thickness
meanThickness = mean(minDistances);

2 Comments

Thanks,
your anwser works though:
bwlabel should use 8-connected: labeledImage = bwlabel(edgeImage, 8); and minDistances should be on columns minDistances = min(distances);
There is one kink in the method. For my nice and relatively smooth layer it works perfectly well, however if you would apply the same method on a layer which could have some prominent bulges, the minimum distance between pixels of each edge would no longer apply as the thickness in this bulged region. However, my suggested (conceptual) method with using the slope would also only work if the bulge is only prominent in one edge and then you would have to locate this edge.
Thanks a lot
OK, if one side is wavy and you want the width to go "perpendicular" from the opposite side, you can do it your way. Did you do it yet? You can
  1. use bwboundaries to get the (x,y) coordinates of the edges,
  2. then smooth the lower edge with something like movmean() or sgolayfilt() (demo attached),
  3. compute endpoints for a line segment,
  4. then use improfile() to extract the pixel values along that line,
  5. then look for the first non-zero pixel.

Sign in to comment.

Products

Release

R2021b

Asked:

on 3 Mar 2022

Edited:

on 7 Mar 2022

Community Treasure Hunt

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

Start Hunting!