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 orangle(...)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}} \]
-
enumerator NONE#
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 + doubleproducesdouble,complex<float> + complex<double>producescomplex<double>, andcomplex<float> + doublealso producescomplex<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);