This repository computes Pore and Grain Size Distribution (PGSD) from a segmented 3D micro-CT image using the local thickness method (maximum inscribed sphere at each voxel via Euclidean distance transform).
The script supports:
.rawvolumes (with dimensions frominput.txt).tif/.tiff3D stacks (dimensions read from file)
- Python 3.9+ recommended.
- Install dependencies:
- pip:
pip install numpy matplotlib seaborn scipy tifffile edt- conda:
conda create -n pgsd python=3.10 -y
conda activate pgsd
conda install -c conda-forge numpy matplotlib seaborn scipy tifffile edt -yNote: edt is optional but strongly recommended — it replaces the single-threaded scipy distance transform with a fast multi-threaded implementation. Without it, the code falls back to scipy automatically.
pgsd.py: main scriptinput.txt: user-editable configuration file
python3 pgsd.pyThe script reads input.txt from the same directory as pgsd.py.
1) Input file
filename: input image path (.raw,.tif,.tiff)
2) RAW file dimensions (required only for .raw)
nx,ny,nz: volume dimensions in voxels- For
.tif/.tiff, these are read directly from the file and must be omitted.
3) Phase labels
pore_label: voxel value representing pore spacesolid_label: voxel value representing solid/grain phase- For non-binary images, all voxel values other than
solid_labelare treated as pore.
4) Resolution
resolution: voxel size in micrometers (µm/voxel), used to convert radii from voxels to µm in the plot and summary statistics.
5) Measure
measure: which phase to analysepore— computes Pore Size Distribution (PSD)grain— computes Grain Size Distribution (GSD)
6) Performance
num_threads: number of CPU threads for the distance transform and maximum filter (requiresedt; ignored otherwise)
7) Output settings
cdf: set totrueto overlay a cumulative distribution curve on the plotsave_fig: output figure path (.pdfor.png)
1. Figure (save_fig):
- Volume-weighted size distribution as a bar chart
- Optional cumulative distribution function (CDF) curve on a secondary axis
2. Console summary:
- Porosity or solid fraction (%)
- Mode, mean, median, and maximum pore/grain radius (µm)
The local thickness method assigns to each pore (or grain) voxel the radius of the largest sphere that fits inside the phase and contains that voxel. This is computed efficiently as follows:
- Compute the Euclidean distance transform (EDT) of the phase mask — each voxel receives its distance to the nearest opposite-phase voxel.
- Find local maxima of the EDT — these are the sphere centres (inscribed sphere radii).
- Build a volume-weighted histogram: each centre contributes weight proportional to r³ (sphere volume), so the distribution reflects the fraction of phase volume occupied by pores/grains of each size.