Thickness, Porosity and Pore Size Distributions

Dear experienced BoneJ-ers,

I was wondering wether anyone of you tried using “Thickness” on a material to estimate its porosity. If I understand the method correctly, I will receive a frequency distribution of maximum diamters for spheres fitting in objects in my binarised image stack. Has anyone tried to calculate a porosity using such data? I would like to compare µCT porosity to my results from Hg intrusion. Does anyone, who is more experienced than me, know if it is more convenient to use “Particle Analyser” instead?

Best regards,

Phillip

1 Like

Dear Phillip,

What do you mean by ‘porosity’?

If you mean the fraction of the sample that is pores, then you should use Volume Fraction. If you want statistics on each individual (unconnected) pore, then use Particle Analyser. If you want a measurement of the distribution of diameters (‘thickness’) of pore spaces, then use Thickness.

This is less a question of convenience than getting to understand what it is that you are trying to measure, and choosing the appropriate plugin to do that.

Michael

1 Like

Dear Michael,

thank you for your quick reply!

Basically, I was wondering whether it was possible to convert the distribution of diameters of pore spaces obtained by ‘thickness’ to a volumic distribution - in other words pore volume fractions classified by diameter.

I am sorry if I appear a little confused here but as you perhaps already guessed I am new to ImageJ as well as BoneJ and have a lot to learn as it seems.

Phillip

Hi Phillip,

If you make a histogram of the Thickness image you will get what I think you are describing. Hit [h] on your keyboard.

The height of each histogram bar will tell you what number of pixels are in each range of thickness that each bar represents. Dividing by total number of pixels will give the volume fraction of pore space with that thickness. Bear in mind that you have to take into account pixels with thickness = 0, which is background or non-pore parts of the image (i.e. the material the pores are in) (we are fixing that at the moment; a better value for background in this context is Double.NaN).

Michael

Hi Michael,

thank you very much!

I tried to follow your explanation and applied ‘Thickness’ to a cropped and binary image stack.
I added up all ‘count’ values of trabecular spacing except for those with a diameter of zero and used this as ‘total pore space’. I applied ‘Volume Fraction’ on the same stack and compared the resulting total pore volume fraction to the quotient ‘total pore space’/‘total pixel count’ (=image resolution; including those pixels with diameter zero). I also did the same for the results of trabecular thickness.
Absolute deviation in pore-/‘bone’-volume is 2.51 % (more pore volume calculated with ‘Volume Fraction’).

I am writing this, since I did not exactly understand what you meant by your annotation about including background/non-pore pixels (at least in a binary picture) but assumed ‘Volume Fraction’ and my pixel count ratio should give comparable results if I did not exclude a large number of pixels. How wrong is that on a scale of 1 to 10? :grimacing:

Phillip

Hi Phillip,

2.5% discrepancy is not too bad, although I’d tend to go with Volume Fraction as the measurement for pore volume / total volume. I wonder whether your histogram has got a few (~2.5%…?) very small pore spaces included in the lowest, zeroth, bar, which will extend from 0 to a bit more than 0 (that’s why NaN is a better value for background here…).

Michael

1 Like

Hi Michael,

Thank you for your help! You will be right about the addition of small pore spaces to the lowest bar of my histogramm but I think you lost me with NaN as alternative background value:
I tried to count NaN pixels based on the NaN example macro (getRawStatistics before minus after “Remove NaNs…”) but it returns zero.
Still, I would like to try what you proposed and use NaN as background value but I am not sure if I have choosen a suitable path to obtain that data.

Phillip

Hi Phillip,

At the moment, Thickness sets background to 0, not NaN. We are changing the code so that NaN is the background value, because it is easier to handle that way for later analyses. In the meantime you might like to try converting all the 0 values to NaN, though I’m not sure of the easiest way to do that. Perhaps a macro could do it, if you loop over all the pixels and do an if (getPixel(x,y) == 0){ setPixel(x,y,NaN); }

Although I’m not sure if the macro language will accept NaN as a numerical argument.

Michael

It should work, although you can also directly use:

setThreshold(1,1e99);
run("NaN Background");

Hello again,

thank you for your help!

Michael, it seems like NaN was assigned as pixel value perfectly fine. The results are, however, the same not counting the now completely gone zero-diameter-fraction. There is no difference in total sum of ‘counts’ in ‘Thickness’ as well as in ‘Spacing’ resulting in the same difference in volume compared to ‘Volume Fraction’. Would it be correct to conclude that there are no small pores included in the zero diameter fraction? I was expecting a difference based on how I think ‘Thickness’ works. May be the irregular pore shape contributes to the difference.

AlexW, your approach may also work, but the threshold unfortunately removes all but the largest pore in my stack.

setThreshold(1,1e99);
run("NaN Background");

Hi Phillip,

Thanks @AlexW for the suggestion. @Phillip’s image is 32-bit so the minimum non-zero value could be very small and only just bigger than 0.

So, the code should rather be

setThreshold(1e-99,1e99);
run("NaN Background");

Or some other very small, positive value instead of 1e-99.