Skip to content

Commit d3fe942

Browse files
authored
Add corrmap operator for windowed correlation maps (#1194)
* Add corrmap operator for windowed correlation maps Add the corrmap() operator, which computes 1D or 2D correlation maps. corrmap produces a per-sample or per-pixel measure of correlation between two signals or images (or, generically, tensors) over a small window local to each output sample. The output is the same size as the input. The 1D and 2D corrmap operators are differentiated by the rank of the window lengths provided to the operator. 2D correlation maps are common in SAR. For that use case, use the MAGNITUDE normalization type and take the abs() of the output to get the real-valued correlation values in the range [0, 1]. See the MatX documentation for full details of the corrmap() operator and normalization modes. Signed-off-by: Thomas Benson <tbenson@nvidia.com> * Update JIT generation to pass CorrMapNormalize enum values Signed-off-by: Thomas Benson <tbenson@nvidia.com> * Add corrmap window to JIT path as constexpr array Also use auto instead of decltype(auto) for corrmap as it returns value and does not need to handle reference returns. Signed-off-by: Thomas Benson <tbenson@nvidia.com> --------- Signed-off-by: Thomas Benson <tbenson@nvidia.com>
1 parent a098e99 commit d3fe942

7 files changed

Lines changed: 1620 additions & 0 deletions

File tree

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
.. _corrmap_func:
2+
3+
corrmap
4+
#######
5+
6+
Per-element windowed correlation map between two operators of identical
7+
shape. Unlike :ref:`corr_func`, which produces a single function-of-lag
8+
output, ``corrmap`` produces an output of the **same shape as the input**,
9+
where each output element is a normalized correlation computed over a small
10+
window of samples around the corresponding input element.
11+
12+
Supports a 1-D window over the last input dimension (signal-processing form)
13+
and a 2-D window over the last two input dimensions (image-processing form).
14+
All other dimensions are treated as independent batches. The window is
15+
cropped at the input boundary: out-of-bounds offsets are skipped and the
16+
normalization uses only the in-bounds samples (means and energies are
17+
computed over the cropped window, not over a zero-padded one).
18+
19+
Typical applications:
20+
21+
- SAR / InSAR coherence and interferogram phase (complex inputs, MAGNITUDE normalization)
22+
- Stereo matching disparity cost (real inputs, ZNCC normalization)
23+
- Template matching, optical flow, change detection (ZNCC normalization)
24+
25+
.. versionadded:: 1.0.0
26+
27+
.. doxygenfunction:: corrmap(const OpA &A, const OpB &B, index_t window)
28+
.. doxygenfunction:: corrmap(const OpA &A, const OpB &B, const cuda::std::array<index_t, 2> &window)
29+
30+
Normalization modes
31+
~~~~~~~~~~~~~~~~~~~
32+
33+
The compile-time template parameter ``Mode`` selects how each window's
34+
samples are combined. The full mathematical definition of each mode is
35+
given in its ``CorrMapNormalize`` enum value.
36+
37+
.. doxygenenum:: matx::CorrMapNormalize
38+
39+
Input type requirements
40+
~~~~~~~~~~~~~~~~~~~~~~~
41+
42+
Inputs must be floating-point or complex floating-point. Supported inner
43+
scalar types are ``float``, ``double``, ``matx::matxFp16`` /
44+
``matx::matxBf16`` (and the underlying ``__half`` / ``__nv_bfloat16``),
45+
and their complex counterparts.
46+
47+
Integer and complex-integer inputs are rejected at compile time by a
48+
``static_assert``. This applies to every mode, including
49+
:cpp:enumerator:`matx::CorrMapNormalize::NONE`: although the NONE-mode
50+
product :math:`A \cdot \bar B` is mathematically well-defined for
51+
integer operands, the normalized modes (MAGNITUDE / ZNCC) require a
52+
final division that would silently truncate to zero for integer
53+
arithmetic, so all integer inputs are rejected uniformly to avoid a
54+
surprising mode-dependent failure mode. Cast integer inputs explicitly
55+
before calling, e.g. ``corrmap(as_float(A), as_float(B), w)``.
56+
57+
Output element type
58+
~~~~~~~~~~~~~~~~~~~
59+
60+
- Complex if either input is complex.
61+
- Real otherwise.
62+
- Precision is the greater of the inputs: e.g. ``float + double`` produces
63+
``double``, ``complex<float> + complex<double>`` produces
64+
``complex<double>``, and ``complex<float> + double`` also produces
65+
``complex<double>``.
66+
67+
Window indexing
68+
~~~~~~~~~~~~~~~
69+
70+
The window uses the floor-center convention: for a
71+
window of length :math:`w` centered at index :math:`n`, the offsets span
72+
:math:`[-\lfloor w/2 \rfloor,\ w - 1 - \lfloor w/2 \rfloor]`. Odd window
73+
sizes are exactly centered; even window sizes introduce a half-element
74+
registration offset.
75+
76+
Examples
77+
~~~~~~~~
78+
79+
2-D MAGNITUDE on complex inputs (SAR/InSAR coherence):
80+
81+
.. literalinclude:: ../../../../test/00_operators/corrmap_test.cu
82+
:language: cpp
83+
:start-after: example-begin corrmap-2d-magnitude
84+
:end-before: example-end corrmap-2d-magnitude
85+
:dedent:
86+
87+
2-D ZNCC on real inputs (classic normalized cross-correlation):
88+
89+
.. literalinclude:: ../../../../test/00_operators/corrmap_test.cu
90+
:language: cpp
91+
:start-after: example-begin corrmap-2d-zncc
92+
:end-before: example-end corrmap-2d-zncc
93+
:dedent:
94+
95+
1-D MAGNITUDE on a batched real signal:
96+
97+
.. literalinclude:: ../../../../test/00_operators/corrmap_test.cu
98+
:language: cpp
99+
:start-after: example-begin corrmap-1d-magnitude
100+
:end-before: example-end corrmap-1d-magnitude
101+
:dedent:

docs_input/executor_compatibility.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ fused JIT expression; non-JIT CUDA execution through cudaExecutor remains availa
8080
"conv2d", "|yes|", "|yes|", "|no|", "Direct convolution supports host and CUDA executors."
8181
"copy", "|yes|", "|yes|", "|no|", "Executor-dispatched assignment/copy transform; CUDAJITExecutor fuses expression evaluation instead of using this transform directly."
8282
"corr", "|yes|", "|yes|", "|no|", "Direct correlation supports host and CUDA executors. FFT correlation can use the CPU FFT backend when enabled."
83+
"corrmap", "|yes|", "|yes|", "|yes|", "Per-element windowed correlation map (1-D or 2-D window). Inputs must be floating-point or complex floating-point; integer inputs are rejected by static_assert."
8384
"cos", "|yes|", "|yes|", "|yes|", "Element-wise expression."
8485
"cosh", "|yes|", "|yes|", "|yes|", "Element-wise expression."
8586
"cov", "|no|", "|yes|", "|no|", "CUDA-only covariance transform."

0 commit comments

Comments
 (0)