Corrosion Thickness Measurement



Hello Everyone,

I am new to ImageJ platform. Can anyone help me write a Macro for the corrosion thickness measurement? Recently I have been using ImageJ to measure the corrosion thickness of my samples. I am doing it manually, which involves measuring 108 samples for each experiment. I have attached the micro-structural image of my sample for your reference and also the step by step procedure of my manual processing.

  1. File --> open (Insert Image)
  2. Analyze --> Set Scale
  3. Line option (Draw a minimum of 50 lines to measure thickness of corroded layer)
  4. Analyse --> Measure
  5. Summarize the data (Required information: Maximum length, Minimum Length and mean length )

It would be great if someone has an idea to write a macro for this. Thank you for your time. Looking forward for your help.

How to get profile data from image?
Which Version Should I Use

Good day!

Here is an example

from the left top of your sample image that shows how a contour of the corroded layer can be followed by a suitable algorithm. As you may realize, the image was inverted for this purpose and it has been lowpass filtered.

You must decide if lowpass filtering is allowed because it generally reduces the accuracy of the measurements.

Of course, one may find the corresponding top contour and from both you can continuously calculate the thickness.

See the recent threads:



Measuring distance between two lines

Hello Herbie,

I tried using the Weka segmentation and got the contour of the corroded layer but not able to find the thickness of the corroded region. The “analyze Skeleton” option gives only the longest and shortest path but I need the maximum thickness and mean thickness of the selected ROI (Top and bottom). Could you please explain me how can I measure the thickness?

recently i also came across another type of corrosion(Localized corrosion[No corrosion in some area]). see image below. I managed to skeletonize them also but I dont know to find the thickness.

Since im new to imageJ, it would be great if you can briefly describe me the process to measure the thickness.
I find that the contour that you determined is more accurate than skeletonization(missing some parts of corroded region).

Can you briefly explain me how you determined the “contour” layer? What is the plugin that is used to measure the thickness of the corroded region? It is good if I avoid low bypass filtering so that I get accurate measurement.



Good day Pranav,

in his thread
Mark describes a method and gives a reference:

I did an experimental macro that performs what I mention in this post:
I think that this simplyfied approach is sufficient for most purposes. However, coding the approach desired by Mark is more involved.

If you have the contours from both sides of the corrosion layer, you can easily compute the thickness by subtracting corresponding contour values.

To my knowledge there is no ImageJ-plugin that performs either Mark’s approach or mine. In short, I fear you have to code a suitable method yourself.

Concerning lowpass-filtering: I didn’t investigate what is the optimum filtering to make the approach work reliably.





for your sample image I could reliably determine the inner contours after image binarization. However the definition of the outer contours is not obvious to me.

Here is an enlarged excerpt from the sample image with your drawing:

How would you formally define the position of the upper end of the yellow line?

Furthermore, shouldn’t the yellow line be exactly vertical?




Hello Herbie,

It is great that you could determine the inner contour.

For the outer contour I will generally draw a straight line(red line as indicated in the image below) where I could clearly differentiate the corroded region from the embedding (see image below).

If the outer contour is uneven (as shown below) i will draw a straight line between the highest points and then draw a vertical line to the inner countour.

Regarding the inner contour I need to exactly trace the corroded region like you have defined in the image.

The vertical yellow line (In your last reply) should be as vertical as possible, so that the measurement is accurate. So generally the vertical line is measured from the upper straight line to the inner contour.

Addidtional information: All my images are taken at 500µm. It would be great if the output of my Maximum and Mean thickness is in µm. I generally use “set scale” to define it. If you can intergrate it into the macro it would be awesome. the distance in pixel is 199, known distance 500 and unit of length is µm.

Thank you for your help.



Thanks Pranav for the details!

Meanwhile I tried to define the outer contours by a straight line just as you’ve now suggested.

One more question:
I assume that the outer contours are horizontal ±0.5 deg. At least this holds for your sample image.

The µm unit is no problem.

There are still some details of the macro to be determined but I think that you’ll see a final version soon.

Stay tuned



Hello Herbie

It is not a problem if the horizontal lines (outer contour) has a tolerance of ±0.5 deg.
That is a great news. Looking forward for the result.

Write me if you require more details.

This was my aim for this measurement:

  1. Batch processing of images(I generally have minimum 108 images) at one time
  2. Measurement of Maximum, Mean and Minimum thickness on top and bottom corroded region for each image
  3. Result for Max, Mean and Min. thickness in µm. Report the 3 thickness for both top and bottom corroded area for
    each image.

Thank you for your help.



Dear Pranav!

It is not a problem if the horizontal lines (outer contour) has a tolerance of ±0.5 deg.

Originally, I meant something different, namely if you can guarantee that the outer boundaries are aligned horizontally within at least ±0.5 deg.

This is important because the first part of my macro tries to horizontally align the image more precisely in order to automatically find the best outer borders. If your images should show greater deviations than ±0.5 deg, my presently applied method would be sub-optimum.





Yea the outer boundaries are always aligned within ±0.5 deg. I can guarantee you that.



Dear Pranav,

would these contours (inner and outer)

be acceptable?




Hello Herbie,

This is perfect.



Dear Pranav,

things appear to converge …

the distance in pixel is 199, known distance 500 and unit of length is µm.

Using the scale-bar I get: 296pel equals 500µm.

Please confirm!



Here are the thickness measures in µm I get with “296pel equals 500µm” from your sample image:


Hello Herbie,

I checked the scale bar and I am still getting the same result.

I am not sure what is pel?

I checked the result obtained by you with my manual measurement. They correlate with each other (Max. thickness: Top 253 and bottom 260). Just check my scale bar and compute the result.



Thanks for checking Pranav!

Here is my result from your sample image “Optical Microscopy_000006.jpg”:

( pel = pixel )




Hello Herbie,

I found the problem. I had the same image taken from different microscope. Since they have different pixels they give values.

It would be great if the macro always measures the line and determines the value for each image. Hope it is not making the process complicated.



Dear Pranav,

we are surpassing the point where the gratis volumn of help is exhausted. Perhaps we should continue on a commercial basis …

Do you have a budget for this work?




Hello Herbie,

There is no budget for this work. I am doing it as part of my work so that I could save a lot of time.

It is not a problem. I can do it manually and determine the pixels. I think the macro that is written so far does all that i expected.

Edit: can you post the macro?

Thank you.



The following ImageJ-macro sets the image scale according to the scale-bar of the image, provided the scale-bar is located somewhere near the right bottom of the image and it looks like your scale-bars do. The macro works for your sample image “Optical Microscopy_000006.jpg”.

/////////////////////// begin macro
requires( "1.51t" );
run( "8-bit" );
b = 10;
setScaleFromBar( b );
/////////////////////// end macro
/////////////////////// begin functions
function diff( aa ) {
	for ( i = 1; i < aa.length; i++ ) {
		aa[i-1] = aa[i] - aa[i-1];
	aa[aa.length-1] = 0;
function getBeginEnd( aaa ) {
	mi = Array.findMinima( aaa, 0 );
	mx = Array.findMaxima( aaa, 0 );
	if ( mx[0] < mi[0] ) aaa[1] = mx[1]; else aaa[1] = mx[0];
	if ( mi[0] > aaa[1] ) aaa[0] = mi[1]; else aaa[0] = mi[0];
function setScaleFromBar( bb ) {
	run( "Set Scale...", "distance=0 known=0 pixel=1 unit=pixel" );
	ww = getWidth();
	makeRectangle( 0, bb, ww, getHeight() - 2 * bb );
	setKeyDown( "alt" );
	a = getProfile();
	setKeyDown( "none" );
	min = Array.findMinima( a, 0 );
	if ( min[0] > min[1] ) yy = min[1]; else yy = min[0];
	pel = abs( min[1] - min[0] );
	a = Array.slice( a, yy + pel );
	diff( a );
	getBeginEnd( a );
	makeRectangle( 0, yy + bb + pel + a[0], ww, abs( a[0] - a[1] ) );
	a = getProfile();
	run( "Select None" );
	diff( a );
	getBeginEnd( a );
	pel = abs( a[0] - a[1] );
 	run( "Set Scale...", "distance=" + pel + " known=500 unit=µm" );
/////////////////////// end functions

Paste the macro code to an empty macro window (Plugins >> New >> Macro) and run it.

You’ve only today mentioned that you work with differently sized images and this means that I must change a lot of code in the corrosion-thickness macro. Presently, I don’t have the time to do so.



Using ImageJ to automatically set scale by detecting a scale bar in the photo

Hello Herbie,

Thank you for the macro. This is a great work. It is not a problem I can work on the microscope that correlated with this macro. Kindly check your private inbox.

Thank you.