corrmap#

Per-element windowed correlation map between two operators of identical shape. Unlike corr, which produces a single function-of-lag output, corrmap produces an output of the same shape as the input, where each output element is a normalized correlation computed over a small window of samples around the corresponding input element.

Supports a 1-D window over the last input dimension (signal-processing form) and a 2-D window over the last two input dimensions (image-processing form). All other dimensions are treated as independent batches. The window is cropped at the input boundary: out-of-bounds offsets are skipped and the normalization uses only the in-bounds samples (means and energies are computed over the cropped window, not over a zero-padded one).

Typical applications:

  • SAR / InSAR coherence and interferogram phase (complex inputs, MAGNITUDE normalization)

  • Stereo matching disparity cost (real inputs, ZNCC normalization)

  • Template matching, optical flow, change detection (ZNCC normalization)

Added in version 1.0.0.

template<CorrMapNormalize Mode = CorrMapNormalize::MAGNITUDE, typename OpA, typename OpB>
__MATX_INLINE__ auto matx::corrmap(const OpA &A, const OpB &B, index_t window)#

Per-sample 1-D windowed correlation map.

Slides a 1-D window of length \( w \) along the last input dimension; all other dimensions are treated as independent batches. Input and output have the same shape.

For an output sample at index \( n \) along the windowed dimension, let \( W \) denote the set of in-bounds window offsets

\[ W = \bigl\{\, k \in \mathbb{Z} \;:\; -\lfloor w/2 \rfloor \le k \le w - 1 - \lfloor w/2 \rfloor, \ \text{and } n + k \text{ is in-bounds}\bigr\}. \]
This is the floor-center indexing convention. For odd \( w \) the window is exactly centered on \( n \); for even \( w \) it is asymmetric by half a sample. The window is cropped at the input boundary: out-of-bounds offsets are skipped and the normalization uses only the in-bounds samples (means and energies are computed over the cropped window, not over a zero-padded one).

For the selected normalization mode the operator computes

\[ y_n = f_{\text{Mode}}\!\left( \{a_k : k \in W\},\ \{b_k : k \in W\}\right), \qquad a_k = A(\ldots, n + k),\ b_k = B(\ldots, n + k), \]

where the function \( f_{\text{Mode}} \) is given in CorrMapNormalize.

Output element type:

  • complex if either input is complex

  • real otherwise

  • precision is the greater of the inputs (e.g. float + double -> double, complex<float> + complex<double> -> complex<double>, complex<float> + double -> complex<double>)

Template Parameters:
  • Mode – Normalization mode (compile-time). Defaults to CorrMapNormalize::MAGNITUDE.

  • OpA – Type of input operator A

  • OpB – Type of input operator B

Parameters:
  • A – Input operator A

  • B – Input operator B (same shape as A)

  • window – Window length \( w \ge 1 \)

Returns:

corrmap operator producing a tensor with the same shape as A

template<CorrMapNormalize Mode = CorrMapNormalize::MAGNITUDE, typename OpA, typename OpB>
__MATX_INLINE__ auto matx::corrmap(const OpA &A, const OpB &B, const cuda::std::array<index_t, 2> &window)#

Per-pixel 2-D windowed correlation map.

Slides a 2-D window of shape \( w_r \times w_c \) over the last two input dimensions; all other dimensions are treated as independent batches. Input and output have the same shape.

For an output pixel at row \( r \), column \( c \), let \( W \) denote the set of in-bounds window offsets

\[ W = \bigl\{\, (i, j) \in \mathbb{Z}^2 \;:\; -\lfloor w_r/2 \rfloor \le i \le w_r - 1 - \lfloor w_r/2 \rfloor,\ -\lfloor w_c/2 \rfloor \le j \le w_c - 1 - \lfloor w_c/2 \rfloor,\ \ \text{and } (r + i, c + j) \text{ is in-bounds}\bigr\}. \]
This is the floor-center indexing convention. For odd window sizes the window is exactly centered on \( (r, c) \); for even sizes it is asymmetric by half a pixel, which introduces a half-pixel registration offset relative to the output grid. The window is cropped at the input boundary: out-of-bounds offsets are skipped and the normalization uses only the in-bounds samples (means and energies are computed over the cropped window, not over a zero-padded one).

For the selected normalization mode the operator computes

\[ y_{r,c} = f_{\text{Mode}}\!\left( \{a_{i,j} : (i,j) \in W\},\ \{b_{i,j} : (i,j) \in W\}\right), \quad a_{i,j} = A(\ldots, r + i,\ c + j),\ b_{i,j} = B(\ldots, r + i,\ c + j), \]

where the function \( f_{\text{Mode}} \) is given in CorrMapNormalize. With complex inputs and the MAGNITUDE mode the result is the complex interferometric coherence: take abs(...) for the coherence magnitude or angle(...) for the interferogram phase.

Output element type:

  • complex if either input is complex

  • real otherwise

  • precision is the greater of the inputs (e.g. float + double -> double, complex<float> + complex<double> -> complex<double>, complex<float> + double -> complex<double>)

Template Parameters:
  • Mode – Normalization mode (compile-time). Defaults to CorrMapNormalize::MAGNITUDE (interferometric coherence for complex inputs).

  • OpA – Type of input operator A

  • OpB – Type of input operator B

Parameters:
  • A – Input operator A

  • B – Input operator B (same shape as A)

  • window – Window dimensions {rows, cols}, each \( \ge 1 \)

Returns:

corrmap operator producing a tensor with the same shape as A

Normalization modes#

The compile-time template parameter Mode selects how each window’s samples are combined. The full mathematical definition of each mode is given in its CorrMapNormalize enum value.

enum class matx::CorrMapNormalize#

Normalization mode for the windowed correlation map.

Given two inputs \( A, B \) of identical shape, for each output element the operator iterates over a small window \( W \) around that element and combines the samples according to the selected mode.

In the per-value equations below, \( a_k, b_k \) are the input samples at the window offsets \( k \in W \), the conjugate is \( \overline{\cdot} \) (the identity for real inputs), and \( N = |W| \) is the number of in-bounds samples in the window.

For the MAGNITUDE and ZNCC modes the listed result ranges are the mathematical bounds. The operator does not clamp, so floating-point arithmetic may produce values slightly outside the bounds in degenerate windows.

Values:

enumerator NONE#

Raw windowed inner product. Result is unbounded, other than the data type limits.

\[ y = \sum_{k \in W} a_k \, \overline{b_k} \]

enumerator MAGNITUDE#

Energy-normalized cross-correlation: divide by the geometric mean of the two windowed energies.

For complex inputs the result is complex with magnitude in \( [0, 1] \): \( |y| \) is the SAR/InSAR coherence magnitude and \( \angle y \) is the interferogram phase. For real inputs the result lies in \( [-1, 1] \).

\[ y = \frac{\displaystyle \sum_{k \in W} a_k \, \overline{b_k}} {\sqrt{\displaystyle \sum_{k \in W} |a_k|^2 \; \sum_{k \in W} |b_k|^2}} \]

enumerator ZNCC#

Zero-mean normalized cross-correlation: subtract the window-local means before normalizing.

This is the classic NCC used in image processing, pattern matching, and is equivalent to the Pearson correlation coefficient. Let \( \mu_a = \tfrac{1}{N}\sum_{k \in W} a_k \) and \( \mu_b = \tfrac{1}{N}\sum_{k \in W} b_k \) be the window-local means. Result is in \( [-1, 1] \) for real inputs; complex with magnitude \( \le 1 \) for complex inputs.

\[ y = \frac{\displaystyle \sum_{k \in W} (a_k - \mu_a)\, \overline{(b_k - \mu_b)}} {\sqrt{\displaystyle \sum_{k \in W} |a_k - \mu_a|^2 \; \sum_{k \in W} |b_k - \mu_b|^2}} \]

Input type requirements#

Inputs must be floating-point or complex floating-point. Supported inner scalar types are float, double, matx::matxFp16 / matx::matxBf16 (and the underlying __half / __nv_bfloat16), and their complex counterparts.

Integer and complex-integer inputs are rejected at compile time by a static_assert. This applies to every mode, including matx::CorrMapNormalize::NONE: although the NONE-mode product \(A \cdot \bar B\) is mathematically well-defined for integer operands, the normalized modes (MAGNITUDE / ZNCC) require a final division that would silently truncate to zero for integer arithmetic, so all integer inputs are rejected uniformly to avoid a surprising mode-dependent failure mode. Cast integer inputs explicitly before calling, e.g. corrmap(as_float(A), as_float(B), w).

Output element type#

  • Complex if either input is complex.

  • Real otherwise.

  • Precision is the greater of the inputs: e.g. float + double produces double, complex<float> + complex<double> produces complex<double>, and complex<float> + double also produces complex<double>.

Window indexing#

The window uses the floor-center convention: for a window of length \(w\) centered at index \(n\), the offsets span \([-\lfloor w/2 \rfloor,\ w - 1 - \lfloor w/2 \rfloor]\). Odd window sizes are exactly centered; even window sizes introduce a half-element registration offset.

Examples#

2-D MAGNITUDE on complex inputs (SAR/InSAR coherence):

// 2-D windowed coherence between two complex images (here A==A for the
// self-coherence sanity check). |Y(r,c)| is the SAR/InSAR coherence map.
(Y = corrmap<CorrMapNormalize::MAGNITUDE>(
      A, A, cuda::std::array<index_t, 2>{win, win})).run(exec);

2-D ZNCC on real inputs (classic normalized cross-correlation):

// Per-pixel ZNCC (mean-subtracted normalized cross-correlation): classic
// NCC for image processing, pattern matching, etc. Real result in [-1, 1].
(Y = corrmap<CorrMapNormalize::ZNCC>(
      A, B, cuda::std::array<index_t, 2>{win, win})).run(exec);

1-D MAGNITUDE on a batched real signal:

// 1-D sliding-window correlation on a batch of length-N signals. The
// scalar window argument selects the 1-D overload; the leading dim is
// batched independently.
(Y = corrmap<CorrMapNormalize::MAGNITUDE>(A, B, win)).run(exec);