Ocean
SumSquareDifferences.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_SUM_SQUARE_DIFFERENCES_H
9 #define META_OCEAN_CV_SUM_SQUARE_DIFFERENCES_H
10 
11 #include "ocean/cv/CV.h"
15 
16 #include "ocean/base/Messenger.h"
17 
18 namespace Ocean
19 {
20 
21 namespace CV
22 {
23 
24 /**
25  * This class implements functions calculating the sum of square differences.
26  * @ingroup cv
27  */
29 {
30  public:
31 
32  /**
33  * Returns the sum of square differences between two square image patches.
34  * @param image0 The image in which the first patch is located, must be valid
35  * @param image1 The image in which the second patch is located, must be valid
36  * @param width0 The width of the first image, in pixels, with range [tPatchSize, infinity)
37  * @param width1 The width of the second image, in pixels, with range [tPatchSize, infinity)
38  * @param centerX0 Horizontal center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize/2, width - tPatchSize/2 - 1]
39  * @param centerY0 Vertical center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize/2, height - tPatchSize/2 - 1]
40  * @param centerX1 Horizontal center position of the (tPatchSize x tPatchSize) block in the second frame, with range [tPatchSize/2, width - tPatchSize/2 - 1]
41  * @param centerY1 Vertical center position of the (tPatchSize x tPatchSize) block in the second frame, with range [tPatchSize/2, height - tPatchSize/2 - 1]
42  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
43  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
44  * @return The resulting sum of square differences, with range [0, infinity)
45  * @tparam tChannels The number of frame channels, with range [1, infinity)
46  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
47  */
48  template <unsigned int tChannels, unsigned int tPatchSize>
49  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);
50 
51  /**
52  * Returns the sum of square differences between an image patch and a memory buffer.
53  * @param image0 The image in which the image patch is located, must be valid
54  * @param width0 Width of the first frame in pixels, with range [tPatchSize, infinity)
55  * @param centerX0 Horizontal center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize / 2, width0 - tPatchSize / 2 - 1]
56  * @param centerY0 Vertical center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize / 2, height0 - tPatchSize / 2 - 1]
57  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
58  * @param buffer1 The memory buffer with `tChannels * tPatchSize * tPatchSize` elements, must be valid
59  * @return The resulting sum of square differences for tPatchSize * tPatchSize * tChannels elements, with range [0, infinity)
60  * @tparam tChannels The number of channels for the given frames, with range [1, infinity)
61  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
62  */
63  template <unsigned int tChannels, unsigned int tPatchSize>
64  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);
65 
66  /**
67  * Returns the sum of square differences between two memory buffers.
68  * @param buffer0 The first memory buffer, must be valid
69  * @param buffer1 The second memory buffer, must be valid
70  * @return The resulting sum of square differences
71  * @tparam tChannels The number of channels the buffers have, with range [1, infinity)
72  * @tparam tPixels The number of pixels the buffer holds, in pixels, with range [1, infinity)
73  */
74  template <unsigned int tChannels, unsigned int tPixels>
75  static inline uint32_t buffer8BitPerChannel(const uint8_t* const buffer0, const uint8_t* const buffer1);
76 
77  /**
78  * Returns the sum of square differences between two square image patches which can be partially outside of the images.
79  * @param image0 The image in which the first patch is located, must be valid
80  * @param image1 The image in which the second patch is located, must be valid
81  * @param width0 The width of the first image, in pixels, with range [tPatchSize/2 + 1, infinity)
82  * @param height0 The height of the first image, in pixels, with range [tPatchSize/2 + 1, infinity)
83  * @param width1 The width of the second image, in pixels, with range [tPatchSize/2 + 1, infinity)
84  * @param height1 The height of the second image, in pixels, with range [tPatchSize/2 + 1, infinity)
85  * @param centerX0 Horizontal center position of the (tPatchSize x tPatchSize) block in the first frame, with range [0, width0 - 1]
86  * @param centerY0 Vertical center position of the (tPatchSize x tPatchSize) block in the first frame, with range [0, height0 - 1]
87  * @param centerX1 Horizontal center position of the (tPatchSize x tPatchSize) block in the second frame, with range [0, width1 - 1]
88  * @param centerY1 Vertical center position of the (tPatchSize x tPatchSize) block in the second frame, with range [0, height1 - 1]
89  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
90  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
91  * @return Pair holding the resulting ssd and the number of pixels which contributed to the ssd, an ssd of -1 if a patch0 pixel does not have a corresponding patch1 pixel
92  * @tparam tChannels The number of frame channels, with range [1, infinity)
93  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
94  */
95  template <unsigned int tChannels, unsigned int tPatchSize>
96  static inline IndexPair32 patchAtBorder8BitPerChannel(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);
97 
98  /**
99  * Returns the sum of square differences between two patches within an image, patch pixels outside the image will be mirrored back into the image.
100  * @param image0 The image in which the first patch is located, must be valid
101  * @param image1 The image in which the second patch is located, must be valid
102  * @param width0 The width of the first image, in pixels, with range [tPatchSize, infinity)
103  * @param height0 The height of the first image, in pixels, with range [tPatchSize, infinity)
104  * @param width1 The width of the second image, in pixels, with range [tPatchSize, infinity)
105  * @param height1 The height of the second image, in pixels, with range [tPatchSize, infinity)
106  * @param centerX0 Horizontal center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize/2, width - tPatchSize/2 - 1]
107  * @param centerY0 Vertical center position of the (tPatchSize x tPatchSize) block in the first frame, with range [tPatchSize/2, height - tPatchSize/2 - 1]
108  * @param centerX1 Horizontal center position of the (tPatchSize x tPatchSize) block in the second frame, with range [tPatchSize/2, width - tPatchSize/2 - 1]
109  * @param centerY1 Vertical center position of the (tPatchSize x tPatchSize) block in the second frame, with range [tPatchSize/2, height - tPatchSize/2 - 1]
110  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
111  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
112  * @return The resulting sum of square differences, with range [0, infinity)
113  * @tparam tChannels The number of frame channels, with range [1, infinity)
114  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
115  */
116  template <unsigned int tChannels, unsigned int tPatchSize>
117  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);
118 };
119 
120 template <unsigned int tChannels, unsigned int tPatchSize>
121 inline uint32_t SumSquareDifferences::patch8BitPerChannel(const uint8_t* image0, const uint8_t* 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)
122 {
123  static_assert(tChannels >= 1u, "Invalid channel number!");
124  static_assert(tPatchSize >= 1u, "Invalid patch size!");
125 
126  ocean_assert(image0 != nullptr && image1 != nullptr);
127 
128  ocean_assert(width0 >= tPatchSize);
129  ocean_assert(width1 >= tPatchSize);
130 
131  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
132 
133  ocean_assert(centerX0 >= tPatchSize_2 && centerY0 >= tPatchSize_2);
134  ocean_assert(centerX1 >= tPatchSize_2 && centerY1 >= tPatchSize_2);
135 
136  ocean_assert(centerX0 < width0 - tPatchSize_2);
137  ocean_assert(centerX1 < width1 - tPatchSize_2);
138 
139  const unsigned int image0StrideElements = width0 * tChannels + image0PaddingElements;
140  const unsigned int image1StrideElements = width1 * tChannels + image1PaddingElements;
141 
142  const uint8_t* const patch0 = image0 + (centerY0 - tPatchSize_2) * image0StrideElements + (centerX0 - tPatchSize_2) * tChannels;
143  const uint8_t* const patch1 = image1 + (centerY1 - tPatchSize_2) * image1StrideElements + (centerX1 - tPatchSize_2) * tChannels;
144 
145 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
146 
147  if constexpr (tPatchSize >= 5u)
148  {
149  return SumSquareDifferencesSSE::patch8BitPerChannel<tChannels, tPatchSize>(patch0, patch1, image0StrideElements, image1StrideElements);
150  }
151 
152 #elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
153 
154  if constexpr (tPatchSize >= 5u)
155  {
156  return SumSquareDifferencesNEON::patch8BitPerChannel<tChannels, tPatchSize>(patch0, patch1, image0StrideElements, image1StrideElements);
157  }
158 
159 #endif // OCEAN_HARDWARE_SSE_VERSION, OCEAN_HARDWARE_NEON_VERSION
160 
161  return SumSquareDifferencesBase::patch8BitPerChannelTemplate<tChannels, tPatchSize>(patch0, patch1, image0StrideElements, image1StrideElements);
162 }
163 
164 template <unsigned int tChannels, unsigned int tPatchSize>
165 inline uint32_t SumSquareDifferences::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)
166 {
167  static_assert(tChannels >= 1u, "Invalid channel number!");
168  static_assert(tPatchSize % 2u == 1u, "Invalid patch size!");
169 
170  ocean_assert(image0 != nullptr && buffer1 != nullptr);
171 
172  ocean_assert(width0 >= tPatchSize);
173 
174  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
175 
176  ocean_assert(centerX0 >= tPatchSize_2 && centerY0 >= tPatchSize_2);
177 
178  ocean_assert(centerX0 < width0 - tPatchSize_2);
179 
180  const unsigned int image0StrideElements = width0 * tChannels + image0PaddingElements;
181 
182  const uint8_t* const patch0 = image0 + (centerY0 - tPatchSize_2) * image0StrideElements + (centerX0 - tPatchSize_2) * tChannels;
183 
184 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
185 
186  if constexpr (tPatchSize >= 5u)
187  {
188  return SumSquareDifferencesSSE::patchBuffer8BitPerChannel<tChannels, tPatchSize>(patch0, buffer1, image0StrideElements);
189  }
190 
191 #elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
192 
193  if constexpr (tPatchSize >= 5u)
194  {
195  return SumSquareDifferencesNEON::patchBuffer8BitPerChannel<tChannels, tPatchSize>(patch0, buffer1, image0StrideElements);
196  }
197 
198 #endif // OCEAN_HARDWARE_SSE_VERSION, OCEAN_HARDWARE_NEON_VERSION
199 
200  return SumSquareDifferencesBase::patchBuffer8BitPerChannelTemplate<tChannels, tPatchSize>(patch0, buffer1, image0StrideElements);
201 }
202 
203 template <unsigned int tChannels, unsigned int tPixels>
204 inline uint32_t SumSquareDifferences::buffer8BitPerChannel(const uint8_t* const buffer0, const uint8_t* const buffer1)
205 {
206  static_assert(tChannels >= 1u, "Invalid channel number!");
207  static_assert(tPixels >= 1u, "Invalid pixel number!");
208 
209  constexpr unsigned int tElements = tChannels * tPixels;
210 
211 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
212 
213  if constexpr (tElements >= 15u)
214  {
215  return SumSquareDifferencesSSE::buffer8BitPerChannel<tElements>(buffer0, buffer1);
216  }
217 
218 #elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
219 
220  if constexpr (tElements >= 8u)
221  {
222  return SumSquareDifferencesNEON::buffer8BitPerChannel<tElements>(buffer0, buffer1);
223  }
224 
225 #endif // OCEAN_HARDWARE_SSE_VERSION, OCEAN_HARDWARE_NEON_VERSION
226 
227  return SumSquareDifferencesBase::buffer8BitPerChannelTemplate<tElements>(buffer0, buffer1);
228 }
229 
230 template <unsigned int tChannels, unsigned int tPatchSize>
231 inline IndexPair32 SumSquareDifferences::patchAtBorder8BitPerChannel(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)
232 {
233  static_assert(tChannels >= 1u, "Invalid channel number!");
234  static_assert(tPatchSize % 2u == 1u, "Invalid patch size!");
235 
236  return SumSquareDifferencesBase::patchAtBorder8BitPerChannelTemplate<tChannels, tPatchSize>(image0, image1, width0, height0, width1, height1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
237 }
238 
239 template <unsigned int tChannels, unsigned int tPatchSize>
240 uint32_t SumSquareDifferences::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)
241 {
242  static_assert(tChannels >= 1u, "Invalid channel number!");
243  static_assert(tPatchSize % 2u == 1u, "Invalid patch size!");
244 
245 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
246 
247  if constexpr (tPatchSize >= 5u)
248  {
249  return SumSquareDifferencesNEON::patchMirroredBorder8BitPerChannel<tChannels, tPatchSize>(image0, image1, width0, height0, width1, height1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
250  }
251 
252 #endif // OCEAN_HARDWARE_SSE_VERSION, OCEAN_HARDWARE_NEON_VERSION
253 
254  return SumSquareDifferencesBase::patchMirroredBorder8BitPerChannelTemplate<tChannels>(image0, image1, tPatchSize, width0, height0, width1, height1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
255 }
256 
257 }
258 
259 }
260 
261 #endif // META_OCEAN_CV_SUM_SQUARE_DIFFERENCES_H
This class implements several sum square differences functions based e.g., on template parameters.
Definition: SumSquareDifferencesBase.h:25
This class implements functions calculating the sum of square differences.
Definition: SumSquareDifferences.h:29
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 sum of square differences between two square image patches.
Definition: SumSquareDifferences.h:121
static uint32_t buffer8BitPerChannel(const uint8_t *const buffer0, const uint8_t *const buffer1)
Returns the sum of square differences between two memory buffers.
Definition: SumSquareDifferences.h:204
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 sum of square differences between an image patch and a memory buffer.
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 square differences between two patches within an image, patch pixels outside the i...
Definition: SumSquareDifferences.h:240
static IndexPair32 patchAtBorder8BitPerChannel(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 square differences between two square image patches which can be partially outside...
Definition: SumSquareDifferences.h:231
std::pair< Index32, Index32 > IndexPair32
Definition of a pair holding 32 bit indices.
Definition: Base.h:138
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15