Skip to content

Resizing

Downsample and Resize make a copy of an image at a different resolution. Downsample samples the grid; Resize filters, interpolates and, for a binary image, restores the porosity. Neither adds information: a coarser copy loses detail, and a finer one adds grid points, not real features.

  • Method strided sampling (Downsample); Gaussian anti-aliasing, linear interpolation and porosity-preserving re-binarisation (Resize)
  • Backend PoreStore's own resampling, with SciPy for the filter and interpolation, on CPU
  • Changes the number of voxels along each axis and the voxel size; values (Downsample) or intensities and porosity-matched phases (Resize)
  • How to run it Downsample and Resize in the User guide

Whether an image is resized as binary follows from its values: a segmented image, with 0 as solid and one other value as pore, is resized as binary and comes back as a boolean image. Any other image is treated as greyscale.

Downsample

Keeps every \(n\)th voxel along each axis, \(n \in \{2, 3, 4\}\) (Use every Nth voxel), starting from the first. Each side of \(N\) voxels becomes \(\lceil N/n \rceil\), and the voxel size becomes \(n h\).

Aspect Setting
Sampling Voxels \(0, n, 2n, \dots\) along each axis; no averaging or filtering
Values Kept exactly, with the same data type, binary or greyscale
Voxel size \(n h\)
Porosity Not controlled: the sampled voxels' porosity, which drifts from the source's

Because nothing is averaged, any feature thinner than \(n\) voxels can vanish or break into pieces, and the sampled grid aliases fine periodic structure. Downsampling is exact and fast, which makes it useful for a quick look or for trying settings on a coarse copy.

Resize

Interpolates to any Zoom factor \(\zeta > 0\): below 1 shrinks, above 1 enlarges. With SciPy:1

  1. Anti-aliasing. When shrinking (\(\zeta < 1\)), the image is low-pass filtered with a Gaussian of standard deviation \(\sigma = (1/\zeta - 1)/2\) source voxels, truncated at \(4\sigma\), so detail finer than the new grid can't alias into it.
  2. Interpolation. Linear interpolation onto the new grid, with voxel centres aligned and mirrored boundaries. Each side of \(N\) voxels becomes \(\lfloor N\zeta + \tfrac12 \rfloor\), and the voxel size becomes \(h/\zeta\). Interpolated values are clipped to the source's range.
  3. Re-binarisation, for a binary source. The voxels with the highest interpolated values become pore, exactly as many as keep the source's porosity, rounded to the nearest whole voxel. Ties are broken by array order. The porosity error is therefore at most half a voxel's worth.

A greyscale source keeps its interpolated intensities, as a floating-point image, without re-binarisation: segment the result afterwards.

Aspect Setting
Filter Gaussian, \(\sigma = (1/\zeta - 1)/2\) source voxels, when \(\zeta < 1\)
Interpolation Linear (order 1), cell-centred, mirrored at the boundary
Binary output Re-binarised by rank to the source porosity
Greyscale output Floating-point intensities, clipped to the source range
Voxel size \(h/\zeta\)
A 100³ synthetic sample reduced four times along each side with each method, through PoreStore's own code. Downsampling keeps every fourth voxel, so porosity can drift and thin solid breaks into fragments. Resizing filters and interpolates first and keeps porosity by rank. The subtitles give each result's porosity and its number of separate solid clusters: neither method guarantees the source's connectivity.

What resizing preserves

Property Downsample Resize, binary
Porosity No, it drifts Yes, to half a voxel
Connectivity No No
Surface area No No
Transport properties No No

A resized image is a different image. Resizing to bring a large sample within reach of a solver is often worth it, but check the effect: run a key analysis on the original and the copy over a region small enough for both, and compare.

Resolution and transport. Transport solvers need several voxels across a throat to resolve flow accurately. Shrinking an image can push throats below that, and permeability is usually the first result to suffer; enlarging gives the solver more voxels per throat but can't recover a throat's true shape from a coarse scan.

References


  1. P. Virtanen et al., "SciPy 1.0: fundamental algorithms for scientific computing in Python," Nature Methods 17 (2020) 261–272. doi:10.1038/s41592-019-0686-2 ↩