Ocean
AdvancedZeroMeanSumSquareDifferencesBase.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_BASE_H
9 #define META_OCEAN_CV_ADVANCED_ADVANCED_ZERO_MEAN_SUM_SQUARE_DIFFERENCES_BASE_H
10 
14 
16 
17 namespace Ocean
18 {
19 
20 namespace CV
21 {
22 
23 namespace Advanced
24 {
25 
26 /**
27  * This class implements functions calculating the zero-mean sum of square differences.
28  * @ingroup cvadvanced
29  */
31 {
32  public:
33 
34  /**
35  * Returns the sum of square differences for an image patch determined between two individual images.
36  * @param image0 The image in which the first patch is located, must be valid
37  * @param image1 The image in which the second patch is located, must be valid
38  * @param width0 The width of the first image, in pixels, with range [tPatchSize + 1, infinity)
39  * @param width1 The width of the second image, in pixels, with range [tPatchSize + 1, infinity)
40  * @param centerX0 Horizontal center position of the (tSize x tSize) block in the first frame, with range [tPatchSize/2, width - tPatchSize/2 - 1)
41  * @param centerY0 Vertical center position of the (tSize x tSize) block in the first frame, with range [tPatchSize/2, height - tPatchSize/2 - 1)
42  * @param centerX1 Horizontal center position of the (tSize x tSize) block in the second frame, with range [tPatchSize/2, width - tPatchSize/2 - 1)
43  * @param centerY1 Vertical center position of the (tSize x tSize) block in the second frame, with range [tPatchSize/2, height - tPatchSize/2 - 1)
44  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
45  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
46  * @return The resulting sum of square differences, with range [0, infinity)
47  * @tparam tChannels The number of frame channels, with range [1, infinity)
48  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
49  */
50  template <unsigned int tChannels, unsigned int tPatchSize>
51  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);
52 
53  /**
54  * Returns the sum of square differences for an image patch determined between two individual images.
55  * @param image0 The image in which the first patch is located, must be valid
56  * @param image1 The image in which the second patch is located, must be valid
57  * @param width0 The width of the first image, in pixels, with range [tPatchSize + 1, infinity)
58  * @param width1 The width of the second image, in pixels, with range [tPatchSize + 1, infinity)
59  * @param centerX0 Horizontal center position of the (tSize x tSize) block in the first frame, with range [tPatchSize/2, width - tPatchSize/2)
60  * @param centerY0 Vertical center position of the (tSize x tSize) block in the first frame, with range [tPatchSize/2, height - tPatchSize/2)
61  * @param centerX1 Horizontal center position of the (tSize x tSize) block in the second frame, with range [tPatchSize/2, width - tPatchSize/2 - 1)
62  * @param centerY1 Vertical center position of the (tSize x tSize) block in the second frame, with range [tPatchSize/2, height - tPatchSize/2 - 1)
63  * @param image0PaddingElements The number of padding elements at the end of each row of the first image, in elements, with range [0, infinity)
64  * @param image1PaddingElements The number of padding elements at the end of each row of the second image, in elements, with range [0, infinity)
65  * @return The resulting sum of square differences, with range [0, infinity)
66  * @tparam tChannels The number of frame channels, with range [1, infinity)
67  * @tparam tPatchSize The size of the square patch (the edge length) in pixel, with range [1, infinity), must be odd
68  */
69  template <unsigned int tChannels, unsigned int tPatchSize>
70  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);
71 
72  /**
73  * Determines the partial zero-mean ssd of two image patches between two frames while for each frame a binary mask specifies whether a pixel is valid or skipped.
74  * Only pixels with two corresponding mask pixels in both frames are used for mean and ssd calculation.<br>
75  * Further, the size of the image patch may be arbitrary (even or odd) and parts of the patch may lie outside the frames (as long as one pixel lies inside each frame).<br>
76  * Beware: The patch coordinate is not determined by the center position but by the upper left position of the patch (as the patch may have even dimensions).<br>
77  * @param frame0 The first frame for ssd determination
78  * @param frame1 The second frame for ssd determination
79  * @param mask0 The 8 bit binary mask corresponding to the first frame (with same dimension), pixels not equal to 0x00 are valid in frame0
80  * @param mask1 The 8 bit binary mask corresponding to the second frame (with same dimension), pixels not equal to 0x00 are valid in frame1
81  * @param width0 The width of the first frame in pixel, with range [1, infinity)
82  * @param height0 The height of the first frame in pixel, with range [1, infinity)
83  * @param width1 The width of the second frame in pixel, with range [1, infinity)
84  * @param height1 The height of the second frame in pixel, with range [1, infinity)
85  * @param sizeX The width of the patch in pixel, with range [1, infinity)
86  * @param sizeY The height of the patch in pixel, with range [1, infinity)
87  * @param left0 The left position of the patch in the first frame, with range [-sizeX + 1, width0)
88  * @param top0 The top position of the patch in the first frame, with range[-sizeY + 1, height0)
89  * @param left1 The left position of the patch in the second frame, with range [-sizeX + 1, width1)
90  * @param top1 The top position of the patch in the second frame, with range [-sizeY + 1, height0),
91  * @return A pair holding the resulting ssd in the first parameter, and the number of valid pixels (that have been used to determined the ssd) in the second parameter
92  * @tparam tChannels The number of data channels of the frames
93  */
94  template <unsigned int tChannels>
95  static inline IndexPair32 determine8BitPerChannelPartialTemplate(const uint8_t* frame0, const uint8_t* frame1, const uint8_t* mask0, const uint8_t* mask1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, unsigned int sizeX, unsigned int sizeY, const int left0, const int top0, const int left1, const int top1);
96 
97  protected:
98 
99  /**
100  * Determines the mean values of given image patch with arbitrary sizes while a binary mask specifies whether a pixel is valid or skipped.
101  * A pixel is valid if the pixel is a non-mask pixels and lies inside the frame.
102  * @param frame The frame in which the mean values are determined
103  * @param mask The 8 bit binary mask defining whether a pixel is valid or skipped, 0x00 specifies a mask pixel
104  * @param width The width of the given frame (and the mask) in pixel, with range [1, infinity)
105  * @param height The height of the given frame (and the mask) in pixel, with range [1, infinity)
106  * @param sizeX The width of the patch in pixel, with range [1, infinity)
107  * @param sizeY The height of the patch in pixel, with range [1, infinity)
108  * @param left The left position of the patch in the frame, with range [-sizeX + 1, width)
109  * @param top The top position of the patch in the frame, with range[-sizeY + 1, height)
110  * @param sums The resulting sum values, individual for each frame channel
111  * @return The number of valid pixels
112  */
113  template <unsigned int tChannels>
114  static inline unsigned int sum8BitPerChannelPartialTemplate(const uint8_t* frame, const uint8_t* mask, const unsigned int width, const unsigned int height, const unsigned int sizeX, const unsigned int sizeY, const int left, const int top, unsigned int sums[tChannels]);
115 
116  /**
117  * Determines the mean values for two given image patches in two individual frames with arbitrary sizes while two binary masks specifies whether a pixel is valid or skipped.
118  * A pixel is valid if in both patches the corresponding pixel is a non-mask pixels and lies inside both frames.<br>
119  * @param frame0 The first frame in which the first mean values are determined
120  * @param frame1 The second frame in which the second mean values are determined
121  * @param mask0 The first 8 bit binary mask defining whether a pixel is valid or skipped in the first frame, 0x00 specifies a mask pixel
122  * @param mask1 The second 8 bit binary mask defining whether a pixel is valid or skipped in the second frame, 0x00 specifies a mask pixel
123  * @param width0 Width of the first frame (and the first mask) in pixel, with range [1, infinity)
124  * @param height0 Height of the first frame (and the first mask) in pixel, with range [1, infinity)
125  * @param width1 Width of the second frame (and the second mask) in pixel, with range [1, infinity)
126  * @param height1 Height of the second frame (and the second mask) in pixel, with range [1, infinity)
127  * @param sizeX The width of the patch in pixel, with range [1, infinity)
128  * @param sizeY The height of the patch in pixel, with range [1, infinity)
129  * @param left0 The left position of the patch in the first frame, with range [-sizeX + 1, width0)
130  * @param top0 The top position of the patch in the first frame, with range[-sizeY + 1, height0)
131  * @param left1 The left position of the patch in the second frame, with range [-sizeX + 1, width1)
132  * @param top1 The top position of the patch in the second frame, with range[-sizeY + 1, height1)
133  * @param sums0 The resulting sum values from the first frame, individual for each frame channel
134  * @param sums1 The resulting sum values from the second frame, individual for each frame channel
135  * @return The number of valid pixels
136  */
137  template <unsigned int tChannels>
138  static inline unsigned int sum8BitPerChannelPartialTemplate(const uint8_t* frame0, const uint8_t* frame1, const uint8_t* mask0, const uint8_t* mask1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, unsigned int sizeX, unsigned int sizeY, const int left0, const int top0, const int left1, const int top1, unsigned int sums0[tChannels], unsigned int sums1[tChannels]);
139 };
140 
141 template <unsigned int tChannels, unsigned int tPatchSize>
142 inline uint32_t AdvancedZeroMeanSumSquareDifferencesBase::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)
143 {
144  static_assert(tChannels != 0u, "Invalid number of frame channels!");
145  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid image patch size, must be odd!");
146 
147  ocean_assert(image0 != nullptr && image1 != nullptr);
148 
149  ocean_assert(width0 >= tPatchSize + 1u);
150  ocean_assert(width1 >= tPatchSize + 1u);
151 
152  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
153 
154  ocean_assert(centerX0 >= Scalar(tPatchSize_2) && centerX0 < Scalar(width0 - tPatchSize_2 - 1u));
155  ocean_assert_and_suppress_unused(centerY0 >= Scalar(tPatchSize_2), tPatchSize_2);
156 
157  ocean_assert(centerX1 >= Scalar(tPatchSize_2) && centerX1 < Scalar(width1 - tPatchSize_2 - 1u));
158  ocean_assert(centerY1 >= Scalar(tPatchSize_2));
159 
160  constexpr unsigned int tPatchPixels = tPatchSize * tPatchSize;
161  constexpr unsigned int tPatchElements = tPatchPixels * tChannels;
162 
163  uint8_t target[tPatchElements * 2u];
164 
165  AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize>(image0, width0, image0PaddingElements, target, Vector2(centerX0, centerY0));
166  AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize>(image1, width1, image1PaddingElements, target + tPatchElements, Vector2(centerX1, centerY1));
167 
168  return ZeroMeanSumSquareDifferences::buffer8BitPerChannel<tChannels, tPatchPixels>(target, target + tPatchElements);
169 }
170 
171 template <unsigned int tChannels, unsigned int tPatchSize>
172 inline uint32_t AdvancedZeroMeanSumSquareDifferencesBase::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)
173 {
174  static_assert(tChannels != 0u, "Invalid number of frame channels!");
175  static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u, "Invalid image patch size, must be odd!");
176 
177  ocean_assert(image0 != nullptr && image1 != nullptr);
178 
179  ocean_assert(width0 >= tPatchSize);
180  ocean_assert(width1 >= tPatchSize + 1u);
181 
182  constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
183 
184  ocean_assert(centerX0 >= tPatchSize_2 && centerX0 < width0 - tPatchSize_2);
185  ocean_assert_and_suppress_unused(centerY0 >= tPatchSize_2, tPatchSize_2);
186 
187  ocean_assert(centerX1 >= Scalar(tPatchSize_2) && centerX1 < Scalar(width1 - tPatchSize_2 - 1u));
188  ocean_assert(centerY1 >= Scalar(tPatchSize_2));
189 
190  constexpr unsigned int tPatchPixels = tPatchSize * tPatchSize;
191  constexpr unsigned int tPatchElements = tPatchPixels * tChannels;
192 
193  uint8_t target[tPatchElements * 2u];
194 
195  constexpr unsigned int targetPaddingElements = 0u;
196 
197  CV::FrameConverter::patchFrame(image0, target, width0, tChannels, centerX0, centerY0, tPatchSize, image0PaddingElements, targetPaddingElements);
198  AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize>(image1, width1, image1PaddingElements, target + tPatchElements, Vector2(centerX1, centerY1));
199 
200  return ZeroMeanSumSquareDifferences::buffer8BitPerChannel<tChannels, tPatchPixels>(target, target + tPatchElements);
201 }
202 
203 template <unsigned int tChannels>
204 inline IndexPair32 AdvancedZeroMeanSumSquareDifferencesBase::determine8BitPerChannelPartialTemplate(const uint8_t* frame0, const uint8_t* frame1, 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 sizeX, const unsigned int sizeY, const int left0, const int top0, const int left1, const int top1)
205 {
206  static_assert(tChannels != 0u, "Invalid number of frame channels!");
207 
208  ocean_assert(frame0 && frame1);
209  ocean_assert(mask0 && mask1);
210 
211  ocean_assert(sizeX >= 1u && sizeY >= 1u);
212  ocean_assert(width0 >= sizeX && width1 >= sizeX);
213  ocean_assert(height0 >= sizeY && height1 >= sizeY);
214 
215  ocean_assert(left0 >= -int(sizeX) + 1 && left0 < int(width0));
216  ocean_assert(top0 >= -int(sizeY) + 1 && top0 < int(height0));
217  ocean_assert(left1 >= -int(sizeX) + 1 && left1 < int(width1));
218  ocean_assert(top1 >= -int(sizeY) + 1 && top1 < int(height1));
219 
220  const int patchLeftBorder = max(0, max(-left0, -left1));
221  const int patchTopBorder = max(0, max(-top0, -top1));
222 
223  const int patchRightBorder = max(0, max(left0 + int(sizeX) - int(width0), left1 + int(sizeX) - int(width1)));
224  const int patchBottomBorder = max(0, max(top0 + int(sizeY) - int(height0), top1 + int(sizeY) - int(height1)));
225 
226  ocean_assert(patchLeftBorder >= 0 && patchLeftBorder < int(sizeX));
227  ocean_assert(patchTopBorder >= 0 && patchTopBorder < int(sizeY));
228  ocean_assert(patchRightBorder >= 0 && patchRightBorder < int(sizeX));
229  ocean_assert(patchBottomBorder >= 0 && patchBottomBorder < int(sizeY));
230 
231  const int pLeft0 = left0 + patchLeftBorder;
232  const int pLeft1 = left1 + patchLeftBorder;
233 
234  const int pTop0 = top0 + patchTopBorder;
235  const int pTop1 = top1 + patchTopBorder;
236 
237  const unsigned int pSizeX = sizeX - patchLeftBorder - patchRightBorder;
238  const unsigned int pSizeY = sizeY - patchTopBorder - patchBottomBorder;
239 
240  if (pSizeX > sizeX || pSizeY > sizeY)
241  {
242  return IndexPair32(0u, 0u);
243  }
244 
245  unsigned int means0[tChannels] = {0u};
246  unsigned int means1[tChannels] = {0u};
247 
248  const unsigned int pixels = sum8BitPerChannelPartialTemplate<tChannels>(frame0, frame1, mask0, mask1, width0, height0, width1, height1, sizeX, sizeY, left0, top0, left1, top1, means0, means1);
249 
250  if (pixels == 0u)
251  {
252  return IndexPair32(0u, 0u);
253  }
254 
255  int means1_0[tChannels];
256 
257  for (unsigned int n = 0u; n < tChannels; ++n)
258  means1_0[n] = int((means1[n] + (pixels / 2u)) / pixels) - int((means0[n] + (pixels / 2u)) / pixels);
259 
260  unsigned int ssd = 0u;
261 
262  frame0 += (pTop0 * int(width0) + pLeft0) * int(tChannels);
263  frame1 += (pTop1 * int(width1) + pLeft1) * int(tChannels);
264 
265  mask0 += (pTop0 * int(width0) + pLeft0);
266  mask1 += (pTop1 * int(width1) + pLeft1);
267 
268  const uint8_t* const mask0End = mask0 + pSizeY * width0;
269 
270  while (mask0 != mask0End)
271  {
272  ocean_assert(mask0 < mask0End);
273 
274  const uint8_t* const mask0RowEnd = mask0 + pSizeX;
275 
276  while (mask0 != mask0RowEnd)
277  {
278  ocean_assert(mask0 < mask0End);
279  ocean_assert(mask0 < mask0RowEnd);
280 
281  const unsigned int factor = (*mask0 * *mask1) != 0u;
282 
283  for (unsigned int n = 0u; n < tChannels; ++n)
284  ssd += sqr(int(frame0[n]) - int(frame1[n]) + means1_0[n]) * factor;
285 
286  frame0 += tChannels;
287  frame1 += tChannels;
288 
289  mask0++;
290  mask1++;
291  }
292 
293  frame0 += (width0 - pSizeX) * tChannels;
294  frame1 += (width1 - pSizeX) * tChannels;
295 
296  mask0 += (width0 - pSizeX);
297  mask1 += (width1 - pSizeX);
298  }
299 
300  return std::make_pair(ssd, pixels);
301 }
302 
303 template <unsigned int tChannels>
304 inline unsigned int AdvancedZeroMeanSumSquareDifferencesBase::sum8BitPerChannelPartialTemplate(const uint8_t* frame, const uint8_t* mask, const unsigned int width, const unsigned int height, const unsigned int sizeX, const unsigned int sizeY, const int left, const int top, unsigned int sums[tChannels])
305 {
306  static_assert(tChannels != 0u, "Invalid number of frame channels!");
307 
308  ocean_assert(frame && mask);
309  ocean_assert(width >= 1u && height >= 1u);
310  ocean_assert(sizeX >= 1u && sizeY >= 1u);
311 
312  ocean_assert(width >= sizeX && height >= sizeY);
313  ocean_assert(left >= -int(sizeX) + 1 && left < int(width));
314  ocean_assert(top >= -int(sizeY) + 1 && top < int(height));
315 
316  const int patchLeftBorder = max(0, -left);
317  const int patchTopBorder = max(0, -top);
318 
319  const int patchRightBorder = max(0, left + int(sizeX) - int(width));
320  const int patchBottomBorder = max(0, top + int(sizeY) - int(height));
321 
322  ocean_assert(patchLeftBorder >= 0 && patchLeftBorder < int(sizeX));
323  ocean_assert(patchTopBorder >= 0 && patchTopBorder < int(sizeY));
324  ocean_assert(patchRightBorder >= 0 && patchRightBorder < int(sizeX));
325  ocean_assert(patchBottomBorder >= 0 && patchBottomBorder < int(sizeY));
326 
327  const int pLeft = left + patchLeftBorder;
328  const int pTop = top + patchTopBorder;
329 
330  const unsigned int pSizeX = sizeX - patchLeftBorder - patchRightBorder;
331  const unsigned int pSizeY = sizeY - patchTopBorder - patchBottomBorder;
332 
333  if (pSizeX > sizeX || pSizeY > sizeY)
334  return 0u;
335 
336  unsigned int pixels = 0u;
337 
338  for (unsigned int n = 0u; n < tChannels; ++n)
339  sums[n] = 0u;
340 
341  frame += (pTop * int(width) + pLeft) * int(tChannels);
342  mask += (pTop * int(width) + pLeft);
343 
344  const uint8_t* const maskEnd = mask + pSizeY * width;
345 
346  while (mask != maskEnd)
347  {
348  ocean_assert(mask < maskEnd);
349 
350  const uint8_t* const maskRowEnd = mask + pSizeX;
351 
352  while (mask != maskRowEnd)
353  {
354  ocean_assert(mask < maskEnd);
355  ocean_assert(mask < maskRowEnd);
356 
357  const unsigned int factor = *mask != 0u;
358 
359  for (unsigned int n = 0u; n < tChannels; ++n)
360  sums[n] += frame[n] * factor;
361 
362  pixels += factor;
363 
364  frame += tChannels;
365  mask++;
366  }
367 
368  frame += int(width - pSizeX) * int(tChannels);
369  mask += int(width - pSizeX);
370  }
371 
372  return pixels;
373 }
374 
375 template <unsigned int tChannels>
376 inline unsigned int AdvancedZeroMeanSumSquareDifferencesBase::sum8BitPerChannelPartialTemplate(const uint8_t* frame0, const uint8_t* frame1, const uint8_t* mask0, const uint8_t* mask1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, unsigned int sizeX, unsigned int sizeY, const int left0, const int top0, const int left1, const int top1, unsigned int sums0[tChannels], unsigned int sums1[tChannels])
377 {
378  static_assert(tChannels != 0u, "Invalid number of frame channels!");
379 
380  ocean_assert(frame0 && frame1);
381  ocean_assert(mask0 && mask1);
382 
383  ocean_assert(sizeX >= 1u && sizeY >= 1u);
384  ocean_assert(width0 >= sizeX && width1 >= sizeX);
385  ocean_assert(height0 >= sizeY && height1 >= sizeY);
386 
387  ocean_assert(left0 >= -int(sizeX) + 1 && left0 < int(width0));
388  ocean_assert(top0 >= -int(sizeY) + 1 && top0 < int(height0));
389  ocean_assert(left1 >= -int(sizeX) + 1 && left1 < int(width1));
390  ocean_assert(top1 >= -int(sizeY) + 1 && top1 < int(height1));
391 
392  const int patchLeftBorder = max(0, max(-left0, -left1));
393  const int patchTopBorder = max(0, max(-top0, -top1));
394 
395  const int patchRightBorder = max(0, max(left0 + int(sizeX) - int(width0), left1 + int(sizeX) - int(width1)));
396  const int patchBottomBorder = max(0, max(top0 + int(sizeY) - int(height0), top1 + int(sizeY) - int(height1)));
397 
398  ocean_assert(patchLeftBorder >= 0 && patchLeftBorder < int(sizeX));
399  ocean_assert(patchTopBorder >= 0 && patchTopBorder < int(sizeY));
400  ocean_assert(patchRightBorder >= 0 && patchRightBorder < int(sizeX));
401  ocean_assert(patchBottomBorder >= 0 && patchBottomBorder < int(sizeY));
402 
403  const int pLeft0 = left0 + patchLeftBorder;
404  const int pLeft1 = left1 + patchLeftBorder;
405 
406  const int pTop0 = top0 + patchTopBorder;
407  const int pTop1 = top1 + patchTopBorder;
408 
409  const unsigned int pSizeX = sizeX - patchLeftBorder - patchRightBorder;
410  const unsigned int pSizeY = sizeY - patchTopBorder - patchBottomBorder;
411 
412  if (pSizeX > sizeX || pSizeY > sizeY)
413  return 0u;
414 
415  for (unsigned int n = 0u; n < tChannels; ++n)
416  sums0[n] = 0u;
417  for (unsigned int n = 0u; n < tChannels; ++n)
418  sums1[n] = 0u;
419 
420  unsigned int pixels = 0u;
421 
422  frame0 += (pTop0 * int(width0) + pLeft0) * int(tChannels);
423  frame1 += (pTop1 * int(width1) + pLeft1) * int(tChannels);
424 
425  mask0 += (pTop0 * int(width0) + pLeft0);
426  mask1 += (pTop1 * int(width1) + pLeft1);
427 
428  const uint8_t* const mask0End = mask0 + pSizeY * width0;
429 
430  while (mask0 != mask0End)
431  {
432  ocean_assert(mask0 < mask0End);
433 
434  const uint8_t* const mask0RowEnd = mask0 + pSizeX;
435 
436  while (mask0 != mask0RowEnd)
437  {
438  ocean_assert(mask0 < mask0End);
439  ocean_assert(mask0 < mask0RowEnd);
440 
441  const unsigned int factor = (*mask0 * *mask1) != 0u;
442 
443  for (unsigned int n = 0u; n < tChannels; ++n)
444  sums0[n] += frame0[n] * factor;
445 
446  for (unsigned int n = 0u; n < tChannels; ++n)
447  sums1[n] += frame1[n] * factor;
448 
449  pixels += factor;
450 
451  frame0 += tChannels;
452  frame1 += tChannels;
453 
454  mask0++;
455  mask1++;
456  }
457 
458  frame0 += int(width0 - pSizeX) * int(tChannels);
459  frame1 += int(width1 - pSizeX) * int(tChannels);
460 
461  mask0 += int(width0 - pSizeX);
462  mask1 += int(width1 - pSizeX);
463  }
464 
465  return pixels;
466 }
467 
468 }
469 
470 }
471 
472 }
473 
474 #endif // META_OCEAN_CV_ADVANCED_ADVANCED_ZERO_MEAN_SUM_SQUARE_DIFFERENCES_BASE_H
This class implements functions calculating the zero-mean sum of square differences.
Definition: AdvancedZeroMeanSumSquareDifferencesBase.h:31
static IndexPair32 determine8BitPerChannelPartialTemplate(const uint8_t *frame0, const uint8_t *frame1, const uint8_t *mask0, const uint8_t *mask1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, unsigned int sizeX, unsigned int sizeY, const int left0, const int top0, const int left1, const int top1)
Determines the partial zero-mean ssd of two image patches between two frames while for each frame a b...
Definition: AdvancedZeroMeanSumSquareDifferencesBase.h:204
static unsigned int sum8BitPerChannelPartialTemplate(const uint8_t *frame, const uint8_t *mask, const unsigned int width, const unsigned int height, const unsigned int sizeX, const unsigned int sizeY, const int left, const int top, unsigned int sums[tChannels])
Determines the mean values of given image patch with arbitrary sizes while a binary mask specifies wh...
Definition: AdvancedZeroMeanSumSquareDifferencesBase.h:304
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: AdvancedZeroMeanSumSquareDifferencesBase.h:142
static void patchFrame(const T *source, T *buffer, const unsigned int width, const unsigned int channels, const unsigned int x, const unsigned int y, const unsigned int patchSize, const unsigned int sourcePaddingElements, const unsigned int bufferPaddingElements)
Copies a small patch area of a given frame into a buffer holding only the entire patch.
Definition: FrameConverter.h:3076
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