Skip to content

BUG: Fix InverseDisplacementFieldImageFilter subsampling geometry#6588

Open
hjmjohnson wants to merge 3 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:bug-inverse-displacement-field-geometry
Open

BUG: Fix InverseDisplacementFieldImageFilter subsampling geometry#6588
hjmjohnson wants to merge 3 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:bug-inverse-displacement-field-geometry

Conversation

@hjmjohnson

Copy link
Copy Markdown
Member

Fixes the two geometry gaps tracked in #6582 (follow-up to #6577): the thin-plate-spline landmark lattice is now centered under subsampling, and the filter gains a SetOutputDirection API (output still inherits the input direction unless explicitly set).

Lattice centering (BUG commit)

PrepareKernelBaseSpline() scaled the sampling spacing by the subsampling factor k but kept the input origin, so landmarks sat on fine indices 0, k, … — zero low-side margin and up to k−1 unsampled voxels on the high side per axis, forcing the spline to extrapolate near the high edge. The lattice now starts at fine index (k−1)/2: margins balanced, landmarks still exactly on voxel centers (values uninterpolated). Measured on the quadratic-field regression test (N=32, k=4): worst-case round-trip error 0.069 → 0.047 voxels; the test threshold (0.06) fails the old code and passes the new with margin.

Output direction API (ENH commit)

The filter exposed SetSize/SetOutputSpacing/SetOutputOrigin but the output always inherited the input direction cosines, so the inverse of a rotated field could not be requested on an axis-aligned grid. Adds m_OutputDirection honored in GenerateOutputInformation(); unless SetOutputDirection() is called, the output inherits the input direction — existing behavior preserved (no default change). Three new GTests: default inheritance, explicit direction with analytic-inverse verification, and the calibrated lattice-centering bound.

Original algorithm by Luis Ibanez (2004); direction-handling groundwork by @physwkim in #6577.

@github-actions github-actions Bot added type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Filtering Issues affecting the Filtering module labels Jul 11, 2026
@hjmjohnson hjmjohnson self-assigned this Jul 11, 2026
@hjmjohnson hjmjohnson marked this pull request as ready for review July 11, 2026 20:47
@greptile-apps

greptile-apps Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes inverse displacement field geometry under subsampling. The main changes are:

  • Centers the subsampled landmark lattice within the input region.
  • Accounts for non-zero input region starts when building landmarks.
  • Adds an explicit output direction API.
  • Adds tests for rotated grids, invalid subsampling, centered lattices, and cropped regions.

Confidence Score: 5/5

This looks safe to merge.

No blocking issues found in the changed code.

T-Rex T-Rex Logs

What T-Rex did

  • An attempt was made to configure the focused inverse-displacement-field GTest target using the specified cmake command.
  • The configure step failed with exit code 127 because cmake was not installed in the sandbox.
  • As a result, the focused GTest target could not be built or run in this sandbox.
  • The log artifact documents the availability checks and test-registration grep around the targeted tests and the attempted configure.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
Modules/Filtering/DisplacementField/include/itkInverseDisplacementFieldImageFilter.h Adds output direction support and validation override declarations.
Modules/Filtering/DisplacementField/include/itkInverseDisplacementFieldImageFilter.hxx Centers the landmark lattice from the input region start and applies explicit output direction when requested.
Modules/Filtering/DisplacementField/test/itkInverseDisplacementFieldImageFilterGTest.cxx Adds tests for output direction behavior, centered subsampling, invalid subsampling, and non-zero-start regions.

Reviews (2): Last reviewed commit: "ENH: Reject inputs too small for the lan..." | Re-trigger Greptile

PrepareKernelBaseSpline() scaled the sampling spacing by the
subsampling factor k but kept the input origin, placing landmarks on
fine indices 0, k, ..., with no low-side margin and up to k-1 unsampled
voxels on the high side of every axis. The thin-plate spline had to
extrapolate near the high edge, degrading the inverse asymmetrically.

Start the lattice at fine index (k-1)/2 instead: margins are balanced
while landmarks remain exactly on voxel centers, so sampled values stay
uninterpolated. For the quadratic-field regression test (N=32, k=4) the
worst-case round-trip error drops from 0.069 to 0.047 voxels.

Follow-up to the subsampler direction fix from InsightSoftwareConsortium#6577; issue InsightSoftwareConsortium#6582.
The filter exposed SetSize, SetOutputSpacing and SetOutputOrigin, but
the output direction could not be controlled: it always inherited the
input direction cosines, so the inverse of a rotated field could not be
requested on an axis-aligned grid.

Add an OutputDirection member honored in GenerateOutputInformation().
Unless explicitly set, the output inherits the input direction,
preserving existing behavior.

Issue InsightSoftwareConsortium#6582.
An input smaller than SubsamplingFactor along any axis produces a
zero-size landmark lattice and the kernel spline receives no landmarks;
a zero factor divides by zero. Verify both before the pipeline runs.

Issue InsightSoftwareConsortium#6582.
@hjmjohnson hjmjohnson force-pushed the bug-inverse-displacement-field-geometry branch from cca3a67 to 326899b Compare July 11, 2026 21:48
@hjmjohnson

Copy link
Copy Markdown
Member Author

@greptileai review — addressed the P1 (non-zero-start region shift) in the latest push; the centered lattice now starts relative to the region index on a zero-based grid, with a new regression test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Filtering Issues affecting the Filtering module type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant