Skip to content

Basic Thresholding

Basic Thresholding classifies every voxel of a greyscale image as pore or solid by comparing its grey level with one threshold \(t\), chosen automatically from the image's histogram, or with a threshold that varies smoothly across the image. It doesn't denoise: noise on either side of \(t\) ends up in the binary image as isolated specks of the wrong phase.

  • Solves a two-class split of the grey levels
  • Methods Otsu (default), Li and a local, Gaussian-weighted threshold, from scikit-image
  • Reports a binary image at the source's size and voxel size
  • How to run it Basic Thresholding in the User guide

The method

  1. Normalise the whole volume to \([0, 1]\) using its global minimum and maximum.
  2. Threshold the whole 3D volume:

    Method Threshold \(t\)
    Otsu (default) One global threshold that maximises the between-class variance of the two classes it creates1
    Li One global threshold that minimises the cross-entropy between the image and its two-class version2
    Local (Adaptive) A separate threshold per voxel, from the Gaussian-weighted mean of a cube of \(b\) voxels on a side around it. It adapts to uneven brightness.
  3. Classify. Voxels at or below \(t\) become pore, as in most CT of rocks with air-filled pores. With Invert (keep above threshold), voxels above \(t\) become pore instead, for scans where the pores are bright.

Setting Symbol Default Range Meaning
Thresholding method Otsu Otsu, Li, Local (Adaptive) How \(t\) is chosen (above).
Block size \(b\) 200 3–501 Local only: side of the neighbourhood, in voxels. An even \(b\) is raised to the next odd number, so the default runs as 201.
Invert (keep above threshold) off Make voxels above \(t\) pore.
A synthetic 140 × 140 greyscale image with dark pores, blurred and with added noise, run through PoreStore's own thresholding code with Otsu and invert off. The histogram is of the normalised intensities; voxels at or below t become pore. Noise leaves isolated specks on both sides of the threshold, since basic thresholding doesn't denoise.

Preview and full run

The preview thresholds a single slice, so its Otsu or Li threshold comes from that slice's histogram, and it can differ slightly from the threshold the full run computes from the whole volume. The local threshold depends only on each voxel's neighbourhood, but a neighbourhood taken within one slice still differs from one taken in the volume.

Reading the result

  • Porosity follows the threshold. Every voxel near \(t\) is a judgement call, so a small change in \(t\) moves the porosity of a scan with a broad, overlapping histogram more than one with two well-separated peaks. Check the histogram before trusting a porosity to more than a couple of digits.
  • Otsu and Li can disagree. Otsu balances the two classes' variances and Li their information content; on a histogram with a small pore peak they can place \(t\) noticeably apart. Pick one method for a study.
  • Partial-volume voxels. A voxel straddling a pore wall has a grey level between the two phases, so thin throats and fine pores are under- or over-counted depending on where \(t\) sits. Resolution matters more than the method here.

References


  1. N. Otsu, "A threshold selection method from gray-level histograms," IEEE Transactions on Systems, Man, and Cybernetics 9 (1979) 62–66. doi:10.1109/TSMC.1979.4310076 ↩

  2. C. H. Li, C. K. Lee, "Minimum cross entropy thresholding," Pattern Recognition 26 (1993) 617–625. doi:10.1016/0031-3203(93)90115-D ↩