Grain size distribution of irregular particles

Hi, I’ve got the SEM image, and I’d like to know the average grain size and the size distribution.

I was wondering if this is correct or not…

Here are the steps:

Original image (I can’t upload the tif file, but the scale is 6.7875pixels/um)

Type → 8 bit
Plugins → MorpholibJ → Seqmentation → Morphological Segmentation → Run (Display in Watershed line)

Image → Lookup tables → Invert LUT

Process → Binary → Watershed

Analyze →Analyze Particles (show outlines)

I was wondering the average size is correct. (is it 1.172um? right?)
And how to obtain the size distribution?

Hi Jeep,

I’m new to imageJ, but I really like to use it in my work. Recently, I also encounter some work requiring analysis of surface grain size.
First of all, I recommend you take SEM photo with larger magnification, which is easy for software to tell the boundaries.
Second, you can try weka trainable segmentation plugin. Train it (2 class, one is grain boundary, the other one the grain surface, ) and it will help you generate a probability.
Thirdly, use morpholibJ – morphological segmentation-(watershed line)
Next, analyze particle.
Finally, this process could give you a roughly segmentation results.
However, you still need to tune the “parameters” in each step, based on your sample and photo, to get the best segmentation results.

1 Like

Hi @nenine,

Thanks for your reply. I’ll try that and get back to you.

Sorry about the delay in reply @jeep168917… I’ve been out sick.

Anywho… looking at your data. Is the entire field of view filled with particles? There is no ‘background’ in your image? If this is the case… it seems your workflow is fine. Otherwise - you’d have to better delineate ‘object’ versus ‘background’. And you can write a script to plot the distribution of your object areas…

You can adapt this code:

getStatistics(area, mean, min, max, std, histogram);
if (bitDepth==8 || bitDepth==24)
    Plot.create("Histogram", "Value", "Count", histogram);
else {
    values = newArray(256);
    value = min;
    binWidth = (max-min)/256;
  for (i=0; i<256; i++) {
       values[i] = value;
        value += binWidth;
   Plot.create("Histogram", "Value", "Count", values, histogram);

Use the built-in macro functions to play around with the code and adapt as you see fit… but this is at least a start. :slight_smile:


1 Like

Hi @etadobson

Thanks for the reply.
I’m not really clear about bitdepth. What is it?
What is the “value”? how could I change into grain size?

Hi @jeep168917 !!

You can read up on that here.

If you are unsure of the bitdepth of your image (should say at the top of the image window)… you can always check using this macro function call:

Returns the bit depth of the active image: 8, 16, 24 (RGB) or 32 (float).

If you check the link I provide above to Built-In Macro Functions you’ll see that function call definition is as follows:

Plot.create(“Title”, “X-axis Label”, “Y-axis Label”, xValues, yValues)
Generates a plot using the specified title, axis labels and X and Y coordinate arrays. If only one array is specified it is assumed to contain the Y values and a 0…n-1 sequence is used as the X values. It is also permissible to specify no arrays and use Plot.setLimits() and Plot.add() to generate the plot. Use to display the plot in a window, or it will be displayed automatically when the macro exits.

Just play with the code a bit yourself… run it, modify it, etc. :slight_smile: You got this!

eta :slight_smile:

1 Like

Hi @etadobson

Thanks for your reply.

how could I change the Y-axis into grain size? Sorry I can’t find out how to do this…


I don’t quite understand what you need… I think you are referring to is the Scale of your image? You can read the available tools in the Scale section of the user guide… though I think what you want is the Set Scale tool, which will let you “define the spatial scale of the active image so measurement results can be presented in calibrated units.”

You can also read this older post on the same topic:

Hope this helps!


1 Like