Ocean
Loading...
Searching...
No Matches
TestNonMaximumSuppression.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_NON_MAXIMUM_SUPPRESSION_H
9#define META_OCEAN_TEST_TESTCV_TEST_NON_MAXIMUM_SUPPRESSION_H
10
12
14
15#include "ocean/base/Frame.h"
16#include "ocean/base/Worker.h"
17
19
20namespace Ocean
21{
22
23namespace Test
24{
25
26namespace TestCV
27{
28
29/**
30 * This class tests the implementation of the NonMaximumSuppression class.
31 * @ingroup testcv
32 */
33class OCEAN_TEST_CV_EXPORT TestNonMaximumSuppression
34{
35 protected:
36
37 /**
38 * Definition of a location combining a strength parameter.
39 */
41
42 /**
43 * Definition of a vector holding locations.
44 */
45 using StrengthPositions = std::vector<StrengthPosition>;
46
47 /**
48 * Definition of a set holding locations.
49 */
50 using StrengthPositionSet = std::set<StrengthPosition>;
51
52 public:
53
54 /**
55 * Tests the entire functionality.
56 * @param width The width of the test frame in pixel, with range [3, infinity)
57 * @param height The height of the test frame in pixel, with range [3, infinity)
58 * @param testDuration Number of seconds for each test, with range (0, infinity)
59 * @param worker The worker object
60 * @param selector Test selector for filtering sub-tests; default runs all tests
61 * @return True, if succeeded
62 */
63 static bool test(const unsigned int width, const unsigned int height, const double testDuration, Worker& worker, const TestSelector& selector = TestSelector());
64
65 /**
66 * Tests the non maximum suppression within a frame.
67 * @param width The width of the test frame in pixel, with range [3, infinity)
68 * @param height The height of the test frame in pixel, with range [3, infinity)
69 * @param subFrameWidth The width of the actual area of application, with range [2, width]
70 * @param subFrameHeight The height of the actual area of application, with range [2, height]
71 * @param strictMaximum True, to search for a strict maximum (larger than all eight neighbors); False, to allow equal values in the upper left neighborhood
72 * @param testDuration Number of seconds for each test, with range (0, infinity)
73 * @param worker The worker object
74 * @return True, if succeeded
75 */
76 static bool testSuppressionInFrame(const unsigned int width, const unsigned int height, const unsigned int subFrameWidth, const unsigned int subFrameHeight, const bool strictMaximum, const double testDuration, Worker& worker);
77
78 /**
79 * Tests the non minimum suppression within a frame (finding local minima).
80 * @param width The width of the test frame in pixel, with range [3, infinity)
81 * @param height The height of the test frame in pixel, with range [3, infinity)
82 * @param strictMaximum True, to search for a strict minimum (smaller than all eight neighbors); False, to allow equal values in the lower right neighborhood
83 * @param testDuration Number of seconds for each test, with range (0, infinity)
84 * @param worker The worker object
85 * @return True, if succeeded
86 */
87 static bool testSuppressionInFrameMinimum(const unsigned int width, const unsigned int height, const bool strictMaximum, const double testDuration, Worker& worker);
88
89 /**
90 * Tests the non maximum suppression within a dataset of strength positions.
91 * @param testDuration Number of seconds for each test, with range (0, infinity)
92 * @return True, if succeeded
93 */
94 static bool testSuppressionInStrengthPositions(const double testDuration);
95
96 /**
97 * Tests the non maximum suppression within a dataset of strength positions.
98 * @param testDuration Number of seconds for each test, with range (0, infinity)
99 * @return True, if succeeded
100 * @tparam TCoordinate The data type of a scalar coordinate
101 * @tparam TStrength The data type of the strength parameter
102 */
103 template <typename TCoordinate, typename TStrength>
104 static bool testSuppressionInStrengthPositions(const double testDuration);
105
106 /**
107 * Tests the 1D precise peak location function.
108 * @return True, if succeeded
109 * @tparam T The data type of the scalar to be used, either 'float' or 'double'
110 */
111 template <typename T>
113
114 /**
115 * Tests the 2D precise peak location function.
116 * @return True, if succeeded
117 * @tparam T The data type of the scalar to be used, either 'float' or 'double'
118 */
119 template <typename T>
121
122 /**
123 * Tests the determinePrecisePeakLocationNxN function.
124 * @return True, if succeeded
125 * @tparam T The data type of the scalar to be used, either 'float' or 'double'
126 */
127 template <typename T>
129
130 /**
131 * Tests the iterative precise peak location function.
132 * @return True, if succeeded
133 * @tparam T The data type of the scalar to be used, either 'float' or 'double'
134 */
135 template <typename T>
137
138 /**
139 * Tests the candidate lookup function.
140 * @param testDuration Number of seconds for each test, with range (0, infinity)
141 * @return True, if succeeded
142 */
143 static bool testCandidate(const double testDuration);
144
145 protected:
146
147 /**
148 * Creates a test frame with artificial feature points.
149 * @param yFrame The frame to which the feature points will be added, must have pixel format FORMAT_Y8, must be valid
150 * @param features The number of feature points to create, with range [0, infinity)
151 * @param featurePointStrength The strength of the feature points to create, with range [1, 255]
152 */
153 static void createFeaturePoints(Frame& yFrame, const unsigned int features, const uint8_t featurePointStrength = 255u);
154
155 /**
156 * Determines the locations of the extrema by a standard implementation.
157 * @param yFrame The frame providing the feature points, with pixel format FORMAT_Y8, must be valid
158 * @param subRegionLeft The left location of the upper left corner of the sub-region in which the points will be determined, with range [0, width - 1]
159 * @param subRegionTop The top location of the upper left corner of the sub-region in which the points will be determined, with range [0, height - 1]
160 * @param subRegionWidth The width of the sub-region in which the points will be determined, with range [width - subRegionLeft]
161 * @param subRegionHeight The height of the sub-region in which the points will be determined, with range [height - subRegionTop]
162 * @param minimalThreshold The minimal value a pixel must have to count as feature candidate
163 * @param strictMaximum True, to search for a strict maximum (larger than all eight neighbors); False, to allow equal values in the upper left neighborhood
164 * @param worker Optional worker object to distribute the computation
165 * @return The resulting locations
166 */
167 static inline StrengthPositions determineFeaturePoints(const Frame& yFrame, const unsigned int subRegionLeft, const unsigned int subRegionTop, const unsigned int subRegionWidth, const unsigned int subRegionHeight, const uint8_t minimalThreshold, const bool strictMaximum, Worker* worker = nullptr);
168
169 /**
170 * Determines the locations of the extrema by a standard implementation.
171 * @param yFrame The frame providing the feature points, with pixel format FORMAT_Y8, must be valid
172 * @param minimalThreshold The minimal value a pixel must have to count as feature candidate
173 * @param strictMaximum True, to search for a strict maximum (larger than all eight neighbors); False, to allow equal values in the upper left neighborhood
174 * @param lock Optional lock which must be defined if this function is executed on several threads in parallel
175 * @param locations The resulting locations in pixel coordinates
176 * @param firstColumn The first column to be handled, with range [1, width - 2]
177 * @param numberColumns The number of columns to be handled, with range [1, width - firstColumn - 1]
178 * @param firstRow The first row to be handled, with range [1, height - 2]
179 * @param numberRows The number of rows to be handled, with range [1, height - firstRow - 1]
180 */
181 static void determineFeaturePointsSubset(const Frame* yFrame, const uint8_t minimalThreshold, const bool strictMaximum, Lock* lock, StrengthPositions* locations, const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows);
182
183 /**
184 * Creates a Y8 frame containing a Gaussian blob at a sub-pixel position.
185 * The frame is filled with a 2D Gaussian centered at `(centerX, centerY)` with the given standard deviation.
186 * When `darkBlob` is false the result is a bright blob on a dark background (pixel = 255 * gauss);
187 * when `darkBlob` is true the result is a dark blob on a bright background (pixel = 255 * (1 - gauss)).
188 * @param frameWidth The width of the resulting frame in pixels, with range [1, infinity)
189 * @param frameHeight The height of the resulting frame in pixels, with range [1, infinity)
190 * @param centerX The horizontal sub-pixel center of the Gaussian blob
191 * @param centerY The vertical sub-pixel center of the Gaussian blob
192 * @param sigma The standard deviation of the Gaussian, with range (0, infinity)
193 * @param darkBlob True, to create a dark blob on a bright background; False, to create a bright blob on a dark background
194 * @tparam T The data type of the scalar to be used, either 'float' or 'double'
195 */
196 template <typename T>
197 static Frame createGaussianFrame(const unsigned int frameWidth, const unsigned int frameHeight, const T centerX, const T centerY, const T sigma, const bool darkBlob);
198
199 /**
200 * Compares two IndexPair32 positions by y-coordinate first, then by x-coordinate.
201 * @param a The first position (x, y)
202 * @param b The second position (x, y)
203 * @return True, if a comes before b
204 */
205 static inline bool comparePositionYX(const IndexPair32& a, const IndexPair32& b);
206};
207
208inline TestNonMaximumSuppression::StrengthPositions TestNonMaximumSuppression::determineFeaturePoints(const Frame& yFrame, const unsigned int subRegionLeft, const unsigned int subRegionTop, const unsigned int subRegionWidth, const unsigned int subRegionHeight, const uint8_t minimalThreshold, const bool strictMaximum, Worker* worker)
209{
210 ocean_assert(yFrame.isValid() && yFrame.pixelFormat() == FrameType::FORMAT_Y8);
211 ocean_assert(subRegionLeft + subRegionWidth <= yFrame.width() && subRegionTop + subRegionHeight <= yFrame.height());
212
213 const unsigned int firstColumn = std::max(1u, subRegionLeft);
214 const unsigned int firstRow = std::max(1u, subRegionTop);
215
216 const unsigned int endColumn = std::min(subRegionLeft + subRegionWidth, yFrame.width() - 1u);
217 const unsigned int endRow = std::min(subRegionTop + subRegionHeight, yFrame.height() - 1u);
218
219 const unsigned int numberColumns = endColumn - firstColumn;
220 const unsigned int numberRows = endRow - firstRow;
221
222 StrengthPositions result;
223
224 if (worker)
225 {
226 Lock lock;
227 worker->executeFunction(Worker::Function::createStatic(&determineFeaturePointsSubset, &yFrame, minimalThreshold, strictMaximum, &lock, &result, firstColumn, numberColumns, 0u, 0u), firstRow, numberRows);
228 }
229 else
230 {
231 determineFeaturePointsSubset(&yFrame, minimalThreshold, strictMaximum, nullptr, &result, firstColumn, numberColumns, firstRow, numberRows);
232 }
233
234 return result;
235}
236
238{
239 return a.second < b.second || (a.second == b.second && a.first < b.first);
240}
241
242}
243
244}
245
246}
247
248#endif // META_OCEAN_TEST_TESTCV_TEST_NON_MAXIMUM_SUPPRESSION_H
This class extends a 2D position by a third parameter storing a strength value.
Definition NonMaximumSuppression.h:76
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition Caller.h:2877
This class implements Ocean's image class.
Definition Frame.h:1879
bool isValid() const
Returns whether this frame is valid.
Definition Frame.h:4612
@ FORMAT_Y8
Pixel format for grayscale images with byte order Y and 8 bits per pixel.
Definition Frame.h:594
unsigned int width() const
Returns the width of the frame format in pixel.
Definition Frame.h:3241
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition Frame.h:3251
unsigned int height() const
Returns the height of the frame in pixel.
Definition Frame.h:3246
This class implements a recursive lock object.
Definition Lock.h:31
This class tests the implementation of the NonMaximumSuppression class.
Definition TestNonMaximumSuppression.h:34
static bool testDeterminePrecisePeakLocationIterativeNxN()
Tests the iterative precise peak location function.
static bool testSuppressionInFrame(const unsigned int width, const unsigned int height, const unsigned int subFrameWidth, const unsigned int subFrameHeight, const bool strictMaximum, const double testDuration, Worker &worker)
Tests the non maximum suppression within a frame.
std::vector< StrengthPosition > StrengthPositions
Definition of a vector holding locations.
Definition TestNonMaximumSuppression.h:45
static void determineFeaturePointsSubset(const Frame *yFrame, const uint8_t minimalThreshold, const bool strictMaximum, Lock *lock, StrengthPositions *locations, const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows)
Determines the locations of the extrema by a standard implementation.
static bool comparePositionYX(const IndexPair32 &a, const IndexPair32 &b)
Compares two IndexPair32 positions by y-coordinate first, then by x-coordinate.
Definition TestNonMaximumSuppression.h:237
std::set< StrengthPosition > StrengthPositionSet
Definition of a set holding locations.
Definition TestNonMaximumSuppression.h:50
static bool testSuppressionInStrengthPositions(const double testDuration)
Tests the non maximum suppression within a dataset of strength positions.
static bool testSuppressionInFrameMinimum(const unsigned int width, const unsigned int height, const bool strictMaximum, const double testDuration, Worker &worker)
Tests the non minimum suppression within a frame (finding local minima).
static bool testDeterminePrecisePeakLocation1()
Tests the 1D precise peak location function.
static bool test(const unsigned int width, const unsigned int height, const double testDuration, Worker &worker, const TestSelector &selector=TestSelector())
Tests the entire functionality.
static StrengthPositions determineFeaturePoints(const Frame &yFrame, const unsigned int subRegionLeft, const unsigned int subRegionTop, const unsigned int subRegionWidth, const unsigned int subRegionHeight, const uint8_t minimalThreshold, const bool strictMaximum, Worker *worker=nullptr)
Determines the locations of the extrema by a standard implementation.
Definition TestNonMaximumSuppression.h:208
static Frame createGaussianFrame(const unsigned int frameWidth, const unsigned int frameHeight, const T centerX, const T centerY, const T sigma, const bool darkBlob)
Creates a Y8 frame containing a Gaussian blob at a sub-pixel position.
static void createFeaturePoints(Frame &yFrame, const unsigned int features, const uint8_t featurePointStrength=255u)
Creates a test frame with artificial feature points.
static bool testSuppressionInStrengthPositions(const double testDuration)
Tests the non maximum suppression within a dataset of strength positions.
static bool testDeterminePrecisePeakLocation2()
Tests the 2D precise peak location function.
static bool testDeterminePrecisePeakLocationNxN()
Tests the determinePrecisePeakLocationNxN function.
static bool testCandidate(const double testDuration)
Tests the candidate lookup function.
This class implements a test selector that parses test function strings and determines which tests sh...
Definition TestSelector.h:51
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
std::pair< Index32, Index32 > IndexPair32
Definition of a pair holding 32 bit indices.
Definition Base.h:138
The namespace covering the entire Ocean framework.
Definition Accessor.h:15