Ocean
ZeroMeanSumSquareDifferences.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_ZERO_MEAN_SUM_SQUARE_DIFFERENCES_H
9 #define META_OCEAN_CV_ZERO_MEAN_SUM_SQUARE_DIFFERENCES_H
10 
11 #include "ocean/cv/CV.h"
15 
16 namespace Ocean
17 {
18 
19 namespace CV
20 {
21 
22 /**
23  * This class implements functions calculating the zero-mean sum of square differences.
24  * @ingroup cv
25  */
27 {
28  public:
29 
30  /**
31  * Returns the zero-mean sum of square differences between two square image patches.
32  * @param image0 The image in which the first patch is located, must be valid
33  * @param image1 The image in which the second patch is located, must be valid
34  * @param width0 The width of the first image, in pixels, with range [tPatchSize, infinity)
35  * @param width1 The width of the second image, in pixels, with range [tPatchSize, infinity)
36  * @param centerX0 Horizontal center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize/2, width - tPatchSize/2 - 1]
37  * @param centerY0 Vertical center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize/2, height - tPatchSize/2 - 1]
38  * @param centerX1 Horizontal center position of the (tPatchSize x tPatchSize) block in the second frame, with range [tPatchSize/2, width - tPatchSize/2 - 1]
39  * @param centerY1 Vertical center position of the (tPatchSize x tPatchSize) block in the second frame, with range [tPatchSize/2, height - tPatchSize/2 - 1]
40  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
41  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity
42  * @return The resulting zero-mean sum of square differences, with range [0, infinity)
43  * @tparam tChannels The number of frame channels, with range [1, infinity)
44  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
45  */
46  template <unsigned int tChannels, unsigned int tPatchSize>
47  static inline uint32_t patch8BitPerChannel(const uint8_t* const image0, const uint8_t* const image1, const unsigned int width0, const unsigned int width1, const unsigned int centerX0, const unsigned int centerY0, const unsigned int centerX1, const unsigned int centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements);
48 
49  /**
50  * Returns the zero-mean sum of square differences between an image patch and a memory buffer.
51  * @param image0 The image in which the image patch is located, must be valid
52  * @param width0 Width of the first frame in pixels, with range [tPatchSize, infinity)
53  * @param centerX0 Horizontal center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize / 2, width0 - tPatchSize / 2 - 1]
54  * @param centerY0 Vertical center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize / 2, height0 - tPatchSize / 2 - 1]
55  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
56  * @param buffer1 The memory buffer with `tChannels * tPatchSize * tPatchSize` elements, must be valid
57  * @return The resulting zero-mean sum of square differences for tPatchSize * tPatchSize * tChannels elements, with range [0, infinity)
58  * @tparam tChannels The number of channels for the given frames, with range [1, infinity)
59  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
60  */
61  template <unsigned int tChannels, unsigned int tPatchSize>
62  static inline unsigned int patchBuffer8BitPerChannel(const uint8_t* const image0, const unsigned int width0, const unsigned int centerX0, const unsigned int centerY0, const unsigned int image0PaddingElements, const uint8_t* const buffer1);
63 
64  /**
65  * Returns the zero-mean sum of square differences between two memory buffers.
66  * @param buffer0 The first memory buffer, must be valid
67  * @param buffer1 The second memory buffer, must be valid
68  * @return The resulting sum of square differences
69  * @tparam tChannels Specifies the number of channels for the given frames
70  * @tparam tPixels The number of pixels the buffer holds, in pixels, with range [1, infinity)
71  */
72  template <unsigned int tChannels, unsigned int tPixels>
73  static inline uint32_t buffer8BitPerChannel(const uint8_t* const buffer0, const uint8_t* const buffer1);
74 
75  /**
76  * Returns the sum of zero-mean square differences between two patches within an image, patch pixels outside the image will be mirrored back into the image.
77  * @param image0 The image in which the first patch is located, must be valid
78  * @param image1 The image in which the second patch is located, must be valid
79  * @param width0 The width of the first image, in pixels, with range [tPatchSize, infinity)
80  * @param height0 The height of the first image, in pixels, with range [tPatchSize, infinity)
81  * @param width1 The width of the second image, in pixels, with range [tPatchSize, infinity)
82  * @param height1 The height of the second image, in pixels, with range [tPatchSize, infinity)
83  * @param centerX0 Horizontal center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize/2, width - tPatchSize/2 - 1]
84  * @param centerY0 Vertical center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize/2, height - tPatchSize/2 - 1]
85  * @param centerX1 Horizontal center position of the (tPatchSize x tPatchSize) block in the second frame, with range [tPatchSize/2, width - tPatchSize/2 - 1]
86  * @param centerY1 Vertical center position of the (tPatchSize x tPatchSize) block in the second frame, with range [tPatchSize/2, height - tPatchSize/2 - 1]
87  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
88  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
89  * @return The resulting zero-mean sum of square differences, with range [0, infinity)
90  * @tparam tChannels The number of frame channels, with range [1, infinity)
91  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
92  */
93  template <unsigned int tChannels, unsigned int tPatchSize>
94  static uint32_t patchMirroredBorder8BitPerChannel(const uint8_t* image0, const uint8_t* image1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, const unsigned int centerX0, const unsigned int centerY0, const unsigned int centerX1, const unsigned int centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements);
95 };
96 
97 template <unsigned int tChannels, unsigned int tPatchSize>
98 inline uint32_t ZeroMeanSumSquareDifferences::patch8BitPerChannel(const uint8_t* const image0, const uint8_t* const image1, const unsigned int width0, const unsigned int width1, const unsigned int centerX0, const unsigned int centerY0, const unsigned int centerX1, const unsigned int centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements)
99 {
100  static_assert(tChannels >= 1u, "Invalid channel number!");
101  static_assert(tPatchSize >= 1u, "Invalid patch size!");
102 
103  ocean_assert(image0 != nullptr && image1 != nullptr);
104 
105  ocean_assert(width0 >= tPatchSize);
106  ocean_assert(width1 >= tPatchSize);
107 
108  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
109 
110  ocean_assert(centerX0 >= tPatchSize_2 && centerY0 >= tPatchSize_2);
111  ocean_assert(centerX1 >= tPatchSize_2 && centerY1 >= tPatchSize_2);
112 
113  ocean_assert(centerX0 < width0 - tPatchSize_2);
114  ocean_assert(centerX1 < width1 - tPatchSize_2);
115 
116  const unsigned int image0StrideElements = width0 * tChannels + image0PaddingElements;
117  const unsigned int image1StrideElements = width1 * tChannels + image1PaddingElements;
118 
119  const uint8_t* const patch0 = image0 + (centerY0 - tPatchSize_2) * image0StrideElements + (centerX0 - tPatchSize_2) * tChannels;
120  const uint8_t* const patch1 = image1 + (centerY1 - tPatchSize_2) * image1StrideElements + (centerX1 - tPatchSize_2) * tChannels;
121 
122 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
123 
124  if constexpr ((tChannels == 1u || tChannels == 3u) && tPatchSize >= 5u)
125  {
126  return ZeroMeanSumSquareDifferencesSSE::patch8BitPerChannel<tChannels, tPatchSize>(patch0, patch1, image0StrideElements, image1StrideElements);
127  }
128 
129 #elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
130 
131  if constexpr ((tChannels == 1u || tChannels == 3u) && tPatchSize >= 5u)
132  {
133  return ZeroMeanSumSquareDifferencesNEON::patch8BitPerChannel<tChannels, tPatchSize>(patch0, patch1, image0StrideElements, image1StrideElements);
134  }
135 
136 #endif // OCEAN_HARDWARE_SSE_VERSION
137 
138  return ZeroMeanSumSquareDifferencesBase::patch8BitPerChannelTemplate<tChannels, tPatchSize>(patch0, patch1, image0StrideElements, image1StrideElements);
139 }
140 
141 template <unsigned int tChannels, unsigned int tPatchSize>
142 inline unsigned int ZeroMeanSumSquareDifferences::patchBuffer8BitPerChannel(const uint8_t* const image0, const unsigned int width0, const unsigned int centerX0, const unsigned int centerY0, const unsigned int image0PaddingElements, const uint8_t* const buffer1)
143 {
144  static_assert(tChannels >= 1u, "Invalid channel number!");
145  static_assert(tPatchSize % 2u == 1u, "Invalid patch size!");
146 
147  ocean_assert(image0 != nullptr && buffer1 != nullptr);
148 
149  ocean_assert(width0 >= tPatchSize);
150 
151  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
152 
153  ocean_assert(centerX0 >= tPatchSize_2 && centerY0 >= tPatchSize_2);
154 
155  ocean_assert(centerX0 < width0 - tPatchSize_2);
156 
157  const unsigned int image0StrideElements = width0 * tChannels + image0PaddingElements;
158 
159  const uint8_t* const patch0 = image0 + (centerY0 - tPatchSize_2) * image0StrideElements + (centerX0 - tPatchSize_2) * tChannels;
160 
161 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
162 
163  if constexpr ((tChannels == 1u || tChannels == 3u) && tPatchSize >= 5u)
164  {
165  return ZeroMeanSumSquareDifferencesSSE::patchBuffer8BitPerChannel<tChannels, tPatchSize>(patch0, buffer1, image0StrideElements);
166  }
167 
168 #elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
169 
170  if constexpr ((tChannels == 1u || tChannels == 3u) && tPatchSize >= 5u)
171  {
172  return ZeroMeanSumSquareDifferencesNEON::patchBuffer8BitPerChannel<tChannels, tPatchSize>(patch0, buffer1, image0StrideElements);
173  }
174 
175 #endif // OCEAN_HARDWARE_SSE_VERSION, OCEAN_HARDWARE_NEON_VERSION
176 
177  return ZeroMeanSumSquareDifferencesBase::patchBuffer8BitPerChannelTemplate<tChannels, tPatchSize>(patch0, buffer1, image0StrideElements);
178 }
179 
180 template <unsigned int tChannels, unsigned int tPixels>
181 inline uint32_t ZeroMeanSumSquareDifferences::buffer8BitPerChannel(const uint8_t* const buffer0, const uint8_t* const buffer1)
182 {
183  static_assert(tChannels >= 1u, "Invalid channel number!");
184  static_assert(tPixels >= 1u, "Invalid pixel number!");
185 
186 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
187 
188  if constexpr ((tChannels == 1u || tChannels == 3u) && tPixels >= 8u)
189  {
190  return ZeroMeanSumSquareDifferencesSSE::buffer8BitPerChannel<tChannels, tPixels>(buffer0, buffer1);
191  }
192 
193 #elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
194 
195  if constexpr ((tChannels == 1u || tChannels == 3u) && tPixels >= 8u)
196  {
197  return ZeroMeanSumSquareDifferencesNEON::buffer8BitPerChannel<tChannels, tPixels>(buffer0, buffer1);
198  }
199 
200 #endif // OCEAN_HARDWARE_SSE_VERSION
201 
202  return ZeroMeanSumSquareDifferencesBase::buffer8BitPerChannelTemplate<tChannels, tPixels>(buffer0, buffer1);
203 }
204 
205 template <unsigned int tChannels, unsigned int tPatchSize>
206 uint32_t ZeroMeanSumSquareDifferences::patchMirroredBorder8BitPerChannel(const uint8_t* image0, const uint8_t* image1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, const unsigned int centerX0, const unsigned int centerY0, const unsigned int centerX1, const unsigned int centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements)
207 {
208  static_assert(tChannels >= 1u, "Invalid channel number!");
209  static_assert(tPatchSize % 2u == 1u, "Invalid patch size!");
210 
211 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
212 
213  if constexpr (tChannels == 1u && tPatchSize >= 5u)
214  {
215  return ZeroMeanSumSquareDifferencesNEON::patchMirroredBorder8BitPerChannel<tChannels, tPatchSize>(image0, image1, width0, height0, width1, height1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
216  }
217 
218 #endif // OCEAN_HARDWARE_NEON_VERSION
219 
220  return ZeroMeanSumSquareDifferencesBase::patchMirroredBorder8BitPerChannel<tChannels>(image0, image1, tPatchSize, width0, height0, width1, height1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
221 }
222 
223 }
224 
225 }
226 
227 #endif // META_OCEAN_CV_ZERO_MEAN_SUM_SQUARE_DIFFERENCES_H
This class implements several zero-mean sum square differences functions based e.g....
Definition: ZeroMeanSumSquareDifferencesBase.h:25
This class implements functions calculating the zero-mean sum of square differences.
Definition: ZeroMeanSumSquareDifferences.h:27
static uint32_t patch8BitPerChannel(const uint8_t *const image0, const uint8_t *const image1, const unsigned int width0, const unsigned int width1, const unsigned int centerX0, const unsigned int centerY0, const unsigned int centerX1, const unsigned int centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements)
Returns the zero-mean sum of square differences between two square image patches.
Definition: ZeroMeanSumSquareDifferences.h:98
static uint32_t buffer8BitPerChannel(const uint8_t *const buffer0, const uint8_t *const buffer1)
Returns the zero-mean sum of square differences between two memory buffers.
Definition: ZeroMeanSumSquareDifferences.h:181
static uint32_t patchMirroredBorder8BitPerChannel(const uint8_t *image0, const uint8_t *image1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, const unsigned int centerX0, const unsigned int centerY0, const unsigned int centerX1, const unsigned int centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements)
Returns the sum of zero-mean square differences between two patches within an image,...
Definition: ZeroMeanSumSquareDifferences.h:206
static unsigned int patchBuffer8BitPerChannel(const uint8_t *const image0, const unsigned int width0, const unsigned int centerX0, const unsigned int centerY0, const unsigned int image0PaddingElements, const uint8_t *const buffer1)
Returns the zero-mean sum of square differences between an image patch and a memory buffer.
Definition: ZeroMeanSumSquareDifferences.h:142
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15