Ocean
TestFrameInterpolatorBilinear.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_TEST_TESTCV_TEST_FRAME_INTERPOLATOR_BILINEAR_H
9 #define META_OCEAN_TEST_TESTCV_TEST_FRAME_INTERPOLATOR_BILINEAR_H
10 
12 
13 #include "ocean/base/Frame.h"
14 #include "ocean/base/Worker.h"
15 
16 #include "ocean/cv/PixelPosition.h"
17 
18 #include "ocean/math/Lookup2.h"
20 #include "ocean/math/Vector2.h"
21 
22 namespace Ocean
23 {
24 
25 namespace Test
26 {
27 
28 namespace TestCV
29 {
30 
31 /**
32  * This class implements a bilinear frame interpolation test.
33  * @ingroup testcv
34  */
35 class OCEAN_TEST_CV_EXPORT TestFrameInterpolatorBilinear
36 {
37  public:
38 
39  /**
40  * Tests all bilinear interpolation filter functions.
41  * @param width The width of the source frame in pixel
42  * @param height The height of the source frame in pixel
43  * @param testDuration Number of seconds for each test, with range (0, infinity)
44  * @param worker The worker object to distribute the CPU load
45  * @return True, if succeeded
46  */
47  static bool test(const unsigned int width, const unsigned int height, const double testDuration, Worker& worker);
48 
49  /**
50  * Tests the pixel interpolation function for frames with 8 bit per channel.
51  * @param testDuration Number of seconds for each test, with range (0, infinity)
52  * @return True, if succeeded
53  */
54  static bool testInterpolatePixel8BitPerChannel(const double testDuration);
55 
56  /**
57  * Tests the pixel interpolation function for frames with 8 bit per channel.
58  * @param testDuration Number of seconds for each test, with range (0, infinity)
59  * @param pixelCenter The pixel center to be used
60  * @return True, if succeeded
61  * @tparam TScalar The data type of the scalar to be used, either 'float' or 'double'
62  */
63  template <typename TScalar>
64  static bool testInterpolatePixel8BitPerChannel(const CV::PixelCenter pixelCenter, const double testDuration);
65 
66  /**
67  * Tests the pixel interpolation function for frames with arbitrary data type.
68  * @param testDuration Number of seconds for each test, with range (0, infinity)
69  * @return True, if succeeded
70  */
71  static bool testInterpolatePixel(const double testDuration);
72 
73  /**
74  * Tests the pixel interpolation function for frames arbitrary data type.
75  * @param testDuration Number of seconds for each test, with range (0, infinity)
76  * @param pixelCenter The pixel center to be used
77  * @return True, if succeeded
78  * @tparam TSource The data type of the source to be used
79  * @tparam TTarget The data type of the target to be used
80  * @tparam TScalar The data type of the scalar to be used, either 'float' or 'double'
81  */
82  template <typename TSource, typename TTarget, typename TScalar>
83  static bool testInterpolatePixel(const CV::PixelCenter pixelCenter, const double testDuration);
84 
85  /**
86  * Tests the affine transformation function using a constant color for unknown image content.
87  * @param testDuration Number of seconds for each test, with range (0, infinity)
88  * @param worker The worker object to distribute the CPU load
89  * @return True, if succeeded
90  */
91  static bool testAffine(const double testDuration, Worker& worker);
92 
93  /**
94  * Tests the homography transformation function supporting arbitrary pixel formats using a constant color for unknown image content.
95  * @param testDuration Number of seconds for each test, with range (0, infinity)
96  * @param worker The worker object to distribute the CPU load
97  * @return True, if succeeded
98  * @tparam T The data type of each pixel channel, e.g., 'float', 'double', 'int', ...
99  */
100  template <typename T>
101  static bool testHomography(const double testDuration, Worker& worker);
102 
103  /**
104  * Tests the homography transformation function defining a binary mask for known and unknown image content.
105  * @param testDuration Number of seconds for each test, with range (0, infinity)
106  * @param worker The worker object to distribute the CPU load
107  * @return True, if succeeded
108  */
109  static bool testHomographyMask(const double testDuration, Worker& worker);
110 
111  /**
112  * Tests the bilinear resize function for extreme image resolutions.
113  * @param testDuration Number of seconds for each test, with range (0, infinity)
114  * @param worker The worker object to distribute the CPU load
115  * @return True, if succeeded
116  */
117  static bool testResizeExtremeResolutions(const double testDuration, Worker& worker);
118 
119  /**
120  * Tests the bilinear resize function.
121  * @param testDuration Number of seconds for each test, with range (0, infinity)
122  * @param worker The worker object to distribute the CPU load
123  * @return True, if succeeded
124  */
125  static bool testResize(const double testDuration, Worker& worker);
126 
127  /**
128  * Tests the bilinear resize function supporting arbitrary data types.
129  * @param testDuration Number of seconds for each test, with range (0, infinity)
130  * @param worker The worker object to distribute the CPU load
131  * @return True, if succeeded
132  * @tparam T The data type of each pixel channel, e.g., `uint8_t`, 'float', 'double', ...
133  */
134  template <typename T>
135  static bool testResize(const double testDuration, Worker& worker);
136 
137  /**
138  * Tests the frame transformation function applying a lookup table.
139  * @param testDuration Number of seconds for each test, with range (0, infinity)
140  * @param worker The worker object to distribute the CPU load
141  * @return True, if succeeded
142  */
143  static bool testLookup(const double testDuration, Worker& worker);
144 
145  /**
146  * Tests the frame transformation function applying a lookup table.
147  * @param testDuration Number of seconds for each test, with range (0, infinity)
148  * @param worker The worker object to distribute the CPU load
149  * @return True, if succeeded
150  * @tparam T The data type of each pixel channel, e.g., `uint8_t`, 'float', 'double', ...
151  */
152  template <typename T>
153  static bool testLookup(const double testDuration, Worker& worker);
154 
155  /**
156  * Tests the frame mask transformation function applying a lookup table.
157  * @param width The width of the test frame in pixel, with range [1, infinity)
158  * @param height The height of the test frame in pixel, with range [1, infinity)
159  * @param testDuration Number of seconds for each test, with range (0, infinity)
160  * @param worker The worker object to distribute the CPU load
161  * @return True, if succeeded
162  */
163  static bool testLookupMask(const unsigned int width, const unsigned int height, const double testDuration, Worker& worker);
164 
165  /**
166  * Tests the frame rotate function.
167  * @param width The width of the test frame in pixel, with range [1, infinity)
168  * @param height The height of the test frame in pixel, with range [1, infinity)
169  * @param testDuration Number of seconds for each test, with range (0, infinity)
170  * @param worker The worker object to distribute the CPU load
171  * @return True, if succeeded
172  */
173  static bool testRotateFrame(const unsigned int width, const unsigned int height, const double testDuration, Worker& worker);
174 
175  /**
176  * Tests the intensity sum of an image patch with sub-pixel location in a 1-channel frame using an integral image.
177  * @param width The width of the frame in pixel, with range [64, infinity)
178  * @param height The height of the frame in pixel, with range [64, infinity)
179  * @param testDuration Number of seconds for each test, with range (0, infinity)
180  * @return True, if succeeded
181  */
182  static bool testPatchIntensitySum1Channel(const unsigned int width, const unsigned int height, const double testDuration);
183 
184  /**
185  * Tests the function for affine transformations (with constant color for unknown image content) for a given frame dimension and channel number.
186  * @param width The width of the frame in pixel, with range [1, infinity)
187  * @param height The height of the frame in pixel, with range [1, infinity)
188  * @param channels The number of frame channels, with range [1, 4]
189  * @param testDuration Number of seconds for each test, with range (0, infinity)
190  * @param worker The worker object to distribute the CPU load
191  * @return True, if succeeded
192  */
193  static bool testAffine(const unsigned int width, const unsigned int height, const unsigned int channels, const double testDuration, Worker& worker);
194 
195  /**
196  * Tests the homography transformation function (with constant color for unknown image content) for arbitrary data types and for a given frame dimension and channel number.
197  * @param width The width of the frame in pixel, with range [1, infinity)
198  * @param height The height of the frame in pixel, with range [1, infinity)
199  * @param channels The number of frame channels, with range [1, 4]
200  * @param testDuration Number of seconds for each test, with range (0, infinity)
201  * @param worker The worker object to distribute the CPU load
202  * @return True, if succeeded
203  * @tparam T The data type of each pixel channel, e.g., 'float', 'double', 'int', ...
204  */
205  template <typename T>
206  static bool testHomography(const unsigned int width, const unsigned int height, const unsigned int channels, const double testDuration, Worker& worker);
207 
208  /**
209  * Tests the homography transformation function (with binary mask defining known and unknown image content) for a given frame dimension and channel number.
210  * @param width The width of the frame in pixel, with range [1, infinity)
211  * @param height The height of the frame in pixel, with range [1, infinity)
212  * @param channels The number of frame channels, with range [1, 4]
213  * @param testDuration Number of seconds for each test, with range (0, infinity)
214  * @param worker The worker object to distribute the CPU load
215  * @return True, if succeeded
216  */
217  static bool testHomographyMask(const unsigned int width, const unsigned int height, const unsigned int channels, const double testDuration, Worker& worker);
218 
219  /**
220  * Tests the bilinear resize function for a given frame dimension and channel number.
221  * @param sourceWidth Width of the source frame in pixel
222  * @param sourceHeight Height of the source frame in pixel
223  * @param sourceChannels Number of the data channels of the source frame, with range [1, 4]
224  * @param targetWidth Width of the target frame in pixel
225  * @param targetHeight Height of the target frame in pixel
226  * @param testDuration Number of seconds for each test, with range (0, infinity)
227  * @param worker The worker object to distribute the CPU load
228  * @return True, if succeeded
229  */
230  static bool testResize(const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourceChannels, const unsigned int targetWidth, const unsigned int targetHeight, const double testDuration, Worker& worker);
231 
232  /**
233  * Tests the bilinear resize function for arbitrary data types and for a given frame dimension and channel number.
234  * @param sourceWidth Width of the source frame in pixel
235  * @param sourceHeight Height of the source frame in pixel
236  * @param sourceChannels Number of the data channels of the source frame
237  * @param targetWidth Width of the target frame in pixel
238  * @param targetHeight Height of the target frame in pixel
239  * @param testDuration Number of seconds for each test, with range (0, infinity)
240  * @param worker The worker object to distribute the CPU load
241  * @return True, if succeeded
242  * @tparam T The data type of each pixel channel, e.g., 'float', 'double', 'int', ...
243  */
244  template <typename T>
245  static bool testResize(const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourceChannels, const unsigned int targetWidth, const unsigned int targetHeight, const double testDuration, Worker& worker);
246 
247  /**
248  * Tests the special case resize function for image resolutions from 400x400 to 256x256.
249  * @param testDuration Number of seconds for each test, with range (0, infinity)
250  * @return True, if succeeded
251  */
252  static bool testSpecialCasesResize400x400To256x256_8BitPerChannel(const double testDuration);
253 
254  /**
255  * Tests the special case resize function for image resolutions from 400x400 to 224x224.
256  * @param testDuration Number of seconds for each test, with range (0, infinity)
257  * @return True, if succeeded
258  */
259  static bool testSpecialCasesResize400x400To224x224_8BitPerChannel(const double testDuration);
260 
261  /**
262  * Tests the frame transformation function applying a lookup table.
263  * @param width The width of the test frame in pixel, with range [20, infinity)
264  * @param height The height of the test frame in pixel, with range [20, infinity)
265  * @param channels The number of frame channels, with range [1, infinity)
266  * @param testDuration Number of seconds for each test, with range (0, infinity)
267  * @param worker The worker object to distribute the CPU load
268  * @return True, if succeeded
269  * @tparam T The data type of each pixel channel, e.g., 'float', 'double', 'int', ...
270  */
271  template <typename T>
272  static bool testLookup(const unsigned int width, const unsigned int height, const unsigned int channels, const double testDuration, Worker& worker);
273 
274  /**
275  * Tests the function to re-sample a camera image.
276  * @param testDuration Number of seconds for each test, with range (0, infinity)
277  * @param worker The worker object to distribute the CPU load
278  * @return True, if succeeded
279  */
280  static bool testResampleCameraImage(const double testDuration, Worker& worker);
281 
282  /**
283  * Tests the function to re-sample a camera image.
284  * @param testDuration Number of seconds for each test, with range (0, infinity)
285  * @param worker The worker object to distribute the CPU load
286  * @return True, if succeeded
287  * @tparam T The data type of each pixel channel, e.g., 'float', 'double', 'int', ...
288  */
289  template <typename T>
290  static bool testResampleCameraImage(const double testDuration, Worker& worker);
291 
292  /**
293  * Validates the bilinear frame resize function.
294  * @param source The source frame that has been resized, must be valid
295  * @param sourceWidth The width of the source frame in pixel, with range [1, infinity)
296  * @param sourceHeight The height of the source frame in pixel, with range [1, infinity)
297  * @param channels Number of the data channels of the source (and target) frame, with range [1, 4]
298  * @param target The resized target frame to be verified, must be valid
299  * @param targetWidth The width of the target frame in pixel, with range [1, infinity)
300  * @param targetHeight The height of the target frame in pixel, with range [1, infinity)
301  * @param xTargetToSource The horizontal scale factor transforming a location in the target frame to a location in the source frame, with range (0, infinity)
302  * @param yTargetToSource The vertical scale factor transforming a location in the target frame to a location in the source frame, with range (0, infinity)
303  * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
304  * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
305  * @param averageAbsErrorToInteger Optional resulting average absolute error between the converted result and the ground truth integer result (rounded result), with range [0, 256)
306  * @param maximalAbsErrorToInteger Optional resulting maximal absolute error between the converted result and the ground truth integer result (rounded result), with range [0, 256)
307  * @param groundTruth Optional resulting ground truth data (the resized image content determined with floating point accuracy), nullptr otherwise
308  */
309  static void validateScaleFrame(const unsigned char* source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const unsigned char* target, const unsigned int targetWidth, const unsigned int targetHeight, const double xTargetToSource, const double yTargetToSource, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, double* averageAbsErrorToInteger, unsigned int* maximalAbsErrorToInteger, unsigned char* groundTruth = nullptr);
310 
311  /**
312  * Validates the bilinear frame resize function for arbitrary data types.
313  * @param source The source frame that has been resized, must be valid
314  * @param sourceWidth The width of the source frame in pixel, with range [1, infinity)
315  * @param sourceHeight The height of the source frame in pixel, with range [1, infinity)
316  * @param channels Number of the data channels of the source (and target) frame, with range [1, 4]
317  * @param target The resized target frame to be verified, must be valid
318  * @param targetWidth The width of the target frame in pixel, with range [1, infinity)
319  * @param targetHeight The height of the target frame in pixel, with range [1, infinity)
320  * @param xSource_s_xTarget The horizontal scale factor transforming a location in the target frame to a location in the source frame, with range (0, infinity)
321  * @param ySource_s_yTarget The vertical scale factor transforming a location in the target frame to a location in the source frame, with range (0, infinity)
322  * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
323  * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
324  * @param averageAbsError Optional resulting average absolute error between the converted result and the ground truth result, with range (-infinity, infinity)
325  * @param maximalAbsError Optional resulting maximal absolute error between the converted result and the ground truth result, with range (-infinity, infinity)
326  * @param groundTruth Optional resulting ground truth data (the resized image content determined with floating point accuracy), nullptr otherwise
327  * @tparam T The data type of each pixel channel, e.g., 'float', 'double', 'int', ...
328  */
329  template <typename T>
330  static void validateScaleFrame(const T* source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const T* target, const unsigned int targetWidth, const unsigned int targetHeight, const double xSource_s_xTarget, const double ySource_s_yTarget, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, double* averageAbsError, double* maximalAbsError, T* groundTruth = nullptr);
331 
332  /**
333  * Validates the homography interpolation function for (almost) arbitrary pixel formats (using a constant background color for unknown image content).
334  * @param input The input frame which has been used for the interpolation, must be valid
335  * @param output The output frame holding the interpolated image information of the input frame, must be valid
336  * @param input_H_output The homography that has been used to interpolate/warp the frame, transforming points int he output frame to points in the input frame, must not be singular
337  * @param backgroundColor The background color for all pixels for which no valid source pixel exists, one for each frame channel, must be valid
338  * @param interpolatedFrameOrigin The origin of the interpolated frame defining the global position of the interpolated frame's pixel coordinate (0, 0), with range (-infinity, infinity)x(-infinity, infinity)
339  * @param averageAbsError Optional resulting average absolute error between the converted result and the ground truth result, with range (-infinity, infinity)
340  * @param maximalAbsError Optional resulting maximal absolute error between the converted result and the ground truth result, with range (-infinity, infinity)
341  * @param groundTruth Optional resulting ground truth frame (the resized image content determined with floating point accuracy), nullptr if not of interest
342  * @tparam T The data type of each pixel channel, e.g., 'float', 'double', 'int', ...
343  */
344  template <typename T>
345  static void validateHomography(const Frame& input, const Frame& output, const SquareMatrix3& input_H_output, const T* backgroundColor, const CV::PixelPositionI& interpolatedFrameOrigin, double* averageAbsError, double* maximalAbsError, Frame* groundTruth = nullptr);
346 
347  protected:
348 
349  /**
350  * Tests the intensity sum of an image patch with sub-pixel location in a 1-channel frame using an integral image.
351  * @param width The width of the frame, in pixel, with range [patchWidth + 1u, infinity)
352  * @param height The height of the frame, in pixel, with range [patchHeight + 1u, infinity)
353  * @param patchWidth Width of the patch, in pixel, with range [1, infinity)
354  * @param patchHeight Height of the patch, in pixel, with range [1, infinity)
355  * @param testDuration Number of seconds for each test, with range (0, infinity)
356  * @return True, if succeeded
357  */
358  static bool testPatchIntensitySum1Channel(const unsigned int width, const unsigned int height, const unsigned int patchWidth, const unsigned int patchHeight, const double testDuration);
359 
360  /**
361  * Validates a pixel interpolation result for frame with 8 bit per channel.
362  * @param frame The frame in pixel the pixel interpolation was applied, must be valid
363  * @param position The position for which the interpolated pixel will be determined, with ranges [0, frame.width() - 1]x[0, frame.height() - 1] for PC_TOP_LEFT, [0, frame.width()]x[0, frame.height()] for PC_CENTER
364  * @param pixelCenter The pixel center to be used during interpolation
365  * @param interpolationResult The interpolation result to be verified, one for each frame channel
366  * @param threshold The maximal distance between interpolated result and ground-truth result so that the result is valid, with range [0, 255)
367  * @return True, if the interpolation is correct
368  * @tparam TScalar The data type of a scalar, either 'float' or 'double'
369  */
370  template <typename TScalar>
371  static bool validateInterpolatePixel8BitPerChannel(const Frame& frame, const VectorT2<TScalar>& position, const CV::PixelCenter pixelCenter, const uint8_t* const interpolationResult, const TScalar threshold);
372 
373  /**
374  * Validates a pixel interpolation result for frame with arbitrary data type.
375  * @param frame The frame in pixel the pixel interpolation was applied, must be valid
376  * @param position The position for which the interpolated pixel will be determined, with ranges [0, frame.width() - 1]x[0, frame.height() - 1] for PC_TOP_LEFT, [0, frame.width()]x[0, frame.height()] for PC_CENTER
377  * @param pixelCenter The pixel center to be used during interpolation
378  * @param interpolationResult The interpolation result to be verified, one for each frame channel
379  * @param threshold The maximal distance between interpolated result and ground-truth result so that the result is valid, with range [0, 255)
380  * @return True, if the interpolation is correct
381  * @tparam TSource The data type of the source to be used
382  * @tparam TTarget The data type of the target to be used
383  * @tparam TScalar The data type of a scalar, either 'float' or 'double'
384  */
385  template <typename TSource, typename TTarget, typename TScalar>
386  static bool validateInterpolatePixel(const Frame& frame, const VectorT2<TScalar>& position, const CV::PixelCenter pixelCenter, const TTarget* const interpolationResult, const TScalar threshold);
387 
388  /**
389  * Validation function for the bilinear interpolation of 2D homogeneous image transformations (+ constant background color for unknown image content).
390  * @param source The frame which will be interpolated based on the homography, must be valid
391  * @param validationTarget The interpolated frame that will be validated, must the same pixel format and origin as 'source' and must be valid
392  * @param source_H_target The 2D homogeneous image transformation that has been used to interpolate/warp the frame, transforming points defined in the interpolatedFrame to the source frame, i.e. pointFrame = transformation * pointInterpolatedFrame, must not be singular
393  * @param backgroundColor The background color for all pixels for which no valid source pixel exists, one for each frame channel, must be valid
394  * @param interpolatedFrameOrigin The origin of the interpolated frame defining the global position of the interpolated frame's pixel coordinate (0, 0), with range (-infinity, infinity)x(-infinity, infinity)
395  * @return True, if the interpolation is correct
396  */
397  static bool validateTransformation8BitPerChannel(const Frame& source, const Frame& validationTarget, const SquareMatrix3& source_H_target, const uint8_t* backgroundColor, const CV::PixelPositionI& interpolatedFrameOrigin);
398 
399  /**
400  * Validates the homography interpolation function (using a binary mask to define known and unknown image content).
401  * @param frame The frame which will be interpolated based on the homography, must be valid
402  * @param interpolatedFrame The interpolated/warped frame to be validated, width same pixel format and pixel origin as 'frame, must be valid
403  * @param interpolatedMask The binary mask corresponding to the interpolated/warped frame specifying known and unknown image content, a mask value of 0xFF defined known image content, 0x00 defines unknown image content, with same pixel origin and frame resolution as 'interpolatedFrame'
404  * @param input_H_output The homography that has been used to interpolate/warp the frame, transforming points in the output frame to points in the input frame, must not be singular
405  * @param interpolatedFrameOrigin The origin of the interpolated frame defining the global position of the interpolated frame's pixel coordinate (0, 0), with range (-infinity, infinity)x(-infinity, infinity)
406  * @return True, if the interpolation is correct
407  */
408  static bool validateHomographyMask8BitPerChannel(const Frame& frame, const Frame& interpolatedFrame, const Frame& interpolatedMask, const SquareMatrix3& input_H_output, const CV::PixelPositionI& interpolatedFrameOrigin);
409 
410  /**
411  * Validates the frame transformation function applying a lookup table.
412  * @param sourceFrame The source frame which has been transformed, must be valid
413  * @param targetFrame The target frame which holds the transformed input frame, must be valid
414  * @param lookupTable The lookup table which has been used for the transformation, must be valid
415  * @param offset True, to interpret the lookup values as offset values; False, to interpret the lookup values as absolute locations
416  * @param backgroundColor The background color to be used, must be valid
417  * @return True, if succeeded
418  * @tparam T The data type of each pixel channel, e.g., 'float', 'double', 'int', ...
419  */
420  template <typename T>
421  static bool validateLookup(const Frame& sourceFrame, const Frame& targetFrame, const LookupCorner2<Vector2>& lookupTable, const bool offset, const T* backgroundColor);
422 
423  /**
424  * Validates the frame mask transformation function applying a lookup table.
425  * @param sourceFrame The source frame which has been transformed, must be valid
426  * @param targetFrame The target frame which holds the transformed input frame, must be valid
427  * @param targetMask The mask associated with the target frame, must be valid
428  * @param lookupTable The lookup table which has been used for the transformation, must be valid
429  * @param offset True, to interpret the lookup values as offset values; False, to interpret the lookup values as absolute locations
430  * @return True, if succeeded
431  */
432  static bool validateLookupMask(const Frame& sourceFrame, const Frame& targetFrame, const Frame& targetMask, const LookupCorner2<Vector2>& lookupTable, const bool offset);
433 
434  /**
435  * Validates the rotation of a frame using a bilinear interpolation.
436  * @param source The source frame to be rotated, must be valid
437  * @param target The target frame which will receive the rotated image, with same frame type as the source frame, must be valid
438  * @param anchorX Position of the rotation anchor in the horizontal direction, with range (-infinity, infinity)
439  * @param anchorY Position of the rotation anchor in the vertical direction, with range (-infinity, infinity)
440  * @param angle The counter clockwise rotation angle in radian, with range [0, 2PI)
441  */
442  static bool validateRotatedFrame(const Frame& source, const Frame& target, const Scalar anchorX, const Scalar anchorY, const Scalar angle);
443 
444  /**
445  * Validate the intensity sum of an image patch with sub-pixel location in a 1-channel frame.
446  * @param yFrame The frame in which the intensity sum is determined, with pixel format FORMAT_Y8, must be valid
447  * @param patchWidth The width of the patch, in pixel, with range [1, infinity)
448  * @param patchHeight The height of the patch, in pixel, with range [1, infinity)
449  * @param center The center of the image patch to be used
450  * @param pixelCenter The pixel center to be used
451  * @param intensity The intensity sum to verify
452  * @return True, if succeeded
453  */
454  static bool validatePatchIntensitySum1Channel(const Frame& yFrame, const unsigned int patchWidth, const unsigned int patchHeight, const Vector2& center, const CV::PixelCenter pixelCenter, const Scalar intensity);
455 
456  /**
457  * Validate the bilinear extraction of frame patches
458  * @param source Pointer to the data of the source frame, must be valid
459  * @param validationTarget Pointer to the data of the target frame that will validated, must be valid
460  * @param sourceWidth Width of the source frame in pixels, range: [targetWidth, infinity)
461  * @param sourceHeight Height of the source frame in pixels, range: [targetWidth, infinity)
462  * @param x Horizontal center position of the patch, range: [targetWidth/2, sourceWidth - targetWidth/2)
463  * @param y Vertical center position of the patch, range: [targetHeight/2, sourceHeight - targetHeight/2)
464  * @param validationTargetWidth Width of the target frame, range: all odd values in range [1, sourceWidth]
465  * @param validationTargetHeight Height of the target frame, range: all odd values in range [1, sourceHeight]
466  * @param sourcePaddingElements Optional number of padding elements of the source frame
467  * @param validationTargetPaddingElements Optional number of padding elements of the target frame
468  * @return True if the validation was successful, otherwise false.
469  * @tparam tChannels Number of data channels of the given source frame, range: [1, infinity)
470  */
471  template <uint32_t tChannels>
472  static bool validatePatchFrame8BitPerChannel(const uint8_t* const source, const uint8_t* const validationTarget, const uint32_t sourceWidth, const uint32_t sourceHeight, const Scalar x, const Scalar y, const uint32_t validationTargetWidth, const uint32_t validationTargetHeight, const uint32_t sourcePaddingElements, const uint32_t validationTargetPaddingElements);
473 
474  /**
475  * Validates the bilinear frame resize function for uint8_t data types using 7-bit integer precision.
476  * This function first interpolates two rows and stores the interpolated result as uint8_t values, followed by an interpolation within the row.
477  * @param source The source frame that has been resized, must be valid
478  * @param sourceWidth The width of the source frame in pixel, with range [1, infinity)
479  * @param sourceHeight The height of the source frame in pixel, with range [1, infinity)
480  * @param channels Number of the data channels of the source (and target) frame, with range [1, 4]
481  * @param target The resized target frame to be verified, must be valid
482  * @param targetWidth The width of the target frame in pixel, with range [1, infinity)
483  * @param targetHeight The height of the target frame in pixel, with range [1, infinity)
484  * @param xSource_s_xTarget The horizontal scale factor transforming a location in the target frame to a location in the source frame, with range (0, infinity)
485  * @param ySource_s_yTarget The vertical scale factor transforming a location in the target frame to a location in the source frame, with range (0, infinity)
486  * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
487  * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
488  * @param averageAbsError Optional resulting average absolute error between the converted result and the ground truth result, with range (-infinity, infinity)
489  * @param maximalAbsError Optional resulting maximal absolute error between the converted result and the ground truth result, with range (-infinity, infinity)
490  * @param groundTruth Optional resulting ground truth data (the resized image content determined with floating point accuracy), nullptr otherwise
491  */
492  static void validateScaleFramePrecision7Bit(const uint8_t* source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const uint8_t* target, const unsigned int targetWidth, const unsigned int targetHeight, const double xSource_s_xTarget, const double ySource_s_yTarget, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, double* averageAbsError, double* maximalAbsError, uint8_t* groundTruth = nullptr);
493 };
494 
495 template <typename T>
496 void TestFrameInterpolatorBilinear::validateScaleFrame(const T* source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const T* target, const unsigned int targetWidth, const unsigned int targetHeight, const double xSource_s_xTarget, const double ySource_s_yTarget, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, double* averageAbsError, double* maximalAbsError, T* groundTruth)
497 {
498  ocean_assert(source != nullptr && target != nullptr);
499  ocean_assert(sourceWidth != 0u && sourceHeight != 0u);
500  ocean_assert(targetWidth != 0u && targetHeight != 0u);
501  ocean_assert(channels >= 1u);
502  ocean_assert(xSource_s_xTarget > 0.0 && ySource_s_yTarget > 0.0);
503 
504  const unsigned int sourceStrideElements = sourceWidth * channels + sourcePaddingElements;
505  const unsigned int targetStrideElements = targetWidth * channels + targetPaddingElements;
506 
507  std::vector<T> result(channels, T(0));
508 
509  if (averageAbsError)
510  {
511  *averageAbsError = NumericD::maxValue();
512  }
513 
514  if (maximalAbsError)
515  {
516  *maximalAbsError = NumericD::maxValue();
517  }
518 
519  double sumAbsError = 0.0;
520  double maxAbsError = 0.0;
521 
522  for (unsigned int y = 0u; y < targetHeight; ++y)
523  {
524  for (unsigned int x = 0u; x < targetWidth; ++x)
525  {
526  const double sx = minmax(0.0, (double(x) + 0.5) * xSource_s_xTarget - 0.5, double(sourceWidth - 1u));
527  const double sy = minmax(0.0, (double(y) + 0.5) * ySource_s_yTarget - 0.5, double(sourceHeight - 1u));
528 
529  const unsigned int leftPixel = (unsigned int)sx;
530  const unsigned int rightPixel = min(leftPixel + 1u, sourceWidth - 1u);
531  ocean_assert(leftPixel < sourceWidth && rightPixel < sourceWidth);
532 
533  const unsigned int topPixel = (unsigned int)sy;
534  const unsigned int bottomPixel = min(topPixel + 1u, sourceHeight - 1u);
535  ocean_assert(topPixel < sourceHeight && bottomPixel < sourceHeight);
536 
537  const double rightFactor = sx - double(leftPixel);
538  const double bottomFactor = sy - double(topPixel);
539 
540  ocean_assert(rightFactor >= 0.0 && rightFactor <= 1.0);
541  ocean_assert(bottomFactor >= 0.0 && bottomFactor <= 1.0);
542 
543  const double leftFactor = 1.0 - rightFactor;
544  const double topFactor = 1.0 - bottomFactor;
545 
546  const T* sourceTopLeft = source + sourceStrideElements * topPixel + leftPixel * channels;
547  const T* sourceTopRight = source + sourceStrideElements * topPixel + rightPixel * channels;
548 
549  const T* sourceBottomLeft = source + sourceStrideElements * bottomPixel + leftPixel * channels;
550  const T* sourceBottomRight = source + sourceStrideElements * bottomPixel + rightPixel * channels;
551 
552  for (unsigned int n = 0u; n < channels; ++n)
553  {
554  const double top = double(sourceTopLeft[n]) * leftFactor + double(sourceTopRight[n]) * rightFactor;
555  const double bottom = double(sourceBottomLeft[n]) * leftFactor + double(sourceBottomRight[n]) * rightFactor;
556 
557  const double interpolated = top * topFactor + bottom * bottomFactor;
558 
559  result[n] = T(interpolated);
560  }
561 
562  const T* const targetValue = target + targetStrideElements * y + x * channels;
563 
564  for (unsigned int n = 0u; n < channels; ++n)
565  {
566  const double absError = NumericD::abs(double(result[n]) - double(targetValue[n]));
567 
568  sumAbsError += absError;
569  maxAbsError = max(maxAbsError, absError);
570  }
571 
572  if (groundTruth)
573  {
574  memcpy(groundTruth + (y * targetWidth + x) * channels, result.data(), sizeof(T) * channels);
575  }
576  }
577  }
578 
579  if (averageAbsError)
580  {
581  *averageAbsError = sumAbsError / double(targetWidth * targetHeight * channels);
582  }
583 
584  if (maximalAbsError)
585  {
586  *maximalAbsError = maxAbsError;
587  }
588 }
589 
590 template <typename T>
591 void TestFrameInterpolatorBilinear::validateHomography(const Frame& input, const Frame& output, const SquareMatrix3& input_H_output, const T* backgroundColor, const CV::PixelPositionI& interpolatedFrameOrigin, double* averageAbsError, double* maximalAbsError, Frame* groundTruth)
592 {
593  ocean_assert(input.isValid() && output.isValid());
594  ocean_assert(input.isPixelFormatCompatible(output.pixelFormat()));
595 
596  ocean_assert(!input_H_output.isSingular());
597  ocean_assert(backgroundColor != nullptr);
598 
599  const Scalar frameBorderEps = Scalar(0.5);
600 
601  ocean_assert(input.numberPlanes() == 1u);
602 
603  const unsigned int channels = input.channels();
604  ocean_assert(channels >= 1u);
605 
606  std::vector<T> result(channels, T(0));
607 
608  if (averageAbsError != nullptr)
609  {
610  *averageAbsError = NumericD::maxValue();
611  }
612 
613  if (maximalAbsError != nullptr)
614  {
615  *maximalAbsError = NumericD::maxValue();
616  }
617 
618  if (groundTruth != nullptr)
619  {
620  groundTruth->set(output.frameType(), false /*forceOwner*/, true /*forceWritable*/);
621  }
622 
623  double sumAbsError = 0.0;
624  double maxAbsError = 0.0;
625  unsigned long long measurements = 0ull;
626 
627  for (unsigned int yOutput = 0u; yOutput < output.height(); ++yOutput)
628  {
629  for (unsigned int xOutput = 0u; xOutput < output.width(); ++xOutput)
630  {
631  const T* const outputPixel = output.constpixel<T>(xOutput, yOutput);
632 
633  const Vector2 outputPosition = Vector2(Scalar(xOutput) + Scalar(interpolatedFrameOrigin.x()), Scalar(yOutput) + Scalar(interpolatedFrameOrigin.y()));
634  const Vector2 inputPosition = input_H_output * outputPosition;
635 
636  if (inputPosition.x() >= Scalar(0) && inputPosition.y() >= Scalar(0) && inputPosition.x() <= Scalar(input.width() - 1u) && inputPosition.y() <= Scalar(input.height() - 1u))
637  {
638  const unsigned int inputLeftPixel = (unsigned int)(inputPosition.x());
639  const unsigned int inputRightPixel = min(inputLeftPixel + 1u, input.width() - 1u);
640 
641  const unsigned int inputTopPixel = (unsigned int)(inputPosition.y());
642  const unsigned int inputBottomPixel = min(inputTopPixel + 1u, input.height() - 1u);
643 
644  const double rightFactor = double(inputPosition.x()) - double(inputLeftPixel);
645  const double bottomFactor = double(inputPosition.y()) - double(inputTopPixel);
646 
647  ocean_assert(rightFactor >= 0.0 && rightFactor <= 1.0);
648  ocean_assert(bottomFactor >= 0.0 && bottomFactor <= 1.0);
649 
650  const double leftFactor = 1.0 - rightFactor;
651  const double topFactor = 1.0 - bottomFactor;
652 
653  const T* const inputTopLeft = input.constpixel<T>(inputLeftPixel, inputTopPixel);
654  const T* const inputTopRight = input.constpixel<T>(inputRightPixel, inputTopPixel);
655 
656  const T* const inputBottomLeft = input.constpixel<T>(inputLeftPixel, inputBottomPixel);
657  const T* const inputBottomRight = input.constpixel<T>(inputRightPixel, inputBottomPixel);
658 
659  for (unsigned int n = 0u; n < channels; ++n)
660  {
661  const double top = double(inputTopLeft[n]) * leftFactor + double(inputTopRight[n]) * rightFactor;
662  const double bottom = double(inputBottomLeft[n]) * leftFactor + double(inputBottomRight[n]) * rightFactor;
663 
664  const double interpolated = top * topFactor + bottom * bottomFactor;
665 
666  result[n] = T(interpolated);
667  }
668 
669  // we do not check the result if we are very close to the frame boundaries
670  if (Numeric::isNotEqual(inputPosition.x(), Scalar(0), frameBorderEps) && Numeric::isNotEqual(inputPosition.x(), Scalar(input.width() - 1u), frameBorderEps)
671  && Numeric::isNotEqual(inputPosition.y(), Scalar(0), frameBorderEps) && Numeric::isNotEqual(inputPosition.y(), Scalar(input.height() - 1u), frameBorderEps))
672  {
673  for (unsigned int n = 0u; n < channels; ++n)
674  {
675  const double absError = NumericD::abs(double(result[n]) - double(outputPixel[n]));
676 
677  sumAbsError += absError;
678  maxAbsError = max(maxAbsError, absError);
679 
680  measurements++;
681  }
682  }
683 
684  if (groundTruth != nullptr)
685  {
686  memcpy(groundTruth->pixel<T>(xOutput, yOutput), result.data(), sizeof(T) * channels);
687  }
688  }
689  else
690  {
691  // we do not check the result if we are very close to the frame boundaries
692  if (Numeric::isNotEqual(inputPosition.x(), Scalar(0), frameBorderEps) && Numeric::isNotEqual(inputPosition.x(), Scalar(input.width() - 1u), frameBorderEps)
693  && Numeric::isNotEqual(inputPosition.y(), Scalar(0), frameBorderEps) && Numeric::isNotEqual(inputPosition.y(), Scalar(input.height() - 1u), frameBorderEps))
694  {
695  for (unsigned int n = 0u; n < channels; ++n)
696  {
697  const double absError = NumericD::abs(double(backgroundColor[n]) - double(outputPixel[n]));
698 
699  sumAbsError += absError;
700  maxAbsError = max(maxAbsError, absError);
701 
702  measurements++;
703  }
704  }
705 
706  if (groundTruth != nullptr)
707  {
708  memcpy(groundTruth->pixel<T>(xOutput, yOutput), backgroundColor, sizeof(T) * channels);
709  }
710  }
711  }
712  }
713 
714  ocean_assert(measurements != 0ull || input.width() <= 2u || input.height() <= 2u || output.width() <= 2u || output.height() <= 2u);
715 
716  if (averageAbsError && measurements != 0ull)
717  {
718  *averageAbsError = sumAbsError / double(measurements);
719  }
720 
721  if (maximalAbsError)
722  {
723  *maximalAbsError = maxAbsError;
724  }
725 }
726 
727 }
728 
729 }
730 
731 }
732 
733 #endif // META_OCEAN_TEST_TESTCV_TEST_FRAME_INTERPOLATOR_BILINEAR_H
This class implements a 2D pixel position with pixel precision.
Definition: PixelPosition.h:65
T y() const
Returns the vertical coordinate position of this object.
Definition: PixelPosition.h:470
T x() const
Returns the horizontal coordinate position of this object.
Definition: PixelPosition.h:458
This class implements Ocean's image class.
Definition: Frame.h:1760
const FrameType & frameType() const
Returns the frame type of this frame.
Definition: Frame.h:3743
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4416
T * pixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex=0u)
Returns the pointer to the data of a specific pixel.
Definition: Frame.h:4177
bool set(const FrameType &frameType, const bool forceOwner, const bool forceWritable=false, const Indices32 &planePaddingElements=Indices32(), const Timestamp &timestamp=Timestamp(false), bool *reallocated=nullptr)
Sets a new frame type for this frame.
const T * constpixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex=0u) const
Returns the pointer to the constant data of a specific pixel.
Definition: Frame.h:4218
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3111
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition: Frame.h:3151
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition: Frame.h:3121
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3116
bool isPixelFormatCompatible(const PixelFormat pixelFormat) const
Returns whether the pixel format of this frame type is compatible with a given pixel format.
Definition: Frame.h:3166
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition: Frame.h:3141
This class implements a 2D lookup object with values at the bins' corners defining the individual loo...
Definition: Lookup2.h:636
static T abs(const T value)
Returns the absolute value of a given value.
Definition: Numeric.h:1220
static bool isNotEqual(const T first, const T second)
Returns whether two values are not equal up to a small epsilon.
Definition: Numeric.h:2613
static constexpr T maxValue()
Returns the max scalar value.
Definition: Numeric.h:3244
bool isSingular() const
Returns whether this matrix is singular (and thus cannot be inverted).
Definition: SquareMatrix3.h:1341
This class implements a bilinear frame interpolation test.
Definition: TestFrameInterpolatorBilinear.h:36
static bool testResampleCameraImage(const double testDuration, Worker &worker)
Tests the function to re-sample a camera image.
static bool testSpecialCasesResize400x400To256x256_8BitPerChannel(const double testDuration)
Tests the special case resize function for image resolutions from 400x400 to 256x256.
static bool testLookup(const double testDuration, Worker &worker)
Tests the frame transformation function applying a lookup table.
static bool testSpecialCasesResize400x400To224x224_8BitPerChannel(const double testDuration)
Tests the special case resize function for image resolutions from 400x400 to 224x224.
static bool testRotateFrame(const unsigned int width, const unsigned int height, const double testDuration, Worker &worker)
Tests the frame rotate function.
static bool validateRotatedFrame(const Frame &source, const Frame &target, const Scalar anchorX, const Scalar anchorY, const Scalar angle)
Validates the rotation of a frame using a bilinear interpolation.
static bool testResize(const double testDuration, Worker &worker)
Tests the bilinear resize function.
static bool testInterpolatePixel(const double testDuration)
Tests the pixel interpolation function for frames with arbitrary data type.
static bool testLookup(const double testDuration, Worker &worker)
Tests the frame transformation function applying a lookup table.
static bool testPatchIntensitySum1Channel(const unsigned int width, const unsigned int height, const unsigned int patchWidth, const unsigned int patchHeight, const double testDuration)
Tests the intensity sum of an image patch with sub-pixel location in a 1-channel frame using an integ...
static bool testInterpolatePixel8BitPerChannel(const CV::PixelCenter pixelCenter, const double testDuration)
Tests the pixel interpolation function for frames with 8 bit per channel.
static bool testResampleCameraImage(const double testDuration, Worker &worker)
Tests the function to re-sample a camera image.
static bool testPatchIntensitySum1Channel(const unsigned int width, const unsigned int height, const double testDuration)
Tests the intensity sum of an image patch with sub-pixel location in a 1-channel frame using an integ...
static bool validateInterpolatePixel8BitPerChannel(const Frame &frame, const VectorT2< TScalar > &position, const CV::PixelCenter pixelCenter, const uint8_t *const interpolationResult, const TScalar threshold)
Validates a pixel interpolation result for frame with 8 bit per channel.
static bool testHomography(const double testDuration, Worker &worker)
Tests the homography transformation function supporting arbitrary pixel formats using a constant colo...
static bool testResize(const double testDuration, Worker &worker)
Tests the bilinear resize function supporting arbitrary data types.
static bool testAffine(const double testDuration, Worker &worker)
Tests the affine transformation function using a constant color for unknown image content.
static bool testResize(const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourceChannels, const unsigned int targetWidth, const unsigned int targetHeight, const double testDuration, Worker &worker)
Tests the bilinear resize function for arbitrary data types and for a given frame dimension and chann...
static bool testAffine(const unsigned int width, const unsigned int height, const unsigned int channels, const double testDuration, Worker &worker)
Tests the function for affine transformations (with constant color for unknown image content) for a g...
static bool test(const unsigned int width, const unsigned int height, const double testDuration, Worker &worker)
Tests all bilinear interpolation filter functions.
static void validateHomography(const Frame &input, const Frame &output, const SquareMatrix3 &input_H_output, const T *backgroundColor, const CV::PixelPositionI &interpolatedFrameOrigin, double *averageAbsError, double *maximalAbsError, Frame *groundTruth=nullptr)
Validates the homography interpolation function for (almost) arbitrary pixel formats (using a constan...
Definition: TestFrameInterpolatorBilinear.h:591
static bool testResizeExtremeResolutions(const double testDuration, Worker &worker)
Tests the bilinear resize function for extreme image resolutions.
static void validateScaleFrame(const unsigned char *source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const unsigned char *target, const unsigned int targetWidth, const unsigned int targetHeight, const double xTargetToSource, const double yTargetToSource, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, double *averageAbsErrorToInteger, unsigned int *maximalAbsErrorToInteger, unsigned char *groundTruth=nullptr)
Validates the bilinear frame resize function.
static bool testLookup(const unsigned int width, const unsigned int height, const unsigned int channels, const double testDuration, Worker &worker)
Tests the frame transformation function applying a lookup table.
static bool validatePatchIntensitySum1Channel(const Frame &yFrame, const unsigned int patchWidth, const unsigned int patchHeight, const Vector2 &center, const CV::PixelCenter pixelCenter, const Scalar intensity)
Validate the intensity sum of an image patch with sub-pixel location in a 1-channel frame.
static bool testHomographyMask(const unsigned int width, const unsigned int height, const unsigned int channels, const double testDuration, Worker &worker)
Tests the homography transformation function (with binary mask defining known and unknown image conte...
static bool validateLookup(const Frame &sourceFrame, const Frame &targetFrame, const LookupCorner2< Vector2 > &lookupTable, const bool offset, const T *backgroundColor)
Validates the frame transformation function applying a lookup table.
static bool testInterpolatePixel8BitPerChannel(const double testDuration)
Tests the pixel interpolation function for frames with 8 bit per channel.
static bool testInterpolatePixel(const CV::PixelCenter pixelCenter, const double testDuration)
Tests the pixel interpolation function for frames arbitrary data type.
static bool testLookupMask(const unsigned int width, const unsigned int height, const double testDuration, Worker &worker)
Tests the frame mask transformation function applying a lookup table.
static bool validateLookupMask(const Frame &sourceFrame, const Frame &targetFrame, const Frame &targetMask, const LookupCorner2< Vector2 > &lookupTable, const bool offset)
Validates the frame mask transformation function applying a lookup table.
static bool testHomographyMask(const double testDuration, Worker &worker)
Tests the homography transformation function defining a binary mask for known and unknown image conte...
static bool testResize(const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourceChannels, const unsigned int targetWidth, const unsigned int targetHeight, const double testDuration, Worker &worker)
Tests the bilinear resize function for a given frame dimension and channel number.
static bool testHomography(const unsigned int width, const unsigned int height, const unsigned int channels, const double testDuration, Worker &worker)
Tests the homography transformation function (with constant color for unknown image content) for arbi...
static bool validateHomographyMask8BitPerChannel(const Frame &frame, const Frame &interpolatedFrame, const Frame &interpolatedMask, const SquareMatrix3 &input_H_output, const CV::PixelPositionI &interpolatedFrameOrigin)
Validates the homography interpolation function (using a binary mask to define known and unknown imag...
static bool validateTransformation8BitPerChannel(const Frame &source, const Frame &validationTarget, const SquareMatrix3 &source_H_target, const uint8_t *backgroundColor, const CV::PixelPositionI &interpolatedFrameOrigin)
Validation function for the bilinear interpolation of 2D homogeneous image transformations (+ constan...
static void validateScaleFramePrecision7Bit(const uint8_t *source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const uint8_t *target, const unsigned int targetWidth, const unsigned int targetHeight, const double xSource_s_xTarget, const double ySource_s_yTarget, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, double *averageAbsError, double *maximalAbsError, uint8_t *groundTruth=nullptr)
Validates the bilinear frame resize function for uint8_t data types using 7-bit integer precision.
static bool validatePatchFrame8BitPerChannel(const uint8_t *const source, const uint8_t *const validationTarget, const uint32_t sourceWidth, const uint32_t sourceHeight, const Scalar x, const Scalar y, const uint32_t validationTargetWidth, const uint32_t validationTargetHeight, const uint32_t sourcePaddingElements, const uint32_t validationTargetPaddingElements)
Validate the bilinear extraction of frame patches.
static bool validateInterpolatePixel(const Frame &frame, const VectorT2< TScalar > &position, const CV::PixelCenter pixelCenter, const TTarget *const interpolationResult, const TScalar threshold)
Validates a pixel interpolation result for frame with arbitrary data type.
This class implements a vector with two elements.
Definition: Vector2.h:96
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
T minmax(const T &lowerBoundary, const T &value, const T &upperBoundary)
This function fits a given parameter into a specified value range.
Definition: base/Utilities.h:903
PixelCenter
Definition of individual centers of pixels.
Definition: CV.h:117
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