Skip to content

fix Overlap to require expandOverlap parameter (TODO: remove all old … - #106

Open
StephanPreibisch wants to merge 4 commits into
masterfrom
fixTPS2
Open

fix Overlap to require expandOverlap parameter (TODO: remove all old …#106
StephanPreibisch wants to merge 4 commits into
masterfrom
fixTPS2

Conversation

@StephanPreibisch

Copy link
Copy Markdown
Contributor

…fusion code in the transformed package - unrelated)

more importantly, fixing issues reported in #104 in a different way, but providing a guess to the inverse TPS. For this we made a compound transformation model that first applies the guess, and then runs the InverseRealTransformGradientDescent, which takes a guess in inverseTol() provided by the source[] in apply().

StephanPreibisch and others added 4 commits September 3, 2026 10:51
…fusion code in the transformed package - unrelated)

more importantly, fixing issues reported in #104 in a different way, but providing a guess to the inverse TPS. For this we made a compound transformation model that first applies the guess, and then runs the InverseRealTransformGradientDescent, which takes a guess in inverseTol() provided by the source[] in apply().
…ting view bounding boxes

imglib2's InverseRealTransformGradientDescent.apply(s, t) calls inverseTol(s, s, ...),
i.e. it seeds the descent with the query point itself. For a tile whose render position
is tens of thousands of pixels from its local pixel coordinates, and with only a few
landmarks, the descent never reaches the true preimage and the resulting bounding box
silently drops the view from every block it should contribute to.

GuessingRealTransform now calls inverseTol(p, invGuess(p), ...) directly for every
corner, using the per-view approximate affine (image -> render) as the seed. Composing
the guess with WrappedIterativeInvertibleRealTransform.inverse() cannot work: that ends
in inverseTol(guess, guess, ...) and inverts a different point. A corner is trusted only
if the descent converged and stayed within max(dimensions) of the guess; otherwise the
guess is used and reported.

init() now passes the approximate affine itself (not its inverse) as the guess.
fitAffineTransform throws instead of silently returning an identity when the landmarks
are ill-defined (e.g. co-planar).

Adds InverseTransformedBoundingBoxTest: exact ground truth with dense landmarks, sparse
split-center landmarks where the un-seeded inverse is ~94,000 px off, and aliasing /
copy() behaviour of GuessingRealTransform.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ate affine and bounding box

The local init() and the BigStitcher-Spark displacement-field cache both need the same
three things per underlying view: the TPS (render -> image), the affine approximating its
inverse (image -> render) and the back-projected bounding box seeded with that affine.
Having each caller assemble them by hand is how the transform directions got mixed up.
TpsSetup / setupTps() now does it once; init() uses it and reuses the TPS instance for
displacement-field sampling instead of solving it a second time.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
IntervalSamplingMethod.CORNERS ) );

if ( invTransform.numFallbacks() > 0 )
IOFunctions.println( "[TPS] inverseTransformedBoundingBox: " + invTransform.numFallbacks() + " of "

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an FYI: IOFunctions.println breaks on headless spark (I might use System.out.println instead)

@indecisiveuser

Copy link
Copy Markdown
Collaborator

Looks good to me! Byte identical to #104 on my real-data test.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants