API

RegisterCoreModule

Core types and utilities for image registration mismatch computations.

Types

  • NumDenom: a packed (numerator, denominator) pair; supports vector-space arithmetic for use with Interpolations.jl
  • MismatchArray: a CenterIndexedArray of NumDenom elements representing mismatch over a range of shifts
  • PreprocessSNF: shot-noise–filtering image preprocessor (bias subtract, square-root transform, band-pass filter)
  • ColonFun: callable singleton returning Colon(), for type-stable slicing

Functions

  • separate: unpack a NumDenom or MismatchArray into (num, denom) arrays
  • ratio: convert NumDenom to a scalar ratio, with threshold masking
  • maxshift: return the maximum-shift half-size of a MismatchArray
  • mismatcharrays: pack array-of-arrays pairs into an array of MismatchArrays
  • argmin_mismatch: find the shift index of the minimum mismatch
  • highpass / highpass!: high-pass filter an image (Gaussian-based, NaN-safe)
  • paddedview / trimmedview: extend/trim a SubArray to/from its parent
source

Types

RegisterCore.NumDenomType
x = NumDenom(num, denom)

A packed (num, denom) pair with element type T. Access fields as x.num and x.denom. Arguments of type Gray are automatically unwrapped; mismatched numeric types are promoted.

NumDenom objects act as 2-vectors under arithmetic — addition and scalar multiplication operate component-wise on both fields:

nd1 + nd2  →  NumDenom(nd1.num + nd2.num, nd1.denom + nd2.denom)
nd1 - nd2  →  NumDenom(nd1.num - nd2.num, nd1.denom - nd2.denom)
c * nd     →  NumDenom(c*nd.num, c*nd.denom)
nd / c     →  NumDenom(nd.num/c, nd.denom/c)

This vector-space algebra (rather than ratio algebra) is intentional: it allows Interpolations.jl to interpolate numerator and denominator jointly without recomputing interpolation weights, enabling efficient aperture-windowed mismatch computations.

As a consequence, convert(Float64, ::NumDenom) is deliberately not defined, because the component-wise arithmetic breaks the ratio interpretation. Use ratio to convert to a scalar ratio.

source
RegisterCore.MismatchArrayType
MismatchArray{ND,N,A}

A CenterIndexedArray whose elements are NumDenom pairs, representing packed numerator/denominator mismatch data over a range of shifts.

The axes are centered at zero, so axes(D, k) runs from -maxshift(D)[k] to +maxshift(D)[k]; an index value of (i, j, ...) corresponds to a shift of (i, j, ...) pixels.

D = MismatchArray(num::AbstractArray, denom::AbstractArray)

Pack same-size arrays num and denom into a MismatchArray with centered axes of half-size size(num) .÷ 2. Element type is NumDenom{promote_type(eltype(num), eltype(denom))}.

D = MismatchArray(T, dims::Dims)
D = MismatchArray(T, dims::Integer...)

Allocate an uninitialized MismatchArray with element type NumDenom{T} and the given dimensions. Useful for pre-allocating output before filling with copyto!.

source
RegisterCore.ColonFunType
ColonFun()(i::Int) -> Colon()

A callable singleton that returns Colon() for any integer argument. Used in place of Colon() directly where type-stable, composable slicing is needed (e.g., constructing index tuples programmatically).

source
RegisterCore.PreprocessSNFType
pp = PreprocessSNF(bias, sigmalp, sigmahp)

Construct a shot-noise–filtered preprocessor. Call it as pp(img) to preprocess an image. All arguments are stored as Float32 (or Vector{Float32}), so Float64 inputs are silently converted.

The "SNF" name stands for "shot-noise filtered": this preprocessor is designed for photon-counting (Poisson) data, where the variance equals the mean.

Processing steps:

  1. Subtract bias and clamp to zero: A′ = max(0, img - bias)
  2. Square-root transform to stabilize variance: A″ = √A′
  3. High-pass filter with Gaussian width sigmahp (subtracts a low-pass Gaussian)
  4. Low-pass filter with Gaussian width sigmalp

sigmalp and sigmahp must each be a vector of length ndims(img). Pass sigmalp = zeros(ndims(img)) to skip low-pass filtering; pass sigmahp = fill(Inf, ndims(img)) to skip high-pass filtering.

When called on a SubArray, pp extends the view to the full parent (via paddedview) before processing, then trims the result back to the original index range (via trimmedview). This preserves any padding context around the sub-region.

If ImageMetadata is loaded, pp also accepts ImageMeta arrays and propagates image properties to the output.

source

MismatchArray functions

RegisterCore.argmin_mismatchFunction
index = argmin_mismatch(numdenom::MismatchArray, thresh::Real)
index = argmin_mismatch(r::CenterIndexedArray{<:Number})

Return the CartesianIndex of the minimum mismatch, excluding edge points.

The first form operates on a MismatchArray: it computes num/denom at each interior point and finds the minimum among points where denom > thresh. The second form operates on a pre-computed ratio array r of plain numbers and finds the interior minimum unconditionally.

"Edge points" are the outermost index value on each side of every dimension; they are always excluded from consideration.

If no valid point is found (e.g., all denom ≤ thresh), returns a zero CartesianIndex — check for this case before using the result as an array index.

source
RegisterCore.maxshiftFunction
mxs = maxshift(D::MismatchArray)

Return the half-size of the MismatchArray D as a tuple of integers — i.e., the maximum shift (in pixels, per dimension) that was searched when computing the mismatch. Equivalent to D.halfsize.

source
RegisterCore.mismatcharraysFunction
mms = mismatcharrays(nums, denom::AbstractArray{<:Number})
mms = mismatcharrays(nums, denoms::AbstractArray{<:AbstractArray})

Pack array-of-arrays (num, denom) pairs into an Array{MismatchArray}.

The first form uses the same denom array for every entry in nums. The second form pairs each nums[i] with the corresponding denoms[i]; nums and denoms must have the same size.

Returns an Array{MismatchArray} with the same shape as nums.

source
RegisterCore.ratioFunction
r = ratio(nd::NumDenom, thresh; fillval=NaN)
r = ratio(r::Real, thresh; fillval=NaN)

Return the ratio nd.num/nd.denom, or fillval (converted to the ratio type) when nd.denom < thresh. Setting thresh = 0 always returns the ratio.

The second form accepts a plain Real and returns it unchanged, regardless of thresh and fillvalthresh and fillval are silently ignored. This allows callers to handle both NumDenom and pre-computed ratio arrays uniformly without branching on the element type.

source
RegisterCore.separateFunction
num, denom = separate(data::AbstractArray{NumDenom{T}})
num, denom = separate(mm::MismatchArray)
nums, denoms = separate(mma::AbstractArray{<:MismatchArray})

Split packed NumDenom data into separate numerator and denominator arrays.

  • For a plain AbstractArray{NumDenom{T}}, returns a pair of Array{T} with the same size and linear indexing as data.
  • For a MismatchArray, returns a pair of CenterIndexedArray{T}, preserving the centered axes (so index ranges correspond to shift values).
  • For an array of MismatchArrays, returns a pair of Array{CenterIndexedArray{T}}.
source

Utility functions

RegisterCore.highpassFunction
datahp = highpass([T], data, sigma)
highpass!(out, data, sigma)
highpass!(data, sigma)

Return (or write in-place) a high-pass–filtered version of data with negative values clamped to zero. The high-pass is computed by subtracting a Gaussian-smoothed copy of data (via ImageFiltering.jl), which gracefully handles NaN values.

sigma must be an iterable (e.g., a tuple or vector) with one width per dimension of data. To skip filtering along a particular axis, set the corresponding entry to Inf (the input is then returned as-is, converted to Array{T}, with no subtraction or clamping applied).

For highpass, the optional first argument T sets the element type of the output:

  • highpass(T, data, sigma) — allocates an output of element type T
  • highpass(data, sigma)T defaults to eltype(data) for AbstractFloat inputs, or Float32 for Integer/FixedPoint inputs

For highpass!, the output element type is eltype(out):

  • highpass!(out, data, sigma) — writes result into out; out and data may be distinct arrays (useful for pre-allocated buffers in hot loops)
  • highpass!(data, sigma) — filters data in-place

See also PreprocessSNF for a combined shot-noise–filtering preprocessor.

source
RegisterCore.paddedviewFunction
Apad = paddedview(A::SubArray)

Return a SubArray of A's parent that extends to the full parent size along every dimension of A that was indexed by a UnitRange. Dimensions indexed by a scalar are still dropped (as usual for SubArray), and dimensions indexed by a Slice are unchanged.

Only Slice, Real, and UnitRange index types are supported; any other index type throws an error.

See also trimmedview.

source
RegisterCore.trimmedviewFunction
B = trimmedview(Bpad::AbstractArray, A::SubArray)

Return a view B of Bpad with axes(B) == axes(A).

Bpad must be an AbstractArray with the same size as paddedview(A) — typically it is the result of an operation applied to paddedview(A). Dimensions of A that were indexed by a scalar are skipped (they are dropped in A); all other dimensions are sliced with the original index range from A.

See also paddedview.

source