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
261 unsigned int ssd = 0u;
262
263 frame0 += (pTop0 * int(width0) + pLeft0) * int(tChannels);
264 frame1 += (pTop1 * int(width1) + pLeft1) * int(tChannels);
265
266 mask0 += (pTop0 * int(width0) + pLeft0);
267 mask1 += (pTop1 * int(width1) + pLeft1);
268
269 const uint8_t* const mask0End = mask0 + pSizeY * width0;
270
271 while (mask0 != mask0End)
272 {
273 ocean_assert(mask0 < mask0End);
274
275 const uint8_t* const mask0RowEnd = mask0 + pSizeX;
276
277 while (mask0 != mask0RowEnd)
278 {
279 ocean_assert(mask0 < mask0End);
280 ocean_assert(mask0 < mask0RowEnd);
281
282 const unsigned int factor = (*mask0 * *mask1) != 0u;
283
284 for (unsigned int n = 0u; n < tChannels; ++n) {
285 ssd += sqr(int(frame0[n]) - int(frame1[n]) + means1_0[n]) * factor;
286}
287
288 frame0 += tChannels;
289 frame1 += tChannels;
290
291 mask0++;
292 mask1++;
293 }
294
295 frame0 += (width0 - pSizeX) * tChannels;
296 frame1 += (width1 - pSizeX) * tChannels;
297
298 mask0 += (width0 - pSizeX);
299 mask1 += (width1 - pSizeX);
300 }
301
302 return std::make_pair(ssd, pixels);
303}
304
305template <unsigned int tChannels>
306inline 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])
307{
308 static_assert(tChannels != 0u, "Invalid number of frame channels!");
309
310 ocean_assert(frame && mask);
311 ocean_assert(width >= 1u && height >= 1u);
312 ocean_assert(sizeX >= 1u && sizeY >= 1u);
313
314 ocean_assert(width >= sizeX && height >= sizeY);
315 ocean_assert(left >= -int(sizeX) + 1 && left < int(width));
316 ocean_assert(top >= -int(sizeY) + 1 && top < int(height));
317
318 const int patchLeftBorder = max(0, -left);
319 const int patchTopBorder = max(0, -top);
320
321 const int patchRightBorder = max(0, left + int(sizeX) - int(width));
322 const int patchBottomBorder = max(0, top + int(sizeY) - int(height));
323
324 ocean_assert(patchLeftBorder >= 0 && patchLeftBorder < int(sizeX));
325 ocean_assert(patchTopBorder >= 0 && patchTopBorder < int(sizeY));
326 ocean_assert(patchRightBorder >= 0 && patchRightBorder < int(sizeX));
327 ocean_assert(patchBottomBorder >= 0 && patchBottomBorder < int(sizeY));
328
329 const int pLeft = left + patchLeftBorder;
330 const int pTop = top + patchTopBorder;
331
332 const unsigned int pSizeX = sizeX - patchLeftBorder - patchRightBorder;
333 const unsigned int pSizeY = sizeY - patchTopBorder - patchBottomBorder;
334
335 if (pSizeX > sizeX || pSizeY > sizeY) {
336 return 0u;
337}
338
339 unsigned int pixels = 0u;
340
341 for (unsigned int n = 0u; n < tChannels; ++n) {
342 sums[n] = 0u;
343}
344
345 frame += (pTop * int(width) + pLeft) * int(tChannels);
346 mask += (pTop * int(width) + pLeft);
347
348 const uint8_t* const maskEnd = mask + pSizeY * width;
349
350 while (mask != maskEnd)
351 {
352 ocean_assert(mask < maskEnd);
353
354 const uint8_t* const maskRowEnd = mask + pSizeX;
355
356 while (mask != maskRowEnd)
357 {
358 ocean_assert(mask < maskEnd);
359 ocean_assert(mask < maskRowEnd);
360
361 const unsigned int factor = *mask != 0u;
362
363 for (unsigned int n = 0u; n < tChannels; ++n) {
364 sums[n] += frame[n] * factor;
365}
366
367 pixels += factor;
368
369 frame += tChannels;
370 mask++;
371 }
372
373 frame += int(width - pSizeX) * int(tChannels);
374 mask += int(width - pSizeX);
375 }
376
377 return pixels;
378}
379
380template <unsigned int tChannels>
381inline 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])
382{
383 static_assert(tChannels != 0u, "Invalid number of frame channels!");
384
385 ocean_assert(frame0 && frame1);
386 ocean_assert(mask0 && mask1);
387
388 ocean_assert(sizeX >= 1u && sizeY >= 1u);
389 ocean_assert(width0 >= sizeX && width1 >= sizeX);
390 ocean_assert(height0 >= sizeY && height1 >= sizeY);
391
392 ocean_assert(left0 >= -int(sizeX) + 1 && left0 < int(width0));
393 ocean_assert(top0 >= -int(sizeY) + 1 && top0 < int(height0));
394 ocean_assert(left1 >= -int(sizeX) + 1 && left1 < int(width1));
395 ocean_assert(top1 >= -int(sizeY) + 1 && top1 < int(height1));
396
397 const int patchLeftBorder = max(0, max(-left0, -left1));
398 const int patchTopBorder = max(0, max(-top0, -top1));
399
400 const int patchRightBorder = max(0, max(left0 + int(sizeX) - int(width0), left1 + int(sizeX) - int(width1)));
401 const int patchBottomBorder = max(0, max(top0 + int(sizeY) - int(height0), top1 + int(sizeY) - int(height1)));
402
403 ocean_assert(patchLeftBorder >= 0 && patchLeftBorder < int(sizeX));
404 ocean_assert(patchTopBorder >= 0 && patchTopBorder < int(sizeY));
405 ocean_assert(patchRightBorder >= 0 && patchRightBorder < int(sizeX));
406 ocean_assert(patchBottomBorder >= 0 && patchBottomBorder < int(sizeY));
407
408 const int pLeft0 = left0 + patchLeftBorder;
409 const int pLeft1 = left1 + patchLeftBorder;
410
411 const int pTop0 = top0 + patchTopBorder;
412 const int pTop1 = top1 + patchTopBorder;
413
414 const unsigned int pSizeX = sizeX - patchLeftBorder - patchRightBorder;
415 const unsigned int pSizeY = sizeY - patchTopBorder - patchBottomBorder;
416
417 if (pSizeX > sizeX || pSizeY > sizeY) {
418 return 0u;
419}
420
421 for (unsigned int n = 0u; n < tChannels; ++n) {
422 sums0[n] = 0u;
423}
424 for (unsigned int n = 0u; n < tChannels; ++n) {
425 sums1[n] = 0u;
426}
427
428 unsigned int pixels = 0u;
429
430 frame0 += (pTop0 * int(width0) + pLeft0) * int(tChannels);
431 frame1 += (pTop1 * int(width1) + pLeft1) * int(tChannels);
432
433 mask0 += (pTop0 * int(width0) + pLeft0);
434 mask1 += (pTop1 * int(width1) + pLeft1);
435
436 const uint8_t* const mask0End = mask0 + pSizeY * width0;
437
438 while (mask0 != mask0End)
439 {
440 ocean_assert(mask0 < mask0End);
441
442 const uint8_t* const mask0RowEnd = mask0 + pSizeX;
443
444 while (mask0 != mask0RowEnd)
445 {
446 ocean_assert(mask0 < mask0End);
447 ocean_assert(mask0 < mask0RowEnd);
448
449 const unsigned int factor = (*mask0 * *mask1) != 0u;
450
451 for (unsigned int n = 0u; n < tChannels; ++n) {
452 sums0[n] += frame0[n] * factor;
453}
454
455 for (unsigned int n = 0u; n < tChannels; ++n) {
456 sums1[n] += frame1[n] * factor;
457}
458
459 pixels += factor;
460
461 frame0 += tChannels;
462 frame1 += tChannels;
463
464 mask0++;
465 mask1++;
466 }
467
468 frame0 += int(width0 - pSizeX) * int(tChannels);
469 frame1 += int(width1 - pSizeX) * int(tChannels);
470
471 mask0 += int(width0 - pSizeX);
472 mask1 += int(width1 - pSizeX);
473 }
474
475 return pixels;
476}
477
478}
479
480}
481
482}
483
484#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:306
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:3141
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition base/Utilities.h:1053
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