Search Center Predictions
dictk.grid.locate's search_centers
parameter defaults to None, which means each point's own
reference_points entry doubles as its search center — a "zero
displacement" guess. Every worked example in this book relies on that
default. It works well here because every displacement used so far is
small relative to the search margin chosen to contain it.
Recoverable Displacement Range
establishes that the searchable range is bounded by search_margin
itself now, not by kernel_margin. That's good news — it's a real,
symmetric bound to design around — but it doesn't remove the underlying
tension: a bigger unknown displacement still needs a bigger
search_margin to contain it, and a bigger search_margin costs more
compute (a larger FFT, at every point). The zero-displacement guess is
the worst case for this: it forces search_margin to cover the entire
possible displacement, with no help from anything already known about
how the specimen is actually deforming.
A Better Guess
If some estimate of the deformation already exists — a coarse global DIC
pass, a prior loading step in a finite element analysis, or just a
reasonable assumption about how the specimen is expected to move — that
estimate can predict roughly where each point ended up, instead of
guessing zero displacement. A smaller search_margin then suffices,
since it only needs to cover how wrong that prediction might be, not
the full displacement itself.
The natural way to express such an estimate is a deformation gradient, the same Continuum Mechanics already defines — extended here to an affine map in homogeneous coordinates, so a single matrix carries both the linear part (stretch, rotation, shear) and a translation:
where is a point's reference position (in homogeneous form) and is its predicted current position — the search center to use, not the answer itself. This is not quite Continuum Mechanics' own : that one is purely linear (no translation, in 2D); this extends it to specifically so one matrix can express a rigid translation too, the same kind of motion Multi-Point Motion tracks.
The default should be — the identity:
Because , an identity
predicts zero displacement — exactly today's existing
default (search_centers=None ⟹ each point's own reference position).
Introducing this way changes nothing for every example
already in this book; it only adds a way to do better when a better
guess is available.
Not Implemented Yet
This is a real API change, not a small one, and it touches design questions this page doesn't resolve on its own:
- Where does apply —
grid.locateonly (a natural fit, since it already computes asearch_centerslist per call), or doestranslation.locate's single-point API need an equivalent? - If a caller supplies both
Fandsearch_centersexplicitly, which wins, or is that combination an error? - Applying an affine to a
PixelCoordinateis itself a small, independently testable piece — likely a new function indictk.image, alongsidetranslate/stretch, beforegrid.locateever calls it. - A worked example needs a source for that isn't
circular (an estimate close enough to be useful, but not so close it
trivializes what
locateis finding). Where that estimate comes from in practice is its own open question.
None of this is scoped or scheduled — this page records that the
direction exists and sketches its math, not a commitment to build it on
any timeline. Build it in pieces, each with its own tests, rather than
landing the whole API change at once: the small affine-transform helper
first, then wiring it into grid.locate behind the identity default,
then a worked example once both exist. See Path
Forward for the related "dynamic
search-window sizing" direction this connects to — a better
-based guess and a smaller search_margin are two sides
of the same idea.
Twelve points, twelve independent correlations, each one still sequential so far: Parallelization picks up from here.