Ocean
AdvancedSumSquareDifferencesBase.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_SUM_SQUARE_DIFFERENCES_TEMPLATE_H
9 #define META_OCEAN_CV_ADVANCED_ADVANCED_SUM_SQUARE_DIFFERENCES_TEMPLATE_H
10 
13 
16 #include "ocean/cv/PixelPosition.h"
17 
18 namespace Ocean
19 {
20 
21 namespace CV
22 {
23 
24 namespace Advanced
25 {
26 
27 /**
28  * This class implements functions calculating the sum of square differences and omit center pixel.
29  * @ingroup cvadvanced
30  */
31 class OCEAN_CV_ADVANCED_EXPORT AdvancedSumSquareDifferencesBase
32 {
33  public:
34 
35  /**
36  * Returns the sum of square differences for an image patch determined 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 center position of the (tSize x tSize) block in the first frame, with range [tPatchSize/2, width - tPatchSize/2 - 1)
42  * @param centerY0 Vertical center position of the (tSize x tSize) block in the first frame, with range [tPatchSize/2, height - tPatchSize/2 - 1)
43  * @param centerX1 Horizontal center position of the (tSize x tSize) block in the second frame, with range [tPatchSize/2, width - tPatchSize/2 - 1)
44  * @param centerY1 Vertical center position of the (tSize x tSize) block in the second frame, with range [tPatchSize/2, height - tPatchSize/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 uint32_t patch8BitPerChannelTemplate(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 determined 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 center position of the (tSize x tSize) block in the first frame, with range [tPatchSize/2, width - tPatchSize/2)
61  * @param centerY0 Vertical center position of the (tSize x tSize) block in the first frame, with range [tPatchSize/2, height - tPatchSize/2)
62  * @param centerX1 Horizontal center position of the (tSize x tSize) block in the second frame, with range [tPatchSize/2, width - tPatchSize/2 - 1)
63  * @param centerY1 Vertical center position of the (tSize x tSize) block in the second frame, with range [tPatchSize/2, height - tPatchSize/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 uint32_t patch8BitPerChannelTemplate(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 patchBuffer8BitPerChannelTemplate(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  * Returns the sum of square differences for an image patch determined for two pixel accurate positions between two individual images.
90  * Further, each image is associated with a binary mask, only valid non-mask pixels are used during SSD calculation.
91  * @param image0 The image in which the first patch is located, must be valid
92  * @param image1 The image in which the second patch is located, must be valid
93  * @param mask0 The mask associated with the first image, must be valid
94  * @param mask1 The mask associated with the second image, must be valid
95  * @param width0 The width of the first image, in pixels, with range [patchSize / 2 + 1, infinity)
96  * @param height0 The height of the first image, in pixels, with range [patchSize / 2 + 1, infinity)
97  * @param width1 The width of the second image, in pixels, with range [patchSize / 2 + 1, infinity)
98  * @param height1 The height of the second image, in pixels, with range [patchSize / 2 + 1, infinity)
99  * @param centerX0 Horizontal sub-pixel center position of the (tPatchSize x tPatchSize) block in the first frame, with range [0, width0 - 1]
100  * @param centerY0 Vertical sub-pixel center position of the (tPatchSize x tPatchSize) block in the first frame, with range [0, height0 - 1]
101  * @param centerX1 Horizontal sub-pixel center position of the (tPatchSize x tPatchSize) block in the second frame, with range [0, width1 - 1]
102  * @param centerY1 Vertical sub-pixel center position of the (tPatchSize x tPatchSize) block in the second frame, with range [0, height1 - 1]
103  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
104  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
105  * @param mask0PaddingElements The number of padding elements at the end of each row of the first mask, in elements, with range [0, infinity)
106  * @param mask1PaddingElements The number of padding elements at the end of each row of the second mask, in elements, with range [0, infinity)
107  * @param maskValue The pixel value of a mask pixel which will be excluded when calculating the SSD, with range [0, 255]
108  * @return The resulting pair holding first: sum of square differences, second: number of pixels contributed to the result
109  * @tparam tChannels The number of frame channels, with range [1, infinity)
110  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
111  */
112  template <unsigned int tChannels, unsigned int tPatchSize>
113  static IndexPair32 patchWithMask8BitPerChannelTemplate(const uint8_t* image0, const uint8_t* image1, const uint8_t* mask0, const uint8_t* mask1, 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, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue);
114 
115  /**
116  * Returns the sum of square differences for an image patch determined for two sub-pixel accurate positions between two individual images.
117  * Further, each image is associated with a binary mask, only valid non-mask pixels in both images are used during SSD calculation.
118  * @param image0 The image in which the first patch is located, must be valid
119  * @param image1 The image in which the second patch is located, must be valid
120  * @param mask0 The mask associated with the first image, must be valid
121  * @param mask1 The mask associated with the second image, must be valid
122  * @param width0 The width of the first image, in pixels, with range [patchSize / 2 + 1, infinity)
123  * @param height0 The height of the first image, in pixels, with range [patchSize / 2 + 1, infinity)
124  * @param width1 The width of the second image, in pixels, with range [patchSize / 2 + 1, infinity)
125  * @param height1 The height of the second image, in pixels, with range [patchSize / 2 + 1, infinity)
126  * @param centerX0 Horizontal sub-pixel center position of the (tPatchSize x tPatchSize) block in the first frame, with range (-infinity, infinity)
127  * @param centerY0 Vertical sub-pixel center position of the (tPatchSize x tPatchSize) block in the first frame, with range (-infinity, infinity)
128  * @param centerX1 Horizontal sub-pixel center position of the (tPatchSize x tPatchSize) block in the second frame, with range (-infinity, infinity)
129  * @param centerY1 Vertical sub-pixel center position of the (tPatchSize x tPatchSize) block in the second frame, with range (-infinity, infinity)
130  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
131  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
132  * @param mask0PaddingElements The number of padding elements at the end of each row of the first mask, in elements, with range [0, infinity)
133  * @param mask1PaddingElements The number of padding elements at the end of each row of the second mask, in elements, with range [0, infinity)
134  * @param maskValue The pixel value of a mask pixel which will be excluded when calculating the SSD, with range [0, 255]
135  * @return The resulting pair holding first: sum of square differences, second: number of pixels contributed to the result
136  * @tparam tChannels The number of data channels of the frames, with range [1, infinity)
137  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
138  */
139  template <unsigned int tChannels, unsigned int tPatchSize>
140  static IndexPair32 patchWithMask8BitPerChannelTemplate(const uint8_t* image0, const uint8_t* image1, const uint8_t* mask0, const uint8_t* mask1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, const Scalar centerX0, const Scalar centerY0, const Scalar centerX1, const Scalar centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue);
141 
142  /**
143  * Returns the sum of square differences between two square patches with sub-pixel accuracy.
144  * @param image0 The first image in which the first patch is located, must be valid
145  * @param image1 The second image in which the second patch is located, must be valid
146  * @param channels Specifies the number of channels for the given frames, with range [1, infinity)
147  * @param patchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
148  * @param width0 Width of the first frame in pixels, with range [patchSize + 1, infinity)
149  * @param width1 Width of the second frame in pixels, with range [patchSize, infinity)
150  * @param centerX0 Horizontal center position of the (patchSize x patchSize) block in the first frame, with range [patchSize/2, width - patchSize/2 - 1)
151  * @param centerY0 Vertical center position of the (patchSize x patchSize) block in the first frame, with range [patchSize/2, height - patchSize/2 - 1)
152  * @param centerX1 Horizontal center position of the (patchSize x patchSize) block in the second frame, with range [patchSize/2, width - patchSize/2 - 1)
153  * @param centerY1 Vertical center position of the (patchSize x patchSize) block in the second frame, with range [patchSize/2, height - patchSize/2 - 1)
154  * @param image0PaddingElements The number of padding elements at the end of each first image, in elements, with range [0, infinity)
155  * @param image1PaddingElements The number of padding elements at the end of each second image, in elements, with range [0, infinity)
156  * @return The resulting sum of square differences for `patchSize * patchSize * channels` elements
157  */
158  static uint32_t patch8BitPerChannel(const uint8_t* const image0, const uint8_t* const image1, const unsigned int channels, const unsigned int patchSize, 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);
159 
160  /**
161  * Returns the sum of square differences between two square patches, one with sub-pixel accuracy, one with pixel accuracy.
162  * @param image0 The first image in which the first patch is located, must be valid
163  * @param image1 The second image in which the second patch is located, must be valid
164  * @param channels Specifies the number of channels for the given frames, with range [1, infinity)
165  * @param patchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
166  * @param width0 Width of the first frame in pixels, with range [patchSize, infinity)
167  * @param width1 Width of the second frame in pixels, with range [patchSize + 1, infinity)
168  * @param centerX0 Horizontal center position of the (patchSize x patchSize) block in the first frame, with range [patchSize/2, width - patchSize/2)
169  * @param centerY0 Vertical center position of the (patchSize x patchSize) block in the first frame, with range [patchSize/2, height - patchSize/2)
170  * @param centerX1 Horizontal center position of the (patchSize x patchSize) block in the second frame, with range [patchSize/2, width - patchSize/2 - 1)
171  * @param centerY1 Vertical center position of the (patchSize x patchSize) block in the second frame, with range [patchSize/2, height - patchSize/2 - 1)
172  * @param image0PaddingElements The number of padding elements at the end of each first image, in elements, with range [0, infinity)
173  * @param image1PaddingElements The number of padding elements at the end of each second image, in elements, with range [0, infinity)
174  * @return The resulting sum of square differences for `patchSize * patchSize * channels` elements
175  */
176  static uint32_t patch8BitPerChannel(const uint8_t* const image0, const uint8_t* const image1, const unsigned int channels, const unsigned int patchSize, 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);
177 
178  /**
179  * Returns the sum of square differences between one sub-pixel image patch and a memory buffer.
180  * @param image0 The first image in which the first patch is located, must be valid
181  * @param channels Specifies the number of channels for the given frames, with range [1, infinity)
182  * @param patchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
183  * @param width0 Width of the first frame in pixels, with range [patchSize, infinity)
184  * @param centerX0 Horizontal center position of the (patchSize x patchSize) block in the first frame, with range [patchSize/2, width - patchSize/2 - 1)
185  * @param centerY0 Vertical center position of the (patchSize x patchSize) block in the first frame, with range [patchSize/2, height - patchSize/2 - 1)
186  * @param image0PaddingElements The number of padding elements at the end of each first image, in elements, with range [0, infinity)
187  * @param buffer1 The memory buffer with `tChannels * tPatchSize * tPatchSize` elements, must be valid
188  * @return The resulting sum of square differences for `patchSize * patchSize * channels` elements
189  */
190  static uint32_t patchBuffer8BitPerChannel(const uint8_t* const image0, const unsigned int channels, const unsigned int patchSize, const unsigned int width0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t* buffer1);
191 
192  /**
193  * Returns the sum of square differences for an image patch determined for two pixel accurate positions between two individual images.
194  * Further, each image is associated with a binary mask, only valid non-mask pixels are used during SSD calculation.
195  * @param image0 The image in which the first patch is located, must be valid
196  * @param image1 The image in which the second patch is located, must be valid
197  * @param mask0 The mask associated with the first image, must be valid
198  * @param mask1 The mask associated with the second image, must be valid
199  * @param channels The number of channels for the given frames, with range [1, infinity)
200  * @param patchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
201  * @param width0 The width of the first image, in pixels, with range [patchSize / 2 + 1, infinity)
202  * @param height0 The height of the first image, in pixels, with range [patchSize / 2 + 1, infinity)
203  * @param width1 The width of the second image, in pixels, with range [patchSize / 2 + 1, infinity)
204  * @param height1 The height of the second image, in pixels, with range [patchSize / 2 + 1, infinity)
205  * @param centerX0 Horizontal sub-pixel center position of the (tSize x tSize) block in the first frame, with range [0, width0 - 1]
206  * @param centerY0 Vertical sub-pixel center position of the (tSize x tSize) block in the first frame, with range [0, height0 - 1]
207  * @param centerX1 Horizontal sub-pixel center position of the (tSize x tSize) block in the second frame, with range [0, width1 - 1]
208  * @param centerY1 Vertical sub-pixel center position of the (tSize x tSize) block in the second frame, with range [0, height1 - 1]
209  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
210  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
211  * @param mask0PaddingElements The number of padding elements at the end of each row of the first mask, in elements, with range [0, infinity)
212  * @param mask1PaddingElements The number of padding elements at the end of each row of the second mask, in elements, with range [0, infinity)
213  * @param maskValue The pixel value of a mask pixel which will be excluded when calculating the SSD, with range [0, 255]
214  * @return The resulting pair holding first: sum of square differences, second: number of pixels contributed to the result
215  */
216  static IndexPair32 patchWithMask8BitPerChannel(const uint8_t* image0, const uint8_t* image1, const uint8_t* mask0, const uint8_t* mask1, const unsigned int channels, const unsigned int patchSize, 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, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue);
217 
218  /**
219  * Returns the sum of square differences for an image patch determined for two pixel accurate positions between two individual images .
220  * Further, each image is associated with a binary mask, only valid non-mask pixels in the first image are used during SSD calculation.
221  * If a valid (mask) pixel in the first image does not have a valid (mask) pixel in the second frame, -1 is returned as SSD value.
222  * @param image0 The image in which the first patch is located, must be valid
223  * @param image1 The image in which the second patch is located, must be valid
224  * @param mask0 The mask associated with the first image, must be valid
225  * @param mask1 The mask associated with the second image, must be valid
226  * @param channels The number of channels for the given frames, with range [1, infinity)
227  * @param patchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
228  * @param width0 The width of the first image, in pixels, with range [patchSize / 2 + 1, infinity)
229  * @param height0 The height of the first image, in pixels, with range [patchSize / 2 + 1, infinity)
230  * @param width1 The width of the second image, in pixels, with range [patchSize / 2 + 1, infinity)
231  * @param height1 The height of the second image, in pixels, with range [patchSize / 2 + 1, infinity)
232  * @param centerX0 Horizontal sub-pixel center position of the (tSize x tSize) block in the first frame, with range [0, width0 - 1]
233  * @param centerY0 Vertical sub-pixel center position of the (tSize x tSize) block in the first frame, with range [0, height0 - 1]
234  * @param centerX1 Horizontal sub-pixel center position of the (tSize x tSize) block in the second frame, with range [0, width1 - 1]
235  * @param centerY1 Vertical sub-pixel center position of the (tSize x tSize) block in the second frame, with range [0, height1 - 1]
236  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
237  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
238  * @param mask0PaddingElements The number of padding elements at the end of each row of the first mask, in elements, with range [0, infinity)
239  * @param mask1PaddingElements The number of padding elements at the end of each row of the second mask, in elements, with range [0, infinity)
240  * @param maskValue The pixel value of a mask pixel which will be excluded when calculating the SSD, with range [0, 255]
241  * @return The resulting pair holding first: sum of square differences, second: number of pixels contributed to the result
242  */
243  static IndexPair32 patchWithRejectingMask8BitPerChannel(const uint8_t* image0, const uint8_t* image1, const uint8_t* mask0, const uint8_t* mask1, const unsigned int channels, const unsigned int patchSize, 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, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue);
244 };
245 
246 template <unsigned int tChannels, unsigned int tPatchSize>
247 uint32_t AdvancedSumSquareDifferencesBase::patch8BitPerChannelTemplate(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)
248 {
249  static_assert(tChannels != 0u, "Invalid number of frame channels!");
250  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid image patch size, must be odd!");
251 
252  ocean_assert(image0 != nullptr && image1 != nullptr);
253 
254  ocean_assert(width0 >= tPatchSize + 1u);
255  ocean_assert(width1 >= tPatchSize + 1u);
256 
257  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
258 
259  ocean_assert(centerX0 >= Scalar(tPatchSize_2) && centerX0 < Scalar(width0 - tPatchSize_2 - 1u));
260  ocean_assert_and_suppress_unused(centerY0 >= Scalar(tPatchSize_2), tPatchSize_2);
261 
262  ocean_assert(centerX1 >= Scalar(tPatchSize_2) && centerX1 < Scalar(width1 - tPatchSize_2 - 1u));
263  ocean_assert(centerY1 >= Scalar(tPatchSize_2));
264 
265  constexpr unsigned int tPatchElements = tPatchSize * tPatchSize * tChannels;
266 
267  uint8_t target[tPatchElements * 2u];
268 
269  AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize>(image0, width0, image0PaddingElements, target, Vector2(centerX0, centerY0));
270  AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize>(image1, width1, image1PaddingElements, target + tPatchElements, Vector2(centerX1, centerY1));
271 
272  return SumSquareDifferences::buffer8BitPerChannelTemplate<tPatchElements>(target, target + tPatchElements);
273 }
274 
275 template <unsigned int tChannels, unsigned int tPatchSize>
276 inline uint32_t AdvancedSumSquareDifferencesBase::patch8BitPerChannelTemplate(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)
277 {
278  static_assert(tChannels != 0u, "Invalid number of frame channels!");
279  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid image patch size, must be odd!");
280 
281  ocean_assert(image0 != nullptr && image1 != nullptr);
282 
283  ocean_assert(width0 >= tPatchSize);
284  ocean_assert(width1 >= tPatchSize + 1u);
285 
286  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
287 
288  ocean_assert(centerX0 >= tPatchSize_2 && centerX0 < width0 - tPatchSize_2);
289  ocean_assert_and_suppress_unused(centerY0 >= tPatchSize_2, tPatchSize_2);
290 
291  ocean_assert(centerX1 >= Scalar(tPatchSize_2) && centerX1 < Scalar(width1 - tPatchSize_2 - 1u));
292  ocean_assert(centerY1 >= Scalar(tPatchSize_2));
293 
294  constexpr unsigned int tPatchPixels = tPatchSize * tPatchSize;
295 
296  constexpr unsigned int tPatchElements = tPatchPixels * tChannels;
297 
298  uint8_t target[tPatchElements * 2u];
299 
300  constexpr unsigned int targetPaddingElements = 0u;
301 
302  CV::FrameConverter::patchFrame<uint8_t>(image0, target, width0, tChannels, centerX0, centerY0, tPatchSize, image0PaddingElements, targetPaddingElements);
303  AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize>(image1, width1, image1PaddingElements, target + tPatchElements, Vector2(centerX1, centerY1));
304 
305  return SumSquareDifferences::buffer8BitPerChannel<tChannels, tPatchPixels>(target, target + tPatchElements);
306 }
307 
308 template <unsigned int tChannels, unsigned int tPatchSize>
309 inline uint32_t AdvancedSumSquareDifferencesBase::patchBuffer8BitPerChannelTemplate(const uint8_t* image0, const unsigned int width0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t* buffer1)
310 {
311  static_assert(tChannels != 0u, "Invalid number of image channels!");
312  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid patch size!");
313 
314  ocean_assert(image0 != nullptr && buffer1 != nullptr);
315 
316  ocean_assert(width0 >= tPatchSize + 1u);
317 
318  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
319 
320  ocean_assert_and_suppress_unused(centerX0 >= Scalar(tPatchSize_2) && centerX0 < Scalar(width0 - tPatchSize_2 - 1u), tPatchSize_2);
321 
322  constexpr unsigned int tPatchPixels = tPatchSize * tPatchSize;
323 
324  uint8_t target[tPatchPixels * tChannels];
325  AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize>(image0, width0, image0PaddingElements, target, Vector2(centerX0, centerY0));
326  return SumSquareDifferences::buffer8BitPerChannel<tChannels, tPatchPixels>(target, buffer1);
327 }
328 
329 template <unsigned int tChannels, unsigned int tPatchSize>
330 IndexPair32 AdvancedSumSquareDifferencesBase::patchWithMask8BitPerChannelTemplate(const uint8_t* image0, const uint8_t* image1, const uint8_t* mask0, const uint8_t* mask1, 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, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue)
331 {
332  static_assert(tChannels >= 1u, "Invalid channel number!");
333  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid patch size!");
334 
335  ocean_assert(image0 != nullptr && image1 != nullptr);
336  ocean_assert(mask0 != nullptr && mask1 != nullptr);
337 
338  const unsigned int patchSize_2 = tPatchSize / 2u;
339 
340  ocean_assert(width0 >= patchSize_2 + 1u && height0 >= patchSize_2 + 1u);
341  ocean_assert(width1 >= patchSize_2 + 1u && height1 >= patchSize_2 + 1u);
342 
343  ocean_assert(centerX0 < width0 && centerY0 < height0);
344  ocean_assert(centerX1 < width1 && centerY1 < height1);
345 
346  const unsigned int image0StrideElements = width0 * tChannels + image0PaddingElements;
347  const unsigned int image1StrideElements = width1 * tChannels + image1PaddingElements;
348 
349  const unsigned int mask0StrideElements = width0 + mask0PaddingElements;
350  const unsigned int mask1StrideElements = width1 + mask1PaddingElements;
351 
352  const unsigned int offsetLeft = std::min(std::min(centerX0, patchSize_2), std::min(centerX1, patchSize_2));
353  const unsigned int offsetTop = std::min(std::min(centerY0, patchSize_2), std::min(centerY1, patchSize_2));
354 
355  const unsigned int offsetRight = std::min(std::min(width0 - centerX0 - 1u, patchSize_2), std::min(width1 - centerX1 - 1u, patchSize_2));
356  const unsigned int offsetBottom = std::min(std::min(height0 - centerY0 - 1u, patchSize_2), std::min(height1 - centerY1 - 1u, patchSize_2));
357 
358  ocean_assert(offsetLeft <= patchSize_2 && offsetRight <= patchSize_2);
359  ocean_assert(offsetTop <= patchSize_2 && offsetTop <= patchSize_2);
360 
361  ocean_assert(offsetLeft <= centerX0 && offsetTop <= centerY0);
362  ocean_assert(offsetTop <= centerY1 && offsetTop <= centerY1);
363 
364  ocean_assert(centerX0 + offsetRight < width0 && centerY0 + offsetBottom < height0);
365  ocean_assert(centerX1 + offsetRight < width1 && centerY1 + offsetBottom < height1);
366 
367  const unsigned int patchWidth = offsetLeft + offsetRight + 1u;
368  const unsigned int patchHeight = offsetTop + offsetBottom + 1u;
369 
370  ocean_assert(patchWidth <= tPatchSize && patchHeight <= tPatchSize);
371 
372  image0 += (centerY0 - offsetTop) * image0StrideElements + (centerX0 - offsetLeft) * tChannels;
373  image1 += (centerY1 - offsetTop) * image1StrideElements + (centerX1 - offsetLeft) * tChannels;
374 
375  mask0 += (centerY0 - offsetTop) * mask0StrideElements + (centerX0 - offsetLeft);
376  mask1 += (centerY1 - offsetTop) * mask1StrideElements + (centerX1 - offsetLeft);
377 
378  uint32_t validPixels = 0u;
379  uint32_t ssd = 0u;
380 
381  for (unsigned int y = 0u; y < patchHeight; ++y)
382  {
383  for (unsigned int x = 0u; x < patchWidth; ++x)
384  {
385  if (mask0[x] != maskValue && mask1[x] != maskValue)
386  {
387  for (unsigned int n = 0u; n < tChannels; ++n)
388  {
389  ssd += sqr(image0[tChannels * x + n] - image1[tChannels * x + n]);
390  }
391 
392  ++validPixels;
393  }
394  }
395 
396  image0 += image0StrideElements;
397  image1 += image1StrideElements;
398 
399  mask0 += mask0StrideElements;
400  mask1 += mask1StrideElements;
401  }
402 
403  return IndexPair32(ssd, validPixels);
404 }
405 
406 template <unsigned int tChannels, unsigned int tPatchSize>
407 inline IndexPair32 AdvancedSumSquareDifferencesBase::patchWithMask8BitPerChannelTemplate(const uint8_t* image0, const uint8_t* image1, const uint8_t* mask0, const uint8_t* mask1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, const Scalar centerX0, const Scalar centerY0, const Scalar centerX1, const Scalar centerY1, const unsigned int image0PaddingElements, const unsigned int image1PaddingElements, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue)
408 {
409  static_assert(tChannels != 0u, "Invalid number of frame channels!");
410 
411  ocean_assert(image0 != nullptr && image1 != nullptr);
412  ocean_assert(mask0 != nullptr && mask1 != nullptr);
413 
414  uint8_t patchBuffers[tPatchSize * tPatchSize * tChannels * 2u];
415  uint8_t maskBuffers[tPatchSize * tPatchSize * 2u];
416 
417  uint8_t* patchBuffer0 = patchBuffers;
418  uint8_t* patchBuffer1 = patchBuffers + tPatchSize * tPatchSize * tChannels;
419 
420  uint8_t* maskBuffer0 = maskBuffers;
421  uint8_t* maskBuffer1 = maskBuffers + tPatchSize * tPatchSize;
422 
423  constexpr unsigned int patchBuffer0PaddingElements = 0u;
424  constexpr unsigned int patchBuffer1PaddingElements = 0u;
425 
426  constexpr unsigned int maskBuffer0PaddingElements = 0u;
427  constexpr unsigned int maskBuffer1PaddingElements = 0u;
428 
429  const uint8_t validMaskValue = 0xFFu - maskValue;
430 
431  AdvancedFrameInterpolatorBilinear::interpolatePatchWithMask8BitPerChannel<tChannels, PC_CENTER>(image0, mask0, width0, height0, image0PaddingElements, mask0PaddingElements, Vector2(centerX0, centerY0), patchBuffer0, maskBuffer0, tPatchSize, tPatchSize, patchBuffer0PaddingElements, maskBuffer0PaddingElements, validMaskValue);
432  AdvancedFrameInterpolatorBilinear::interpolatePatchWithMask8BitPerChannel<tChannels, PC_CENTER>(image1, mask1, width1, height1, image1PaddingElements, mask1PaddingElements, Vector2(centerX1, centerY1), patchBuffer1, maskBuffer1, tPatchSize, tPatchSize, patchBuffer1PaddingElements, maskBuffer1PaddingElements, validMaskValue);
433 
434  uint32_t ssd = 0u;
435  uint32_t validPixels = 0u;
436 
437  for (unsigned int y = 0u; y < tPatchSize; ++y)
438  {
439  for (unsigned int x = 0u; x < tPatchSize; ++x)
440  {
441  if (*maskBuffer0 == validMaskValue && *maskBuffer1 == validMaskValue)
442  {
443  for (unsigned int n = 0u; n < tChannels; ++n)
444  {
445  ssd += sqrDistance(patchBuffer0[n], patchBuffer1[n]);
446  }
447 
448  ++validPixels;
449  }
450 
451  patchBuffer0 += tChannels;
452  patchBuffer1 += tChannels;
453 
454  ++maskBuffer0;
455  ++maskBuffer1;
456  }
457  }
458 
459  return IndexPair32(ssd, validPixels);
460 }
461 
462 }
463 
464 }
465 
466 }
467 
468 #endif // META_OCEAN_CV_ADVANCED_ADVANCED_SUM_SQUARE_DIFFERENCES_TEMPLATE_H
This class implements functions calculating the sum of square differences and omit center pixel.
Definition: AdvancedSumSquareDifferencesBase.h:32
static uint32_t patch8BitPerChannel(const uint8_t *const image0, const uint8_t *const image1, const unsigned int channels, const unsigned int patchSize, 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)
Returns the sum of square differences between two square patches, one with sub-pixel accuracy,...
static IndexPair32 patchWithMask8BitPerChannel(const uint8_t *image0, const uint8_t *image1, const uint8_t *mask0, const uint8_t *mask1, const unsigned int channels, const unsigned int patchSize, 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, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue)
Returns the sum of square differences for an image patch determined for two pixel accurate positions ...
static uint32_t patch8BitPerChannelTemplate(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 determined between two individual images.
Definition: AdvancedSumSquareDifferencesBase.h:247
static IndexPair32 patchWithMask8BitPerChannelTemplate(const uint8_t *image0, const uint8_t *image1, const uint8_t *mask0, const uint8_t *mask1, 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, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue)
Returns the sum of square differences for an image patch determined for two pixel accurate positions ...
Definition: AdvancedSumSquareDifferencesBase.h:330
static IndexPair32 patchWithRejectingMask8BitPerChannel(const uint8_t *image0, const uint8_t *image1, const uint8_t *mask0, const uint8_t *mask1, const unsigned int channels, const unsigned int patchSize, 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, const unsigned int mask0PaddingElements, const unsigned int mask1PaddingElements, const uint8_t maskValue)
Returns the sum of square differences for an image patch determined for two pixel accurate positions ...
static uint32_t patchBuffer8BitPerChannelTemplate(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: AdvancedSumSquareDifferencesBase.h:309
static uint32_t patchBuffer8BitPerChannel(const uint8_t *const image0, const unsigned int channels, const unsigned int patchSize, const unsigned int width0, const Scalar centerX0, const Scalar centerY0, const unsigned int image0PaddingElements, const uint8_t *buffer1)
Returns the sum of square differences between one sub-pixel image patch and a memory buffer.
static uint32_t patch8BitPerChannel(const uint8_t *const image0, const uint8_t *const image1, const unsigned int channels, const unsigned int patchSize, 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 between two square patches with sub-pixel accuracy.
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition: base/Utilities.h:1089
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition: base/Utilities.h:1029
std::pair< Index32, Index32 > IndexPair32
Definition of a pair holding 32 bit indices.
Definition: Base.h:138
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