Measuring thickness (or width) of cracks

Hi everyone,

I’m new to image processing and I’ve encountered a problem I can’t solve.
I have images of cracked rock (shapes in black). I would like to calculate the width of the cracks and their average width. I have tested some methods proposed in the forum but it doesn’t work. If someone can propose me a method of automatic thickness (or width) calculation, I would be grateful.
Thank you in advance.

Ps: The attached image represents a single slice. The images on which I am working are composed of thousands slices.
Image: img.tif (2.8 MB)

Have a look here:
https://www.optinav.info/Local_Thickness.htm

1 Like

Another way could be to used the product of the Distance Map and the Skeleton of the thresholded binary image.
The result is the distance to the outer contour for each of the skeleton points (which are the maxima of the distance map and therefor a kind of major axis of the crack).

The following macro applied to the posted image

should demonstrate the principle:

setOption("BlackBackground", true);

setThreshold(69, 132);
run("Convert to Mask");

rename("orig");
run("Duplicate...", "title=dist");
run("Duplicate...", "title=skel");

selectWindow("dist");
run("Distance Map");

selectWindow("skel");
run("Skeletonize");
run("Divide...", "value=255");
setMinAndMax(0, 0);

imageCalculator("Multiply create", "dist","skel");
selectWindow("Result of dist");
run("Fire");
setMinAndMax(0, 57);
2 Likes

Hey phaub,
Thank you for your prompt response.
I tried to rup your script. All commands work except the last command ‘‘fire’’ which doesn’t work. I couldn’t get the thicknesses (widths) I’m looking for.
Do you have an idea about this problem ? How can I get a table of values?
Thank you in advance
Last image obtained : Result of dist.tif (1.4 MB)

Hey Gabriel,
Thank you for your response.
I’m looking for numerical values of the thickness, i.e. a table. I think this method gives only images.
Can I output an array or numerical values of the calculated thicknesses? Or scale?
Thank you in advance.

I think the colours in the image should give you he local thickness values.
You mentioned “far from reality” results. Is your image properly calibrated? Did you read the two papers associated with that plugin (in the link provided).
Results in the image itself seems to me good (perhaps the best) way to represent a point-wise analysis.

1 Like

The images of the procedure should look like:

Your result image shows an outline. That is not correct.

Pls make sure that the images ‘dist’ and ‘skel’ look like in my overview image.
Adjust the Brightness/Contrast to display the pixels in ‘skel’ because they only have intensity value = 1. (only for your proof - not necessary during macro execution)

The result is not given as a table but as an image.
The intensity values of the pixels represent the distance between outer contour and skeleton line.

I used the Fire LUT to display the distance values in different colors (see menu Image/Lookup Tables, there should be an entry ‘Fire’). You can use any other LUT if ‘Fire’ is not available on your system. This is only cosmetics.
I have change the order of the last two lines of the macro. Pls check if it works with this change.

Thank you very much for your help.
I have succeeded in getting my images. My objective for this work is to compare cracking thickness for several images (thousands). Is it possible to make a comparison between the images by this method? Also I didn’t understand how I can convert the intensity values of the pixels into thicknesses “The intensity values of the pixels represent the distance between outer contour and skeleton line”???
Thanks in advance

Pls check the macro step by step.

The Distance Map shows for every pixel (point) inside the crack the distance to its outer contour (edge of the crack). ok?
Obviously this distance has its maximum in the middle of crack. (see image ‘dist’). This maximum values are interesting for you because they show the distance of the middle line to the counter (or in other words the half width of crack) along the crack.

So how to find the maximum line?
This can easily be done with the function Skeletonize. Skeletonize exactly delivers this maximum line.
But the skeleton image only shows the position of the line and does not contain distance information. Therefore I changed the skeleton image to a binary image with intensity 0 for background and intensity 1 for points on the line (this is done by run(“Divide…”) ).
Then I multiplied the distance information in ‘dist’ with the line position in ‘skel’. So all the background and all values of the crack are eliminated (multiplied by 0) and only the values of the middle line/maxmimum line remain unmodified in the image (multiplied by 1).

The resulting image shows the distance (half width of crack) along the middle line of the crack.
voilà

How can you analyse the data?
All the information can be derived from the image histogram.
(menu Analyze/Histogram)

  • The number of pixels with intensity > 0 are a representation of the cracks length.
  • The maximum of the histogram is a representation of the maximum of the half-width of the crack.
    The mean value of all pixels with intensity > 0 is a representation of the mean value of the half-width of the crack.

Those values can be calculated from the histogram array in the macro and can be used to compare the different cracks. ok?

(For more information on how to work with macro and arrays please see the macro examples and macro language documentation.)

(Advanced: Even the progression of the width along the crack could be calculated from this kind of result images.)

regards
peter

2 Likes

Hi Peter,
Thank you very much for the explanation.
I tried to follow the sequence of instructions you explained to me. I understood the principle of calculation.
I used this macro to output the results of the histogram.

nBins = 256;
run (“Clear Results”);
row = 0;
getHistogram(values, counts, nBins);
for (i=1; i<nBins; i++) {
setResult(“Value”, row, values[i]);
setResult(“Count”, row, counts[i]);
row++;
}
updateResults();

And I got the following results:

Total value= 570
mean= 2.24
Max= 72

And I calculated the width of the cracks as you explained…

  • The results obtained overerestimate the real width of the cracks.
    I use the scale : 22.3463 pxl/mm.
  • e.g. for average width is between 3.70 and 4.70 mm approx. (measured by ruler)
    -And by the calculation obtained by the histogram I found width =6.44 mm
  • length (by hysterogram)= 25.50 mm //// length (byruler) =18 mm
    Attached are all data and results obtained
    orig1.tif (1.4 MB) Result of dist1.tif (1.4 MB) Results cracks.csv (4.4 KB)
    Thank you in advance

I performed the analysis with the above macro on your original image.
Then I exported the histogram values of the result image to excel and calculated the following results:

Total (intensity/distances) = 60984
Total Pixels (length of crack) = 3183
Max = 48 pixels
Mean = 60984/3183 = 19.16 pixels

=>

Max width of crack = 2 * 48 pixel = 96 pixel
(this can be confirmed by manual measurement in the original image)
Mean width of crack = 2 * 19.2 pixel = 38.4 pixel

With your scale (22.3463 pxl/mm) I get:
Max Crack Width = 4.29 mm
Men Crack Width = 1.71 mm

Pls check your histogram macro and/or use Excel for cross checking your analysis.

Hi,
I repeated the calculations on the image that we processed yesterday and I got nearly the same results that you found. I don’t know why it didn’t work for the other image.
Anyway, I would like to thank you very much Peter for your help and relevant explications.
That is very gracious of you

1 Like

You are welcome!

One more hint:
Be aware of the threshold command in the macro

The values are selected manually for your test image.
They must not fit to other images.
To use autoThreshold you should set the black background outside of the circular area to white before autoThresholding.

1 Like