skills/cv/anisotropic-spacing-trilinear-resample/SKILL.md
Resample a 3D medical volume to a fixed network input shape using physical voxel spacing (dz, dy, dx), correcting the Z dimension by the dz/dy ratio so anisotropic CT scans (1mm in-plane, 5mm slice) end up anatomically isotropic before trilinear interpolation
npx skillsauth add wenmin-wu/ds-skills cv-anisotropic-spacing-trilinear-resampleInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
CT volumes are routinely anisotropic: 0.7mm in-plane and 5mm between slices is normal. If you F.interpolate a (60, 512, 512) volume directly to (96, 256, 256), you stretch the Z axis 1.6x in voxel space but the physical distance per slice is already 7x the in-plane spacing — the resulting volume looks correct in tensor shape but is geometrically wrong, and the network learns the wrong aspect ratio. The fix is to first scale the slice count by dz / dy (the spacing ratio), then resample to the target shape. This delivers an anatomically isotropic input regardless of the source acquisition.
import torch
import torch.nn.functional as F
def resample_to_shape(image, spacing, target_hw=256, target_d=96):
dz, dy, dx = spacing # physical mm/voxel
d, h, w = image.shape
# 1. Correct Z count by physical-spacing ratio (anisotropy fix)
d_iso = int(dz / dy * d * 0.5) # 0.5 = empirically tuned compression
# 2. Scale all axes to in-plane target
scale = target_hw / h
d_out = int(scale * d_iso)
h_out = w_out = int(scale * h)
# 3. Final resample to fixed network input shape
image = F.interpolate(image[None, None],
size=(d_out, h_out, w_out),
mode='trilinear',
align_corners=False)[0, 0]
image = F.interpolate(image[None, None],
size=(target_d, target_hw, target_hw),
mode='trilinear',
align_corners=False)[0, 0]
return image
PixelSpacing (dy, dx) and SliceThickness (or SpacingBetweenSlices) → dz from the DICOM headersd_iso = int(dz / dy * d * factor)* 0.5 factor: pure dz/dy over-corrects in practice — a damping factor between 0.4 and 0.6 is empirically best for abdominal CT.interpolate calls into one introduces aliasing for high anisotropy ratios.align_corners=False: the PyTorch default for new code; matches OpenCV/numpy convention.dz: fall back to SpacingBetweenSlices if SliceThickness is absent; some scanners populate only one.data-ai
Scaled Pinball Loss (SPL) metric for evaluating quantile forecasts, normalized by mean absolute successive differences of training data
data-ai
Walk backward through a time series and multiplicatively rescale segments when jumps exceed a fraction of the running mean to correct data collection anomalies
testing
Transform forecasting target to next/current ratio minus one so that optimizing MAE or squared error implicitly minimizes SMAPE
tools
Convert point forecasts to prediction intervals by scaling with logit-transformed quantile ratios passed through a Normal CDF