Ocean
AdvancedZeroMeanSumSquareDifferences.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_ADVANCED_ADVANCED_ZERO_MEAN_SUM_SQUARE_DIFFERENCES_H
9 #define META_OCEAN_CV_ADVANCED_ADVANCED_ZERO_MEAN_SUM_SQUARE_DIFFERENCES_H
10 
13 
14 #include "ocean/cv/PixelPosition.h"
15 
16 #include "ocean/math/Math.h"
17 
18 namespace Ocean
19 {
20 
21 namespace CV
22 {
23 
24 namespace Advanced
25 {
26 
27 /**
28  * This class implements zero-mean sum of square difference calculation functions.
29  * @ingroup cvadvanced
30  */
32 {
33  public:
34 
35  /**
36  * Returns the sum of square differences for an image patch block determined for two sub-pixel positions between two individual images.
37  * @param image0 The image in which the first patch is located, must be valid
38  * @param image1 The image in which the second patch is located, must be valid
39  * @param width0 The width of the first image, in pixels, with range [tPatchSize + 1, infinity)
40  * @param width1 The width of the second image, in pixels, with range [tPatchSize + 1, infinity)
41  * @param centerX0 Horizontal sub-pixel center position of the (tSize x tSize) block in the first frame, with range [tSize/2, width0 - tSize/2 - 1)
42  * @param centerY0 Vertical sub-pixel center position of the (tSize x tSize) block in the first frame, with range [tSize/2, height0 - tSize/2 - 1)
43  * @param centerX1 Horizontal sub-pixel center position of the (tSize x tSize) block in the second frame, with range [tSize/2, width1 - tSize/2 - 1)
44  * @param centerY1 Vertical sub-pixel center position of the (tSize x tSize) block in the second frame, with range [tSize/2, height1 - tSize/2 - 1)
45  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
46  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
47  * @return The resulting sum of square differences, with range [0, infinity)
48  * @tparam tChannels The number of frame channels, with range [1, infinity)
49  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
50  */
51  template <unsigned int tChannels, unsigned int tPatchSize>
52  static inline uint32_t patch8BitPerChannel(const uint8_t* image0, const uint8_t* image1, const unsigned int width0, const unsigned int width1, const Scalar centerX0, const Scalar centerY0, const Scalar centerX1, const Scalar centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements);
53 
54  /**
55  * Returns the sum of square differences for an image patch block determined for one pixel and one sub-pixel position between two individual images.
56  * @param image0 The image in which the first patch is located, must be valid
57  * @param image1 The image in which the second patch is located, must be valid
58  * @param width0 The width of the first image, in pixels, with range [tPatchSize + 1, infinity)
59  * @param width1 The width of the second image, in pixels, with range [tPatchSize + 1, infinity)
60  * @param centerX0 Horizontal pixel center position of the (tSize x tSize) block in the first frame, with range [tSize/2, width0 - tSize/2)
61  * @param centerY0 Vertical pixel center position of the (tSize x tSize) block in the first frame, with range [tSize/2, height0 - tSize/2)
62  * @param centerX1 Horizontal sub-pixel center position of the (tSize x tSize) block in the second frame, with range [tSize/2, width1 - tSize/2 - 1)
63  * @param centerY1 Vertical sub-pixel center position of the (tSize x tSize) block in the second frame, with range [tSize/2, height1 - tSize/2 - 1)
64  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
65  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
66  * @return The resulting sum of square differences, with range [0, infinity)
67  * @tparam tChannels The number of frame channels, with range [1, infinity)
68  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
69  */
70  template <unsigned int tChannels, unsigned int tPatchSize>
71  static inline uint32_t 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 Scalar centerX1, const Scalar centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements);
72 
73  /**
74  * Determines the sum of square differences between an image patch with sub-pixel accuracy and a memory buffer.
75  * @param image0 The image in which the patch is located with sub-pixel accuracy, must be valid
76  * @param width0 The width of the image in pixel, with range [tPatchSize + 1, infinity)
77  * @param centerX0 The horizontal center position of the image patch with sub-pixel accuracy, with range [tPatchSize / 2, width0 - tPatchSize / 2 - 1]
78  * @param centerY0 The vertical center position of the image patch with sub-pixel accuracy, with range [tPatchSize / 2, height0 - tPatchSize / 2 - 1]
79  * @param image0PaddingElements The number of padding elements at the end of each image row, in elements, with range [0, infinity)
80  * @param buffer1 The memory buffer with `tChannels * tPatchSize * tPatchSize` elements, must be valid
81  * @return The resulting ssd value
82  * @tparam tChannels The number of channels for the given frames, with range [1, infinity)
83  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
84  */
85  template <unsigned int tChannels, unsigned int tPatchSize>
86  static inline uint32_t patchBuffer8BitPerChannel(const uint8_t* image0, const unsigned int width0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t* buffer1);
87 
88  /**
89  * Determines the sum of square differences between an image patch with sub-pixel accuracy and a memory buffer.
90  * Pixels in the square region pointing outside the frame are mirrored back into the frame.
91  * @param image0 The image in which the patch is located with sub-pixel accuracy, must be valid
92  * @param width0 The width of the image in pixel, with range [tPatchSize/2 + 1, infinity)
93  * @param height0 The height of the image in pixel, with range [tPatchSize/2 + 1, infinity)
94  * @param centerX0 The horizontal center position of the image patch with sub-pixel accuracy, with range [0, width0)
95  * @param centerY0 The vertical center position of the image patch with sub-pixel accuracy, with range [0, height0)
96  * @param image0PaddingElements The number of padding elements at the end of each image row, in elements, with range [0, infinity)
97  * @param buffer1 The memory buffer with `tChannels * tPatchSize * tPatchSize` elements, must be valid
98  * @return The resulting ssd value
99  * @tparam tChannels The number of channels for the given frames, with range [1, infinity)
100  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
101  */
102  template <unsigned int tChannels, unsigned int tPatchSize>
103  static inline uint32_t patchMirroredBorderBuffer8BitPerChannel(const uint8_t* image0, const unsigned int width0, const unsigned int height0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t* buffer1);
104 };
105 
106 template <unsigned int tChannels, unsigned int tPatchSize>
107 inline uint32_t AdvancedZeroMeanSumSquareDifferences::patch8BitPerChannel(const uint8_t* image0, const uint8_t* image1, const unsigned int width0, const unsigned int width1, const Scalar centerX0, const Scalar centerY0, const Scalar centerX1, const Scalar centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements)
108 {
109  static_assert(tChannels >= 1u, "Invalid channel number!");
110  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid patch size!");
111 
112  ocean_assert(image0 != nullptr && image1 != nullptr);
113 
114  ocean_assert(width0 >= tPatchSize + 1u);
115  ocean_assert(width1 >= tPatchSize + 1u);
116 
117  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
118 
119  ocean_assert(centerX0 >= Scalar(tPatchSize_2) && centerX0 < Scalar(width0 - tPatchSize_2 - 1u));
120  ocean_assert(centerX1 >= Scalar(tPatchSize_2) && centerX1 < Scalar(width1 - tPatchSize_2 - 1u));
121 
122  ocean_assert_and_suppress_unused(centerY0 >= Scalar(tPatchSize_2) && centerY1 >= Scalar(tPatchSize_2), tPatchSize_2);
123 
124 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
125 
126  /*if constexpr (tChannels >= 1u && tChannels <= 4u && tPatchSize == 5u) // not yet implemented
127  {
128  return AdvancedZeroMeanSumSquareDifferencesSSE::patch8BitPerChannel<tChannels, tPatchSize>(image0, image1, width0, width1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
129  }*/
130 
131 #elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
132 
133  /*if constexpr (tPatchSize >= 5u) // not yet implemented
134  {
135  return AdvancedZeroMeanSumSquareDifferencesNEON::patch8BitPerChannel<tChannels, tPatchSize>(image0, image1, width0, width1, centeRX0, centerY0, centeRX1, centerY1, image0PaddingElements, image1PaddingElements);
136  }*/
137 
138 #endif // OCEAN_HARDWARE_SSE_VERSION, OCEAN_HARDWARE_NEON_VERSION
139 
140  return AdvancedZeroMeanSumSquareDifferencesBase::patch8BitPerChannelTemplate<tChannels, tPatchSize>(image0, image1, width0, width1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
141 }
142 
143 template <unsigned int tChannels, unsigned int tPatchSize>
144 inline uint32_t AdvancedZeroMeanSumSquareDifferences::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 Scalar centerX1, const Scalar centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements)
145 {
146  static_assert(tChannels >= 1u, "Invalid channel number!");
147  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid patch size!");
148 
149  ocean_assert(image0 != nullptr && image1 != nullptr);
150 
151  ocean_assert(width0 >= tPatchSize + 1u);
152  ocean_assert(width1 >= tPatchSize + 1u);
153 
154  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
155 
156  ocean_assert(centerX0 >= tPatchSize_2 && centerX0 < width0 - tPatchSize_2);
157  ocean_assert(centerX1 >= Scalar(tPatchSize_2) && centerX1 < Scalar(width1 - tPatchSize_2 - 1u));
158 
159  ocean_assert_and_suppress_unused(centerY0 >= tPatchSize_2 && centerY1 >= Scalar(tPatchSize_2), tPatchSize_2);
160 
161 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
162 
163  /*if constexpr (tChannels >= 1u && tChannels <= 4u && tPatchSize == 5u)
164  {
165  return AdvancedZeroMeanSumSquareDifferencesSSE::patch8BitPerChannel<tChannels, tPatchSize>(image0, image1, width0, width1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
166  }*/
167 
168 #elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
169 
170  /*if constexpr (tPatchSize >= 5u)
171  {
172  return AdvancedZeroMeanSumSquareDifferencesNEON::patch8BitPerChannel<tChannels, tPatchSize>(image0, image1, width0, width1, centeRX0, centerY0, centeRX1, centerY1, image0PaddingElements, image1PaddingElements); // **TODO**
173  }*/
174 
175 #endif // OCEAN_HARDWARE_SSE_VERSION, OCEAN_HARDWARE_NEON_VERSION
176 
177  return AdvancedZeroMeanSumSquareDifferencesBase::patch8BitPerChannelTemplate<tChannels, tPatchSize>(image0, image1, width0, width1, centerX0, centerY0, centerX1, centerY1, image0PaddingElements, image1PaddingElements);
178 }
179 
180 template <unsigned int tChannels, unsigned int tPatchSize>
181 inline uint32_t AdvancedZeroMeanSumSquareDifferences::patchBuffer8BitPerChannel(const uint8_t* image0, const unsigned int width0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t* buffer1)
182 {
183  static_assert(tChannels != 0u, "Invalid number of image channels!");
184  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid patch size!");
185 
186  ocean_assert(image0 != nullptr && buffer1 != nullptr);
187 
188  ocean_assert(width0 >= tPatchSize + 1u);
189 
190  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
191 
192  ocean_assert_and_suppress_unused(centerX0 >= Scalar(tPatchSize_2) && centerX0 < Scalar(width0 - tPatchSize_2 - 1u), tPatchSize_2);
193  ocean_assert(centerY0 >= Scalar(tPatchSize_2));
194 
195  constexpr unsigned int tPatchPixels = tPatchSize * tPatchSize;
196 
197  uint8_t target[tPatchPixels * tChannels];
198  AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize>(image0, width0, image0PaddingElements, target, Vector2(centerX0, centerY0));
199  return ZeroMeanSumSquareDifferences::buffer8BitPerChannel<tChannels, tPatchPixels>(target, buffer1);
200 }
201 
202 template <unsigned int tChannels, unsigned int tPatchSize>
203 inline uint32_t AdvancedZeroMeanSumSquareDifferences::patchMirroredBorderBuffer8BitPerChannel(const uint8_t* image0, const unsigned int width0, const unsigned int height0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t* buffer1)
204 {
205  static_assert(tChannels != 0u, "Invalid number of image channels!");
206  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid patch size!");
207 
208  ocean_assert(image0 != nullptr && buffer1 != nullptr);
209 
210  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
211 
212  ocean_assert(width0 >= tPatchSize_2 + 1u);
213  ocean_assert_and_suppress_unused(height0 >= tPatchSize_2 + 1u, tPatchSize_2);
214 
215  ocean_assert(centerX0 >= Scalar(0) && centerX0 < Scalar(width0));
216  ocean_assert(centerY0 >= Scalar(0) && centerY0 < Scalar(height0));
217 
218  constexpr unsigned int tPatchPixels = tPatchSize * tPatchSize;
219 
220  uint8_t target[tPatchPixels * tChannels];
221  AdvancedFrameInterpolatorBilinear::interpolateSquareMirroredBorder8BitPerChannel<tChannels, tPatchSize>(image0, width0, height0, image0PaddingElements, target, Vector2(centerX0, centerY0));
222  return ZeroMeanSumSquareDifferences::buffer8BitPerChannel<tChannels, tPatchPixels>(target, buffer1);
223 }
224 
225 }
226 
227 }
228 
229 }
230 
231 #endif // META_OCEAN_CV_ADVANCED_ADVANCED_ZERO_MEAN_SUM_SQUARE_DIFFERENCES_H
This class implements functions calculating the zero-mean sum of square differences.
Definition: AdvancedZeroMeanSumSquareDifferencesBase.h:31
This class implements zero-mean sum of square difference calculation functions.
Definition: AdvancedZeroMeanSumSquareDifferences.h:32
static uint32_t patchBuffer8BitPerChannel(const uint8_t *image0, const unsigned int width0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t *buffer1)
Determines the sum of square differences between an image patch with sub-pixel accuracy and a memory ...
Definition: AdvancedZeroMeanSumSquareDifferences.h:181
static uint32_t patch8BitPerChannel(const uint8_t *image0, const uint8_t *image1, const unsigned int width0, const unsigned int width1, const Scalar centerX0, const Scalar centerY0, const Scalar centerX1, const Scalar centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements)
Returns the sum of square differences for an image patch block determined for two sub-pixel positions...
Definition: AdvancedZeroMeanSumSquareDifferences.h:107
static uint32_t patchMirroredBorderBuffer8BitPerChannel(const uint8_t *image0, const unsigned int width0, const unsigned int height0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t *buffer1)
Determines the sum of square differences between an image patch with sub-pixel accuracy and a memory ...
Definition: AdvancedZeroMeanSumSquareDifferences.h:203
float Scalar
Definition of a scalar type.
Definition: Math.h:128
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15