Ocean
CalibrationPatternDetector.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_DETECTOR_CALIBRATION_PATTERN_DETECTOR_H
9 #define META_OCEAN_CV_DETECTOR_CALIBRATION_PATTERN_DETECTOR_H
10 
13 
14 #include "ocean/base/Frame.h"
15 #include "ocean/base/Lock.h"
16 #include "ocean/base/Timestamp.h"
17 #include "ocean/base/Worker.h"
18 
20 
21 namespace Ocean
22 {
23 
24 namespace CV
25 {
26 
27 namespace Detector
28 {
29 
30 /**
31  * This class implements a detector for calibration patterns.
32  * The calibration pattern is composed by a rectangular grid of black quadratic boxes.<br>
33  * All boxes must have the same size the white space between the boxes must match the box size.<br>
34  * @ingroup cvdetector
35  */
36 class OCEAN_CV_DETECTOR_EXPORT CalibrationPatternDetector
37 {
38  public:
39 
40  /**
41  * Definition of a (row) vector holding 2D positions.
42  */
43  typedef std::vector<Vector2> PatternRow;
44 
45  /**
46  * Definition of a vector holding rows.
47  */
48  typedef std::vector<PatternRow> PatternRows;
49 
50  /**
51  * Redefinition of a calibration pattern.
52  */
54 
55  protected:
56 
57  /**
58  * Definition of a threshold container for tracking parameters.
59  */
61  {
62  public:
63 
64  /**
65  * Creates a new threshold object.
66  * @param width The width of the camera frame for which the threshold is specified in pixel, with range [1, infinity)
67  * @param height The height of the camera frame for which the threshold is specified in pixel, with range [1, infinity)
68  * @param harrisCorners Strength threshold for Harris corners
69  * @param maximalDistance Maximal pixel distance between predicted and real corner, with range (0, infinity)
70  */
71  inline TrackingThresholds(const unsigned int width, const unsigned int height, const unsigned int harrisCorners, const Scalar maximalDistance);
72 
73  /**
74  * Returns the strength threshold of the Harris corner.
75  * @return The threshold of the corner detector
76  */
77  inline unsigned int harrisCornerThreshold() const;
78 
79  /**
80  * Returns the maximal distance between predicted and real corner, in pixel.
81  * @param width The width of the camera frame for which the distance is requested in pixel, with range [1, infinity)
82  * @param height The height of the camera frame for which the distance is requested in pixel, with range [1, infinity)
83  * @return The maximal distance, with range (0, infinity)
84  */
85  inline Scalar maximalCornerDistance(const unsigned int width, const unsigned int height) const;
86 
87  protected:
88 
89  /// The inverted diagonal distance between two opposite corners inside the camera frame.
91 
92  /// Strength threshold for Harris corners.
93  const unsigned int harrisCornerThreshold_;
94 
95  /// Maximal pixel distance between predicted and real corner.
97  };
98 
99  /**
100  * Definition of a threshold container for detection parameters.
101  */
103  {
104  public:
105 
106  /**
107  * Creates a new threshold object.
108  * @param width The width of the camera frame for which the threshold is specified in pixel, with range [1, infinity)
109  * @param height The height of the camera frame for which the threshold is specified in pixel, with range [1, infinity)
110  * @param harrisCorners Strength threshold for Harris corners
111  * @param maximalDistance Maximal pixel distance between predicted and real corner, with range (0, infinity)
112  * @param maximalParallelAngle Maximal angle between two lines so that they still count as parallel
113  * @param orientationError The expected orientation error each provided line can have e.g., due to measurement/detection inaccuracies, in radian with range [0, PI/2)
114  */
115  inline DetectionThresholds(const unsigned int width, const unsigned int height, const unsigned int harrisCorners, const Scalar maximalDistance, const Scalar maximalParallelAngle, const Scalar orientationError);
116 
117  /**
118  * Returns the maximal angle between two lines so that they still count as parallel.
119  * @return The maximal angle in radian, with range [0, PI/2)
120  */
121  inline Scalar maximalParallelAngle() const;
122 
123  /**
124  * The expected orientation error each provided line can have e.g., due to measurement/detection inaccuracies, in radian with range [0, PI/2)
125  * @return The expected error in radian, with range [0, PI/2)
126  */
127  inline Scalar orientationError() const;
128 
129  protected:
130 
131  /// Maximal angle between two lines so that they still count as parallel in radian, with range [0, PI/2).
133 
134  /// The expected orientation error each provided line can have e.g., due to measurement/detection inaccuracies, in radian with range [0, PI/2).
136  };
137 
138  public:
139 
140  /**
141  * Creates a new calibration pattern detector object.
142  * A common calibration pattern may have e.g. 5 horizontal and 7 vertical boxes while each box has a size of 0.02m.<br>
143  * Thus, overall 35 boxes are defined fitting to a size of a DIN A4 size.
144  * @param horizontalBoxes Number of horizontal boxes, with range [1, infinity)
145  * @param verticalBoxes Number of vertical boxes, with range [1, infinity)
146  */
147  CalibrationPatternDetector(const unsigned int horizontalBoxes, const unsigned int verticalBoxes);
148 
149  /**
150  * Returns the number of horizontal boxes.
151  * @return Horizontal boxes
152  */
153  inline unsigned int horizontalBoxes() const;
154 
155  /**
156  * Returns the number of vertical boxes.
157  * @return Vertical boxes
158  */
159  inline unsigned int verticalBoxes() const;
160 
161  /**
162  * Returns the number of horizontal edges.
163  * Each horizontal box will provide two horizontal edges.<br>
164  * Beware: In this meaning the direction of these edges is not horizontal.
165  * @return Number of horizontal edges
166  */
167  inline unsigned int horizontalEdges() const;
168 
169  /**
170  * Returns the number of vertical edges.
171  * Each vertical box will provide two vertical edges.<br>
172  * Beware: In this meaning the direction of these edges is not horizontal.
173  * @return Number of vertical edges
174  */
175  inline unsigned int verticalEdges() const;
176 
177  /**
178  * Returns the most recent pattern information (corners of the calibration pattern) associated with the last image frame<br>
179  * in which a pattern could be detected successfully.
180  * @return Most recent pattern rows
181  */
182  inline const Pattern& pattern() const;
183 
184  /**
185  * Detects the calibration pattern in a new image frame.
186  * @param frame New frame to be used for pattern detection
187  * @param worker Optional worker object to be used to distribute the computation to several CPU cores.
188  * @return True, if a pattern could be detected inside the new frame
189  */
190  bool detectPattern(const Frame& frame, Worker* worker = nullptr);
191 
192  /**
193  * Releases the information of the previously found calibration pattern.
194  */
195  void release();
196 
197  /**
198  * Returns whether the detector holds valid parameters.
199  * @return True, if so
200  */
201  inline bool isValid() const;
202 
203  private:
204 
205  /**
206  * Re-detects the calibration pattern using the calibration corners form the previous frame.
207  * @param yFrame Grayscale frame of the input frame
208  * @param timestamp Frame timestamp to be used as pattern timestamp if the pattern could be detected
209  * @param worker Optional worker object to distribute the computational load
210  * @return True, if succeeded
211  */
212  bool detectCalibrationPatternWithPreviousCorners(const Frame& yFrame, const Timestamp timestamp, Worker* worker);
213 
214  /**
215  * Detects the calibration pattern without any previous information.
216  * @param yFrame Grayscale frame of the input frame
217  * @param timestamp Frame timestamp to be used as pattern timestamp if the pattern could be detected
218  * @param worker Optional worker object to distribute the computational load
219  * @return True, if succeeded
220  */
221  bool detectCalibrationPatternWithoutKnowledge(const Frame& yFrame, const Timestamp timestamp, Worker* worker);
222 
223  /**
224  * Re-detects the calibration pattern using the calibration corners form the previous frame.
225  * @param harrisCorners Already detector Harris corners
226  * @param maxCornerDistance Maximal distance between previous and new corners in pixel to count as the same corner
227  * @param timestamp Frame timestamp to be used as pattern timestamp if the pattern could be detected
228  * @return True, if succeeded
229  */
230  bool detectCalibrationPatternWithPreviousCorners(const HarrisCorners& harrisCorners, const Scalar maxCornerDistance, const Timestamp timestamp);
231 
232  /**
233  * Detects the calibration pattern without any previous information.
234  * @param yFrame Grayscale frame of the input frame
235  * @param harrisCorners Already detector Harris corners
236  * @param maxCornerDistance Maximal distance between previous and new corners in pixel to count as the same corner
237  * @param maxParallelAngle Maximal angle between two lines so that they still count as parallel, with range [0, PI/2)
238  * @param orientationError The expected orientation error each provided line can have e.g., due to measurement/detection inaccuracies, in radian with range [0, PI/2)
239  * @param timestamp Frame timestamp to be used as pattern timestamp if the pattern could be detected
240  * @param worker Optional worker object to distribute the computational load
241  * @return True, if succeeded
242  */
243  bool detectCalibrationPatternWithoutKnowledge(const Frame& yFrame, const HarrisCorners& harrisCorners, const Scalar maxCornerDistance, const Scalar maxParallelAngle, const Scalar orientationError, const Timestamp timestamp, Worker* worker);
244 
245  /**
246  * Sorts lines regarding to the signed distance to a given point.
247  * @param lines The lines to be sorted, further the directions of some lines may flip
248  * @param point The point to which the distance is determined
249  */
250  static void sortLinesAccordingDistance(Lines2& lines, const Vector2& point = Vector2(0, 0));
251 
252  private:
253 
254  /// Number of horizontal boxes.
255  unsigned int horizontalBoxes_ = 0u;
256 
257  /// Number of vertical boxes.
258  unsigned int verticalBoxes_ = 0u;
259 
260  /// Number of horizontal edges.
261  unsigned int horizontalEdges_ = 0u;
262 
263  /// Number of vertical edges.
264  unsigned int verticalEdges_ = 0u;
265 
266  /// Holds the most recent pattern rows.
268 
269  /// Index of the recently used tracking threshold parameters.
270  unsigned int trackingThresholdIndex_ = 0u;
271 
272  /// Index of the recently used tracking detection parameters.
273  unsigned int detectionThresholdIndex_ = 0u;
274 };
275 
276 inline CalibrationPatternDetector::TrackingThresholds::TrackingThresholds(const unsigned int width, const unsigned int height, const unsigned int harrisCorner, const Scalar maximalDistance) :
277  invFrameDiagonal_(Numeric::ratio(Scalar(1), Vector2(Scalar(width), Scalar(height)).length())),
278  harrisCornerThreshold_(harrisCorner),
279  maximalCornerDistance_(maximalDistance)
280 {
281  ocean_assert(width != 0u && height != 0u);
282 }
283 
285 {
286  return harrisCornerThreshold_;
287 }
288 
289 inline Scalar CalibrationPatternDetector::TrackingThresholds::maximalCornerDistance(const unsigned int width, const unsigned int height) const
290 {
291  ocean_assert(width != 0u && height != 0u);
292 
293  const Scalar currentDiagonal(Vector2(Scalar(width), Scalar(height)).length());
294  ocean_assert(Numeric::isNotEqualEps(currentDiagonal));
295 
296  return maximalCornerDistance_ * currentDiagonal * invFrameDiagonal_;
297 }
298 
299 inline CalibrationPatternDetector::DetectionThresholds::DetectionThresholds(const unsigned int width, const unsigned int height, const unsigned int harrisCorner, const Scalar maximalDistance, const Scalar maximalParallelAngle, const Scalar orientationError) :
300  TrackingThresholds(width, height, harrisCorner, maximalDistance),
301  maximalParallelAngle_(maximalParallelAngle),
302  orientationError_(orientationError)
303 {
305  ocean_assert(orientationError_ >= 0 && orientationError_ < Numeric::pi_2());
306 }
307 
309 {
310  ocean_assert(maximalParallelAngle_ >= 0 && maximalParallelAngle_ < Numeric::pi_2());
311  return maximalParallelAngle_;
312 }
313 
315 {
316  ocean_assert(orientationError_ >= 0 && orientationError_ < Numeric::pi_2());
317  return orientationError_;
318 }
319 
321 {
322  return horizontalBoxes_;
323 }
324 
325 inline unsigned int CalibrationPatternDetector::verticalBoxes() const
326 {
327  return verticalBoxes_;
328 }
329 
331 {
332  return horizontalEdges_;
333 }
334 
335 inline unsigned int CalibrationPatternDetector::verticalEdges() const
336 {
337  return verticalEdges_;
338 }
339 
341 {
342  return horizontalBoxes_ > 0u && verticalBoxes_ > 0u;
343 }
344 
346 {
347  return pattern_;
348 }
349 
350 }
351 
352 }
353 
354 }
355 
356 #endif // META_OCEAN_CV_DETECTOR_CALIBRATION_PATTERN_DETECTOR_H
Definition of a threshold container for detection parameters.
Definition: CalibrationPatternDetector.h:103
Scalar orientationError() const
The expected orientation error each provided line can have e.g., due to measurement/detection inaccur...
Definition: CalibrationPatternDetector.h:314
DetectionThresholds(const unsigned int width, const unsigned int height, const unsigned int harrisCorners, const Scalar maximalDistance, const Scalar maximalParallelAngle, const Scalar orientationError)
Creates a new threshold object.
Definition: CalibrationPatternDetector.h:299
Scalar maximalParallelAngle() const
Returns the maximal angle between two lines so that they still count as parallel.
Definition: CalibrationPatternDetector.h:308
const Scalar orientationError_
The expected orientation error each provided line can have e.g., due to measurement/detection inaccur...
Definition: CalibrationPatternDetector.h:135
const Scalar maximalParallelAngle_
Maximal angle between two lines so that they still count as parallel in radian, with range [0,...
Definition: CalibrationPatternDetector.h:132
Definition of a threshold container for tracking parameters.
Definition: CalibrationPatternDetector.h:61
TrackingThresholds(const unsigned int width, const unsigned int height, const unsigned int harrisCorners, const Scalar maximalDistance)
Creates a new threshold object.
Definition: CalibrationPatternDetector.h:276
Scalar maximalCornerDistance(const unsigned int width, const unsigned int height) const
Returns the maximal distance between predicted and real corner, in pixel.
Definition: CalibrationPatternDetector.h:289
const unsigned int harrisCornerThreshold_
Strength threshold for Harris corners.
Definition: CalibrationPatternDetector.h:93
const Scalar maximalCornerDistance_
Maximal pixel distance between predicted and real corner.
Definition: CalibrationPatternDetector.h:96
const Scalar invFrameDiagonal_
The inverted diagonal distance between two opposite corners inside the camera frame.
Definition: CalibrationPatternDetector.h:90
unsigned int harrisCornerThreshold() const
Returns the strength threshold of the Harris corner.
Definition: CalibrationPatternDetector.h:284
This class implements a detector for calibration patterns.
Definition: CalibrationPatternDetector.h:37
CalibrationPatternDetector(const unsigned int horizontalBoxes, const unsigned int verticalBoxes)
Creates a new calibration pattern detector object.
bool detectCalibrationPatternWithoutKnowledge(const Frame &yFrame, const Timestamp timestamp, Worker *worker)
Detects the calibration pattern without any previous information.
unsigned int horizontalEdges() const
Returns the number of horizontal edges.
Definition: CalibrationPatternDetector.h:330
bool isValid() const
Returns whether the detector holds valid parameters.
Definition: CalibrationPatternDetector.h:340
bool detectCalibrationPatternWithPreviousCorners(const HarrisCorners &harrisCorners, const Scalar maxCornerDistance, const Timestamp timestamp)
Re-detects the calibration pattern using the calibration corners form the previous frame.
unsigned int horizontalBoxes_
Number of horizontal boxes.
Definition: CalibrationPatternDetector.h:255
unsigned int verticalEdges() const
Returns the number of vertical edges.
Definition: CalibrationPatternDetector.h:335
Pattern pattern_
Holds the most recent pattern rows.
Definition: CalibrationPatternDetector.h:267
std::vector< Vector2 > PatternRow
Definition of a (row) vector holding 2D positions.
Definition: CalibrationPatternDetector.h:43
unsigned int verticalBoxes_
Number of vertical boxes.
Definition: CalibrationPatternDetector.h:258
static void sortLinesAccordingDistance(Lines2 &lines, const Vector2 &point=Vector2(0, 0))
Sorts lines regarding to the signed distance to a given point.
std::vector< PatternRow > PatternRows
Definition of a vector holding rows.
Definition: CalibrationPatternDetector.h:48
Geometry::CameraCalibration::Pattern Pattern
Redefinition of a calibration pattern.
Definition: CalibrationPatternDetector.h:53
unsigned int horizontalEdges_
Number of horizontal edges.
Definition: CalibrationPatternDetector.h:261
void release()
Releases the information of the previously found calibration pattern.
bool detectCalibrationPatternWithPreviousCorners(const Frame &yFrame, const Timestamp timestamp, Worker *worker)
Re-detects the calibration pattern using the calibration corners form the previous frame.
unsigned int verticalBoxes() const
Returns the number of vertical boxes.
Definition: CalibrationPatternDetector.h:325
bool detectPattern(const Frame &frame, Worker *worker=nullptr)
Detects the calibration pattern in a new image frame.
unsigned int verticalEdges_
Number of vertical edges.
Definition: CalibrationPatternDetector.h:264
unsigned int horizontalBoxes() const
Returns the number of horizontal boxes.
Definition: CalibrationPatternDetector.h:320
const Pattern & pattern() const
Returns the most recent pattern information (corners of the calibration pattern) associated with the ...
Definition: CalibrationPatternDetector.h:345
bool detectCalibrationPatternWithoutKnowledge(const Frame &yFrame, const HarrisCorners &harrisCorners, const Scalar maxCornerDistance, const Scalar maxParallelAngle, const Scalar orientationError, const Timestamp timestamp, Worker *worker)
Detects the calibration pattern without any previous information.
This class implements Ocean's image class.
Definition: Frame.h:1760
Definition of a class holding the information about one calibration pattern.
Definition: CameraCalibration.h:41
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static constexpr T pi_2()
Returns PI/2 which is equivalent to 90 degree.
Definition: Numeric.h:938
static constexpr bool isNotEqualEps(const T value)
Returns whether a value is not smaller than or equal to a small epsilon.
Definition: Numeric.h:2237
This class implements a timestamp.
Definition: Timestamp.h:36
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
std::vector< HarrisCorner > HarrisCorners
Definition of a vector holding Harris corners.
Definition: HarrisCorner.h:24
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< Line2 > Lines2
Definition of a vector holding Line2 objects.
Definition: Line2.h:57
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15