Ocean
Loading...
Searching...
No Matches
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
17namespace Ocean
18{
19
20namespace CV
21{
22
23namespace 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
141template <unsigned int tChannels, unsigned int tPatchSize>
142inline 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
171template <unsigned int tChannels, unsigned int tPatchSize>
172inline 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
203template <unsigned int tChannels>
204inline 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
303template <unsigned int tChannels>
304inline 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
375template <unsigned int tChannels>
376inline 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:3127
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:129
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15