Ocean
Loading...
Searching...
No Matches
MarkerCandidate.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_CALIBRATION_MARKER_CANDIDATE_H
9#define META_OCEAN_CV_CALIBRATION_MARKER_CANDIDATE_H
10
14
16
17namespace Ocean
18{
19
20namespace CV
21{
22
23namespace Calibration
24{
25
26/// Forward declaration.
27class MarkerCandidate;
28
29/**
30 * Definition of a vector holding marker candidates.
31 * @ingroup cvcalibration
32 */
33using MarkerCandidates = std::vector<MarkerCandidate>;
34
35/**
36 * This class implements a candidate of a marker.
37 * The candidate of a marker can have individual levels of certainty:
38 * <pre>
39 * 1. The 16 border points of the marker are known, and the sign.
40 * 2. The 25 points of the marker are known.
41 * 3. The marker has a known id.
42 * 4. The marker has known neighbors.
43 * 5. The marker has a known coordinate, and thus is actually not a candidate anymore but a unique marker associated with a calibration board.
44 * </pre>
45 * @ingroup cvcalibration
46 */
47class OCEAN_CV_CALIBRATION_EXPORT MarkerCandidate : public Marker
48{
49 public:
50
51 /**
52 * Definition of an unordered map mapping pixel directions to marker candidate indices.
53 */
54 using NeighborMap = std::unordered_map<CV::PixelDirection, size_t>;
55
56 public:
57
58 /**
59 * Creates an invalid marker candidate.
60 */
61 MarkerCandidate() = default;
62
63 /**
64 * Creates a new marker candidate object with indices of the 16 border points of the marker.
65 * The border indices in the marker are defined as follows:
66 * <pre>
67 * ----------------
68 * | 0 1 2 3 4 |
69 * | 15 5 |
70 * | 14 6 |
71 * | 13 7 |
72 * | 12 11 10 9 8 |
73 * ----------------
74 * </pre>
75 * The provided border indices can be provided in clockwise or counter-clockwise order.<br>
76 * Further, the indices can start at any marker corner, the correct order and correct start corner will be determined automatically once more and more information is known/provided.
77 * @param borderIndices The indices of the border points of the marker, the signals of all border points must be identical, must be 16 indices
78 * @param points The points from which the border indices are defined, must be valid
79 */
80 MarkerCandidate(const Indices32& borderIndices, const Points& points);
81
82 /**
83 * Returns the index of a point of the marker.
84 * The indices in the marker are defined as follows:
85 * <pre>
86 * ----------------
87 * | 0 1 2 3 4 |
88 * | 5 6 7 8 9 |
89 * | 10 11 12 13 14 |
90 * | 15 16 17 18 19 |
91 * | 20 21 22 23 24 |
92 * ----------------
93 * </pre>
94 * @param indexInMarker The index of the point in the marker, with range [0, 24]
95 * @return The index of the point as defined in the points vector, -1 if the point is not known
96 */
97 Index32 pointIndex(const size_t indexInMarker) const;
98
99 /**
100 * Returns the index of a point in the border of the marker.
101 * The border indices in the marker are defined as follows:
102 * <pre>
103 * ----------------
104 * | 0 1 2 3 4 |
105 * | 15 5 |
106 * | 14 6 |
107 * | 13 7 |
108 * | 12 11 10 9 8 |
109 * ----------------
110 * </pre>
111 * @param indexInBorder The index of the point in the border of the marker, with range [0, 15]
112 * @return The index of the point as defined in the points vector, -1 if the point is not known
113 */
114 Index32 borderIndex(const size_t indexInBorder) const;
115
116 /**
117 * Sets the index of a point of the marker.
118 * @param indexInMarker The index of the point in the marker, with range [0, 24]
119 * @param pointIndex The index of the point as defined in the points vector, -1 if the point is not known
120 */
121 void setPointIndex(const size_t indexInMarker, const Index32 pointIndex);
122
123 /**
124 * Sets the coordinate of the marker.
125 * The coordinate of the marker describes the position of the marker within a calibration board.
126 * @param markerCoordinate The coordinate of the marker to set
127 */
128 inline void setMarkerCoordinate(const CV::PixelPosition& markerCoordinate);
129
130 /**
131 * Returns the position of this marker within a calibration board.
132 * The coordinate of the marker describes the position of the marker within a calibration board.
133 * @return The marker's coordinate, invalid if unknown
134 * @see hasMarkerCoordinate().
135 */
136 inline const CV::PixelPosition& markerCoordinate() const;
137
138 /**
139 * Returns the marker candidate rotated by a multiple of 90 degree.
140 * @param degree The number of 90 degree to rotate, in clockwise order, possible values are {-360, -270, ..., 0, ..., 270, 360}
141 * @return The rotated marker candidate
142 */
143 MarkerCandidate rotatedClockWise(const int degree) const;
144
145 /**
146 * Rotates this marker candidate by a multiple of 90 degree.
147 * Rotating the marker candidate will also rotate the directions of the neighbors accordingly.
148 * @param degree The number of 90 degree to rotate, in clockwise order, possible values are {-360, -270, ..., 0, ..., 270, 360}
149 */
150 void rotateClockWise(const int degree);
151
152 /**
153 * Returns whether this marker candidate is a neighbor of a given marker candidate.
154 * The neighboring marker candidate must have a different sign (as neighboring markers have do not have the same sign/color).
155 * @param markerCandidate The marker candidate to check, must be valid
156 * @param points The points associated with both marker candidates
157 * @param localEdge The resulting local edge of this marker candidate at which the neighbor marker candidate is located, in case the marker candidate is a neighbor
158 * @param neighborEdge The resulting edge of the neighbor marker candidate at which this marker candidate is located, in case the marker candidate
159 * @param maxDistancePercentage The maximal distance between the predicted corner and the actual corner of a neighboring marker candidate, in relation to the distance between the two marker candidate corners, with range (0, infinity)
160 * @return True, if the provided marker candidate is a neighbor of this marker candidate
161 */
162 bool isNeighbor(const MarkerCandidate& markerCandidate, const Points& points, CV::PixelDirection& localEdge, CV::PixelDirection& neighborEdge, const Scalar maxDistancePercentage) const;
163
164 /**
165 * Returns whether this marker candidate has an edge which is close to a predicted edge.
166 * This marker candidate must have valid border indices for this check.
167 * @param predictedCornerA The first corner of the predicted edge
168 * @param predictedCornerB The second corner of the predicted edge
169 * @param points The points associated with this marker candidate
170 * @param maxSqrDistanceA The maximal square distance between the predicted first corner and the actual first corner of this marker candidate, with range [0, infinity)
171 * @param maxSqrDistanceB The maximal square distance between the predicted second corner and the actual second corner of this marker candidate, with range [0, infinity)
172 * @return The direction in which the predicted edge is located in this marker candidate, PD_INVALID if the predicted edge is not close to an edge of this marker candidate
173 */
174 CV::PixelDirection hasEdge(const Vector2& predictedCornerA, const Vector2& predictedCornerB, const Points& points, const Scalar maxSqrDistanceA, const Scalar maxSqrDistanceB) const;
175
176 /**
177 * Adds a marker candidate as neighbor to this marker candidate.
178 * The neighbor direction is defined as the direction from this marker candidate to the neighbor marker candidate.
179 * @param neighborDirection The direction in which the neighbor marker candidate is located, must not be a diagonal direction
180 * @param neighborMarkerCandidateIndex The index of the neighboring marker candidate
181 */
182 inline void addNeighbor(const CV::PixelDirection neighborDirection, const size_t neighborMarkerCandidateIndex);
183
184 /**
185 * Returns the known neighbors of this marker candidate.
186 * @return The marker candidate's neighbors
187 */
188 inline const NeighborMap& neighbors() const;
189
190 /**
191 * Returns the center position of this marker candidate.
192 * The center position is defined as the average of all known points of the marker candidate.
193 * @param points The points associated with this marker candidate, must be valid
194 * @return The center position of this marker candidate
195 */
196 Vector2 center(const Points& points) const;
197
198 /**
199 * Returns whether this marker candidate has 16 valid border point indices.
200 * Having 16 valid border indices is the minimal requirement for a marker candidate.
201 * @return True, if so
202 * @see hasValidIndices().
203 */
205
206 /**
207 * Returns whether this marker candidate has 25 valid point indices.
208 * Having 25 valid point indices means that all points of the marker are known but does not yet mean that the marker has a valid id.
209 * @return True, if so
210 */
211 bool hasValidIndices() const;
212
213 /**
214 * Returns whether this marker candidate has at least one known neighbor candidate marker.
215 * @return True, if so
216 */
217 inline bool hasNeighbor() const;
218
219 /**
220 * Returns whether this marker candidate has at least one known neighbor with a known valid marker id.
221 * @param markerCandidates The marker candidates from which the neighbors are checked, must be valid
222 * @return True, if so
223 */
224 bool hasNeighborWithMarkerId(const MarkerCandidates& markerCandidates) const;
225
226 /**
227 * Returns whether a specific marker candidate is a known neighbor of this marker candidate.
228 * @param markerCandidateIndex The index of the marker candidate to check, with range [0, markerCandidates.size())
229 * @return The direction in which the marker candidate is located, PD_INVALID if the marker candidate is not a known neighbor
230 */
231 CV::PixelDirection neighborDirection(const size_t markerCandidateIndex) const;
232
233 /**
234 * Returns whether this marker candidate has a known marker coordinate.
235 * Having a valid marker coordinate means that this candidate has been associated with a unique position within a calibration board.
236 * @return True, if so
237 */
238 inline bool hasMarkerCoordinate() const;
239
240 /**
241 * Determines the id of the marker candidate.
242 * The marker id is determined based on the 25 known points of the marker candidate.<br>
243 * @param points The points associated with this marker candidate, must be valid
244 * @return True, if succeeded; False, if the marker candidate does not have 25 valid point indices or if the points do not match with any known marker layout
245 */
246 bool determineMarkerId(const Points& points);
247
248 /**
249 * Returns whether this marker candidate has been initialized with valid border indices.
250 * A valid marker candidate does not yet mean that the candidate is actually a valid marker with known id, markers coordinate etc.
251 * @return True, if so
252 */
253 inline bool isValid() const;
254
255 /**
256 * Returns the 25 marker indices for given 16 border indices.
257 * @param borderIndices The border indices of the marker candidate, must be 16 indices
258 * @param clockWise True, to receive the indices in clockwise order; False, to receive the indices in counter-clockwise order
259 * @return The resulting 25 marker indices, the inner indices will be invalid
260 */
261 static Indices32 borderIndicesToMarkerIndices(const Indices32& borderIndices, const bool clockWise);
262
263 /**
264 * Rotates 25 marker indices clockwise by 90 degree.
265 * @param indices The 25 marker indices to rotate
266 * @return The resulting rotated 25 marker indices
267 */
269
270 /**
271 * Rotates the 25 marker indices by 180 degree.
272 * @param indices The 25 marker indices to rotate
273 * @return The resulting rotated 25 marker indices
274 */
275 static Indices32 rotateIndices180(const Indices32& indices);
276
277 /**
278 * Rotates 25 marker indices counter-clockwise by 90 degree.
279 * @param indices The 25 marker indices to rotate
280 * @return The resulting rotated 25 marker indices
281 */
283
284 /**
285 * Removes a marker candidate from a vector of marker candidates.
286 * Further, the marker candidate will be removed as known neighbor from all other marker candidates.
287 * @param markerCandidates The vector of marker candidates from which the marker candidate will be removed, must be valid
288 * @param index The index of the marker candidate to be removed, with range [0, markerCandidates.size())
289 */
290 static void removeMarkerCandidate(MarkerCandidates& markerCandidates, const size_t index);
291
292 protected:
293
294 /// The 25 indices of the points of the marker, empty if invalid.
296
297 /// The map mapping the four neighbor directions to other marker candidates.
299
300 /// The coordinate of the marker, invalid if unknown.
302};
303
304inline void MarkerCandidate::setMarkerCoordinate(const CV::PixelPosition& markerCoordinate)
305{
306 ocean_assert(!markerCoordinate_.isValid());
308}
309
311{
312 ocean_assert(markerCoordinate_.isValid());
313 return markerCoordinate_;
314}
315
316inline void MarkerCandidate::addNeighbor(const CV::PixelDirection neighborDirection, const size_t neighborMarkerCandidateIndex)
317{
319 ocean_assert(neighborMap_.find(neighborDirection) == neighborMap_.cend());
320
321 neighborMap_[neighborDirection] = neighborMarkerCandidateIndex;
322}
323
325{
326 return neighborMap_;
327}
328
330{
331 return !neighborMap_.empty();
332}
333
335{
336 return markerCoordinate_.isValid();
337}
338
339inline bool MarkerCandidate::isValid() const
340{
341 return pointIndices_.size() == 25;
342}
343
344}
345
346}
347
348}
349
350#endif // META_OCEAN_CV_CALIBRATION_MARKER_CANDIDATE_H
This class implements a candidate of a marker.
Definition MarkerCandidate.h:48
static Indices32 rotateIndicesClockWise90(const Indices32 &indices)
Rotates 25 marker indices clockwise by 90 degree.
bool isValid() const
Returns whether this marker candidate has been initialized with valid border indices.
Definition MarkerCandidate.h:339
bool hasValidBorderIndices() const
Returns whether this marker candidate has 16 valid border point indices.
bool isNeighbor(const MarkerCandidate &markerCandidate, const Points &points, CV::PixelDirection &localEdge, CV::PixelDirection &neighborEdge, const Scalar maxDistancePercentage) const
Returns whether this marker candidate is a neighbor of a given marker candidate.
CV::PixelDirection hasEdge(const Vector2 &predictedCornerA, const Vector2 &predictedCornerB, const Points &points, const Scalar maxSqrDistanceA, const Scalar maxSqrDistanceB) const
Returns whether this marker candidate has an edge which is close to a predicted edge.
Vector2 center(const Points &points) const
Returns the center position of this marker candidate.
MarkerCandidate()=default
Creates an invalid marker candidate.
bool hasValidIndices() const
Returns whether this marker candidate has 25 valid point indices.
bool hasNeighbor() const
Returns whether this marker candidate has at least one known neighbor candidate marker.
Definition MarkerCandidate.h:329
static Indices32 rotateIndices180(const Indices32 &indices)
Rotates the 25 marker indices by 180 degree.
void setMarkerCoordinate(const CV::PixelPosition &markerCoordinate)
Sets the coordinate of the marker.
Definition MarkerCandidate.h:304
void rotateClockWise(const int degree)
Rotates this marker candidate by a multiple of 90 degree.
void setPointIndex(const size_t indexInMarker, const Index32 pointIndex)
Sets the index of a point of the marker.
MarkerCandidate(const Indices32 &borderIndices, const Points &points)
Creates a new marker candidate object with indices of the 16 border points of the marker.
const CV::PixelPosition & markerCoordinate() const
Returns the position of this marker within a calibration board.
Definition MarkerCandidate.h:310
static Indices32 rotateIndicesCounterClockWise90(const Indices32 &indices)
Rotates 25 marker indices counter-clockwise by 90 degree.
void addNeighbor(const CV::PixelDirection neighborDirection, const size_t neighborMarkerCandidateIndex)
Adds a marker candidate as neighbor to this marker candidate.
Definition MarkerCandidate.h:316
std::unordered_map< CV::PixelDirection, size_t > NeighborMap
Definition of an unordered map mapping pixel directions to marker candidate indices.
Definition MarkerCandidate.h:54
bool hasMarkerCoordinate() const
Returns whether this marker candidate has a known marker coordinate.
Definition MarkerCandidate.h:334
const NeighborMap & neighbors() const
Returns the known neighbors of this marker candidate.
Definition MarkerCandidate.h:324
NeighborMap neighborMap_
The map mapping the four neighbor directions to other marker candidates.
Definition MarkerCandidate.h:298
static Indices32 borderIndicesToMarkerIndices(const Indices32 &borderIndices, const bool clockWise)
Returns the 25 marker indices for given 16 border indices.
Index32 pointIndex(const size_t indexInMarker) const
Returns the index of a point of the marker.
static void removeMarkerCandidate(MarkerCandidates &markerCandidates, const size_t index)
Removes a marker candidate from a vector of marker candidates.
MarkerCandidate rotatedClockWise(const int degree) const
Returns the marker candidate rotated by a multiple of 90 degree.
Index32 borderIndex(const size_t indexInBorder) const
Returns the index of a point in the border of the marker.
bool hasNeighborWithMarkerId(const MarkerCandidates &markerCandidates) const
Returns whether this marker candidate has at least one known neighbor with a known valid marker id.
bool determineMarkerId(const Points &points)
Determines the id of the marker candidate.
CV::PixelDirection neighborDirection(const size_t markerCandidateIndex) const
Returns whether a specific marker candidate is a known neighbor of this marker candidate.
CV::PixelPosition markerCoordinate_
The coordinate of the marker, invalid if unknown.
Definition MarkerCandidate.h:301
Indices32 pointIndices_
The 25 indices of the points of the marker, empty if invalid.
Definition MarkerCandidate.h:295
This class implements the base class for a marker in a calibration board.
Definition Marker.h:27
bool isValid() const
Returns whether this pixel position object holds two valid parameters.
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition Base.h:96
uint32_t Index32
Definition of a 32 bit index value.
Definition Base.h:84
PixelDirection
Definition of individual directions with pixel accuracy.
Definition CV.h:85
@ PD_WEST
Definition CV.h:93
@ PD_EAST
Definition CV.h:101
@ PD_SOUTH
Definition CV.h:97
@ PD_NORTH
Definition CV.h:89
std::vector< Point > Points
Definition of a vector holding points.
Definition cv/calibration/Point.h:31
std::vector< MarkerCandidate > MarkerCandidates
Definition of a vector holding marker candidates.
Definition MarkerCandidate.h:33
float Scalar
Definition of a scalar type.
Definition Math.h:129
The namespace covering the entire Ocean framework.
Definition Accessor.h:15