Image Analysis: measuring cusping and roughness

Dear All,
I am looking for a solution for the following problem. Please refer the image below.
A straight line was drawn though the mid-axis each of the black laths as shown. Lines perpendicular to this axial line were drawn to the peaks and valleys of the black laths.The height difference between peaks and valleys is defined as the roughness. The spacing between the valleys is defined as a measure of cusp spacing. Right now I am doing it manually and its subjective to lots of errors. Please suggest a way by which I can automate this process. ( ie findout the hight difference and spacing between an area of selected peaks and vallieys.

1 Comment

Funny. Two authors in one night posting the same questions as if for the first time when there had already been a discussion of the same topic weeks earlier:
http://www.mathworks.com/matlabcentral/answers/16296-image-analysis-finding-the-cusp-spacing

Sign in to comment.

 Accepted Answer

Here's how I would approach it:
% Read the image and convert to BW mask of peaks
I_orig = imread('cusp_micro.jpg');
I = rgb2gray(I_orig);
BW_peaks = im2bw(I);
% How far is every non-peak pixel from its nearest peak?
distFromPeaks = bwdist(BW_peaks);
% Let's only choose pixels further from a peak than any of its neighbours
maxDistsMask = imregionalmax(distFromPeaks);
[trI,trJ] = find(maxDistsMask);
trVals = I(maxDistsMask);
tr2pkDists = distFromPeaks(maxDistsMask);
% Now loop over each trough and find the image intensity of its nearest
% peak (add 5 pixels padding so we choose the max from a few nearby peaks)
pkInds = find(BW_peaks);
[pkI,pkJ] = ind2sub(size(BW_peaks),pkInds);
trPartnerPkVals = zeros(size(trI));
for i = 1:length(trI)
tr2allPkDists = sqrt((pkI-trI(i)).^2 + (pkJ-trJ(i)).^2);
withinRangeMask = tr2allPkDists < (tr2pkDists(i) + 5);
trPartnerPkVals(i) = max(I(pkInds(withinRangeMask)));
end
% Display what we've got:
I_norm = double(I)/double(max(I(:)));
figure, imshow(cat(3,I_norm,max(BW_peaks, I_norm),I_norm)), hold on
plot(trJ,trI,'m.')
% Now if we look at all of the maxdists in the image, how far away from
% peaks are they?
figure, plot(sort(tr2pkDists)), title 'Distribution of cusp spacing'
figure, plot(sort(trPartnerPkVals - double(I(maxDistsMask))))
title 'Distribution of roughness'
So the largest trough2pk distance (or cusp spacing) is around 40 pixels. Notice of course that there are a range of pk2trough values depending on where you look in the image, likewise measures of roughness. You may need a scheme to select maximum cusp spacing or roughness within an X-pixel radius of an area you're interested in, or something similar.
Thanks, Sven.

5 Comments

Hi Sven,
Thank you very much for the response .
This method really solves my problem. But my manual results shows some difference from the values. By cusp spacing, I meant the distance between two valleys. I have uploaded three more figures for your reference. By measuring the distance between valleys, I essentially get the "Subgrain Size" which is clearly be seen as a contrast difference inside the black laths. As you can see, the distance between peaks is not equal to the distance between the nearby valleys. Is this code measuring the same ? I am not familiar with the matlab functions so its hard for me to follow the code. seek your help
https://picasaweb.google.com/116243239493929305987/MatlabImageAnalysis#5669747708705297170
https://picasaweb.google.com/116243239493929305987/MatlabImageAnalysis#5669747834907479762
https://picasaweb.google.com/116243239493929305987/MatlabImageAnalysis#5669748713610544850
"measuring the distance between two valleys" is easy to say, but impossible to clarify.
Take for example, the 2nd image in your list above. Look at the long horizontal valley near the bottom of the image.
What is it's "distance"? How would you actually measure that? Why did you choose what you did to even *make* a measurement? I guess you need to choose:
A. Where in the long horizontal valley to measure *from*
B. Which of the many neighbouring valley to measure *to*
C. Which *point* in that neighbouring valley to measure to.
I don't see any straight-forward definition for A, B, and C.
Remember that distance is measured between two points. My algorithm above defined the two points as:
1. The local maxima of the distance map from the peaks
2. The part of the peaks closest to (1)
Well, The long laths with small valleys is an issue. I must consider a piece with a roundness, aspect ratio or so.
Here is an analysis of a processed image
https://picasaweb.google.com/116849636652679518537/Example2#5669919510020063826
https://picasaweb.google.com/116849636652679518537/Example2#5669919570387963842
We can see that there are four subgrains here indicated by a,b,c and d. If I exclude a and d and measure the cusp spacing ( or subgrain length), I must get the length between 2-4 and 4-6. My roughness values are difference between 1e-2f,2f-3g,3g-4h,4h-5i etc...
Manual measurements of the Cusp spacings gives me 104 pixels (2-4) and 128 pixels (4-6). But the matlab plot does not give those values. For roughness, the plot gives me a single value of 255, what I was looking for was the above mentioned for roughness. that certainly changes from one after the other.
We can see that point 6 is not detected by the algorithm. If we watershed on the original image, distance between two cut lines joining the ultimate point between them can be cusp spacing. difference between one of the cut lines and a perpendicular from the ultimate point to the edge can be the roughness value.
dear Sven,
Can I further join the points in each laths and draw perpendiculars from the line to the lath edges and measure their lengths based on a pixels distance we specify ?? so that the expected output should look like this
https://picasaweb.google.com/116243239493929305987/December292011#5691497323268999938
My idea is to just describe the laths roughness based on the distribution of lengths of perpendiculars based on the width we specify. At a particular width, there will be a nice distribution of long and short lines and I will be able to manipulate it further.
dear Sven
could you please guide me understanding this portion of the code ?
% Now loop over each trough and find the image intensity of its nearest
% peak (add 5 pixels padding so we choose the max from a few nearby peaks)
pkInds = find(BW_peaks);
[pkI,pkJ] = ind2sub(size(BW_peaks),pkInds);
trPartnerPkVals = zeros(size(trI));
for i = 1:length(trI)
tr2allPkDists = sqrt((pkI-trI(i)).^2 + (pkJ-trJ(i)).^2);
withinRangeMask = tr2allPkDists < (tr2pkDists(i) + 5);
trPartnerPkVals(i) = max(I(pkInds(withinRangeMask)));
end
what exactly is [pkI,pkJ] ?? and what does it do with the rest of the code ? when I tried plotting [pkI,pkJ], it filled everywhere other than the black pixels...
thanks in advance,
Shanoob

Sign in to comment.

More Answers (0)

Asked:

on 30 Oct 2011

Community Treasure Hunt

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

Start Hunting!