Ocean
cv/detector/qrcodes/Utilities.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 #pragma once
9 
11 
15 
16 #include "ocean/base/Worker.h"
17 
18 #include "ocean/cv/Bresenham.h"
19 #include "ocean/cv/Canvas.h"
20 
21 #include "ocean/math/AnyCamera.h"
22 #include "ocean/math/Vector2.h"
23 
24 namespace Ocean
25 {
26 
27 namespace CV
28 {
29 
30 namespace Detector
31 {
32 
33 namespace QRCodes
34 {
35 
36 /**
37  * Definition of utility functions related to the detection of QR codes
38  * @ingroup cvdetectorqrcodes
39  */
40 class OCEAN_CV_DETECTOR_QRCODES_EXPORT Utilities
41 {
42  public:
43 
44  /**
45  * Definition of return codes of the parsing function for the Wi-Fi configurations
46  */
47  enum ParsingStatus : uint32_t
48  {
49  /// Indicates that parsing was successful
50  PS_SUCCESS = 0u,
51  /// Indicates that the input has an invalid prefix
53  /// Indicates that a field uses an invalid format, for example it isn't closed correctly
55  /// Indicates that the content of a field is invalid, missing, or could not be processed correctly
57  /// Indicates that field type is unknown or invalid
59  /// Indicates that a field has been found multiple times when it should have been unique
61  /// Indicates that the config is terminated correctly
62  PS_ERROR_INVALID_TERMINATION
63  };
64 
65  /**
66  * Definition of a helper class to convert between the coordinate systems that are used for QR codes.
67  *
68  * The default coordinate system (code space) for the 2D locations of the modules is defined as follows (similar to images):
69  * * the x-axis points right,
70  * * the y-axis points down, and
71  * * the origin is in the top-left corner of the QR code
72  * * the pixel origin is in the top-left corner of each pixel
73  *
74  * In the example below, `s = 4 * version + 17` is the number of modules per side:
75  *
76  * <pre>
77  * (0, 0) (s, 0)
78  * o-------+----> x-axis
79  * | |
80  * | |
81  * | |
82  * +-------+
83  * (0, s) | (s, s)
84  * v
85  * y-axis
86  * </pre>
87  *
88  * The coordinate system for 3D locations of modules in its (normalized) object space is defined as follows:
89  * * the x-axis points right in the QR code plane
90  * * the y-axis points up in the QR code plane
91  * * the z-axis points upwards (normal of the QR code plane, pointing towards the camera)
92  * * the origin is in the center of the QR code
93  * * the pixel origin is in the center of each pixel
94  *
95  * <pre>
96  * y
97  * (-1, 1, 0) ^ (1, 1, 0)
98  * +---|---+
99  * | | |
100  * | o-----> x
101  * | |
102  * +-------+
103  * (-1, -1, 0) (1, -1, 0)
104  * </pre>
105  *
106  * The conversion from the first coordinate system (2D) to normalized object space (3D) is defined as follows:
107  *
108  * <pre>
109  * x' = ((2 / s) * x) - 1
110  * y' = ((-2 / s) * y) + 1
111  * z' = 0
112  * </pre>
113  */
114  class OCEAN_CV_DETECTOR_QRCODES_EXPORT CoordinateSystem
115  {
116  public:
117 
118  /**
119  * Constructs an coordinate system object
120  * Coordinates are normalized to the range `[-1, 1]` or `[-scale, scale]` for `scale != 1`.
121  * @param version The version for which the coordinate system should be prepared, range: [1, 40]
122  * @param scale Optional scaling factor for the coordinates in the object space, range: (0, infinity)
123  */
124  CoordinateSystem(const unsigned int version, const Scalar scale = Scalar(1));
125 
126  /**
127  * Returns the scaling factor that is used for coordinate scaling
128  * @return The scaling factor
129  */
130  inline Scalar scale() const;
131 
132  /**
133  * Converts an x-coordinate from code space to object space
134  * @param xCodeSpace The coordinate that will be converted from code to object space, pixel origin is assumed to be in the pixel center (add 0.5, if applicable)
135  * @return The coordinate converted to object space
136  */
137  inline Scalar convertCodeSpaceToObjectSpaceX(const Scalar xCodeSpace) const;
138 
139  /**
140  * Converts an y-coordinate from code space to object space
141  * @param yCodeSpace The coordinate that will be converted from code to object space, pixel origin is assumed to be in the pixel center (add 0.5, if applicable)
142  * @return The coordinate converted to object space
143  */
144  inline Scalar convertCodeSpaceToObjectSpaceY(const Scalar yCodeSpace) const;
145 
146  /**
147  * Compute the locations of the four corners of a code in object space
148  * Coordinates are normalized to the range `[-1, 1]` or `[-scale, scale]` for `scale != 1`.
149  * @param scale Optional scaling factor for the coordinates in the object space, range: (0, infinity)
150  * @return The 4 corners in object space in the order top-left, bottom-left, bottom-right, and top-right.
151  */
152  static inline Vectors3 computeCornersInObjectSpace(const Scalar scale = Scalar(1));
153 
154  /**
155  * Computes the locations of the centers of the 3 finder patterns for a specific QR code version in object space
156  * Coordinates are normalized to the range `[-1, 1]` or `[-scale, scale]` for `scale != 1`.
157  * @param version The version for which the locations of the finder pattern centers will be computed, range: [1, 40]
158  * @param scale Optional scaling factor for the coordinates in the object space, range: (0, infinity)
159  * @return The 3D locations of the finder pattern centers in object space, will have 3 elements
160  */
161  static Vectors3 computeFinderPatternCentersInObjectSpace(const unsigned int version, const Scalar scale = Scalar(1));
162 
163  /**
164  * Computes the locations of alignment patterns for a specific QR code version in object space
165  * Coordinates are normalized to the range `[-1, 1]`.
166  * @param version The version for which the locations of the alignment patterns will be computed, range: [1, 40]
167  * @param scale Optional scaling factor for the coordinates in the object space, range: (0, infinity)
168  * @return The 3D locations of the alignment patterns in object space in row-wise order
169  */
170  static std::vector<Vectors3> computeAlignmentPatternsInObjectSpace(const unsigned int version, const Scalar scale = Scalar(1));
171 
172  /**
173  * Computes the locations of the version information fields for a specific QR code version in object space
174  * Coordinates are normalized to the range `[-1, 1]`.
175  * <pre>
176  * version information 1 (6 x 3 modules)
177  * |
178  * v
179  * ############## 0 1 2 ##############
180  * ## ## 3 4 5 ## ##
181  * ## ###### ## 6 7 8 ## ###### ##
182  * ## ###### ## 9 A B ## ###### ##
183  * ## ###### ## C D E ## ###### ##
184  * ## ## F G H ## ##
185  * ############## ## ## ## ## ##############
186  *
187  * ##
188  *
189  * ##
190  *
191  * 0 3 6 9 C F ##
192  * 1 4 7 A D G <-- version information 2 (3 x 6 modules)
193  * 2 5 8 B E H ##
194  *
195  * ##############
196  * ## ##
197  * ## ###### ##
198  * ## ###### ##
199  * ## ###### ##
200  * ## ##
201  * ##############
202  * </pre>
203  *
204  * @param version The version for which the locations of the alignment patterns will be computed, range: [7, 40]
205  * @param versionInformation1 If true, the module locations of the first field in the top right corner will be returned, otherwise the ones of the second field in the lower left corner
206  * @return The 3D locations of the 18 modules of the selected version information field in object space (in the order that they will need to be read)
207  */
208  static Vectors3 computeVersionInformationModulesInObjectSpace(const unsigned int version, const bool versionInformation1);
209 
210  protected:
211 
212  /// Global factor for coordinate scaling
214 
215  /// The scale factor for x-coordinates
217 
218  /// The scale factor for y-coordinates
220  };
221 
222  public:
223 
224  /**
225  * Draws an unscaled image of a QR code (FORMAT_Y8), i.e. one modules corresponds to one pixel
226  * @param code The QR code that will be drawn, must be valid
227  * @param border The border that should be drawn around the QR codes in multiples of modules, range: [0, infinity)
228  * @param foregroundColor The color that the foreground modules (i.e. module value is 1) should have, range: [0, 255], this value must differ from `backgroundColor` by at least 30 intensity steps
229  * @param backgroundColor The color that the background modules (i.e. module value is 0) should have, range: [0, 255], this value must differ from `foregroundColor` by at least 30 intensity steps
230  * @return The frame holding the image of the QR code, will be invalid in case of a failure
231  */
232  static Frame draw(const QRCodeBase& code, const unsigned int border, const uint8_t foregroundColor = 0u, const uint8_t backgroundColor = 255u);
233 
234  /**
235  * Draws a scaled image of a QR code (FORMAT_Y8)
236  * @param code The QR code that will be drawn, must be valid
237  * @param frameSize The width and height of the resulting frame, range: [qrcode.modulesCount() + 2u * border, infinity)
238  * @param allowTrueMultiple True, then the value of `frameSize` may be increased to smallest multiple of `qrcode.modulesCount() + 2u * border` that is larger or equal to `frameSize`, otherwise the specified value of `frameSize` will be used
239  * @param border The border that should be drawn around the QR codes in multiple of modules, range: [0, infinity)
240  * @param worker Optional worker that is used to draw the QR code
241  * @param foregroundColor The color that the foreground modules (i.e. module value is 1) should have, range: [0, 255], this value must differ from `backgroundColor` by at least 30 intensity steps
242  * @param backgroundColor The color that the background modules (i.e. module value is 0) should have, range: [0, 255], this value must differ from `foregroundColor` by at least 30 intensity steps
243  * @return The frame holding the image of the QR code, will be invalid in case of a failure
244  */
245  static Frame draw(const QRCodeBase& code, const unsigned int frameSize, const bool allowTrueMultiple, const unsigned int border, Worker* worker = nullptr, const uint8_t foregroundColor = 0u, const uint8_t backgroundColor = 255u);
246 
247  /**
248  * Draws an observation of a QR code into a given frame.
249  * @param frame The frame in which the observation of a QR codes will be drawn, must be valid
250  * @param observation The observation of a QR codes that will be drawn, must be valid
251  * @param code The corresponding QR code
252  */
253  static inline void drawObservation(Frame& frame, const LegacyQRCodeDetector2D::Observation& observation, const QRCode& code);
254 
255  /**
256  * Draws an observation of a QR code into a given frame.
257  * @param frame The frame in which the observation of a QR codes will be drawn, must be valid
258  * @param frame_H_code The homography transformation that maps from the coordinate frame of the code into the frame, i.e. `pointInFrame = frame_H_code pointInCode`, must be valid
259  * @param finderPatterns The three detected finder patterns that are part of the QR code and which will be drawn into the frame
260  * @param version The version of the QR code, range: [1, 40]
261  * @param modules The modules of the QR codes that will be drawn into the frame, must `QRCode::modulesPerSide(version) * QRCode::modulesPerSide(version)` elements
262  */
263  static void drawObservation(Frame& frame, const SquareMatrix3& frame_H_code, const FinderPatternTriplet& finderPatterns, const unsigned int version, const std::vector<uint8_t>& modules);
264 
265  /**
266  * Draws observations of QR codes into a given frame.
267  * @param frame The frame in which the observations of the QR codes will be drawn, must be valid
268  * @param observations The observations of QR codes that will be drawn, must be valid
269  * @param codes The corresponding QR codes, must have the same size as `observations`
270  */
271  static inline void drawObservations(Frame& frame, const LegacyQRCodeDetector2D::Observations& observations, const QRCodes& codes);
272 
273  /**
274  * Draws observations of QR codes into a given frame.
275  * @param anyCamera The camera that was used for the detection of the QR codes, must be valid
276  * @param frame The frame into which observations of the QR codes will be drawn, must be valid, match the camera size, have its origin in the upper left corner, and have a pixel format that is compatible with RGB24
277  * @param observations The observations of QR codes that will be drawn, must have the same size as `codes`
278  * @param codes The corresponding QR codes, must have the same size as `observations`
279  */
280  static void drawObservations(const AnyCamera& anyCamera, Frame& frame, const QRCodeDetector2D::Observations& observations, const QRCodes& codes);
281 
282  /**
283  * Draw the location of a finder pattern in a given frame.
284  * @param frame The frame in which the finder pattern will be drawn, must be valid
285  * @param finderPattern The finder pattern that will be drawn
286  * @param color The color to be used for drawing, one value for each channel of `frame`, must be valid
287  */
288  static void drawFinderPattern(Frame& frame, const FinderPattern& finderPattern, const uint8_t* color);
289 
290  /**
291  * Draws a line between two 2D points into a frame with lens distortion
292  * @param anyCamera The camera profile that will be used to draw the line, must be valid
293  * @param frame The frame into which the line will be drawn, must be valid, match the camera size, have its origin in the upper left corner, and have a pixel format that is compatible with RGB24
294  * @param pointA The first end point of the line segment
295  * @param pointB The second end point of the line segment
296  * @param color Optional color of the line segments
297  * @param steps Optional number of segments that the line will be split into, range: [1, infinity)
298  * @tparam tLineWidth The line of the width, range: [1, infinity), must be an odd value
299  */
300  template <unsigned int tLineWidth>
301  static void drawLine(const AnyCamera& anyCamera, Frame& frame, const Vector2& pointA, const Vector2& pointB, const uint8_t* color = nullptr, const size_t steps = 10);
302 
303  /**
304  * Draws a line between two 3D points into a frame with lens distortion
305  * @param anyCamera The camera profile that will be used to draw the line, must be valid
306  * @param frame The frame into which the line will be drawn, must be valid, match the camera size, have its origin in the upper left corner, and have a pixel format that is compatible with RGB24
307  * @param pointA The first end point of the line segment
308  * @param pointB The second end point of the line segment
309  * @param color Optional color of the line segments
310  * @param steps Optional number of segments that the line will be split into, range: [1, infinity)
311  * @tparam tLineWidth The line of the width, range: [1, infinity), must be an odd value
312  */
313  template <unsigned int tLineWidth>
314  static void drawLine(const AnyCamera& anyCamera, Frame& frame, const Vector3& pointA, const Vector3& pointB, const uint8_t* color = nullptr, const size_t steps = 10);
315 
316  /**
317  * Draws a (projected) 3D line into a given frame.
318  * @param frame The frame in which the line will be painted, must be valid
319  * @param flippedCamera_T_world The transformation transforming world to the flipped camera, the flipped camera points towards the positive z-space with y-axis down, must be valid
320  * @param anyCamera The camera profile defining the projection, must be valid
321  * @param objectPoint0 The start 3D object point of the 3D line, defined in world
322  * @param objectPoint1 The end 3D object point of the 3D line, defined in world
323  * @param segments The number of segments in which the line will be separated, with range [1, infinity), the more segments the better the adjustment to the camera distortion (if any)
324  * @param foregroundColor The foreground color of the line, nullptr to skip the painting with the foreground color
325  * @param backgroundColor The background color of the line, nullptr to skip the painting with the background color
326  * @tparam tForegroundLineWidth The line width of the foreground line, range: [1, infinity); must be an odd value
327  * @tparam tBackgroundLineWidth The line width of the background line, range: [0, infinity); for value 0 no background line is drawn, otherwise this value should be larger than `tForegroundLineWidth` and must be an odd value,
328  */
329  template <unsigned int tForegroundLineWidth, unsigned int tBackgroundLineWidth>
330  static void drawLineIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Vector3& objectPoint0, const Vector3& objectPoint1, const unsigned int segments, const uint8_t* foregroundColor, const uint8_t* backgroundColor);
331 
332  /**
333  * Draws a 3D coordinate system (projected) into a frame.
334  * If the frame is an RGB 24bit frame, than the axes are painted in red (x), green (y), and blue (z); otherwise the axes are painted black.<br>
335  * @param frame The frame in which the coordinate system is painted, must be valid
336  * @param flippedCamera_T_world The camera pose converting world to the flipped camera coordinate system (a camera coordinate system pointing towards the positive z-space), must be valid
337  * @param anyCamera The camera profile that is used to render the coordinate system
338  * @param world_T_coordinateSystem The transformation of the coordinate system that transforms points defined in the local coordinate system (which will be rendered) into points defined in the world coordinate system, must be valid
339  * @param length The length of the three axes of the coordinate system, defined in the units of the local coordinate system (coordinateSystem)
340  * @tparam tForegroundLineWidth The line width of the foreground line, range: [1, infinity); must be an odd value
341  * @tparam tBackgroundLineWidth The line width of the background line, range: [0, infinity); for value 0 no background line is drawn, otherwise this value should larger than `tForegroundLineWidth` and must be an odd value,
342  */
343  template <unsigned int tForegroundLineWidth, unsigned int tBackgroundLineWidth>
344  static void drawCoordinateSystemIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_coordinateSystem, const Scalar length);
345 
346 #if defined(OCEAN_QRCODES_QRCODEDEBUGELEMENTS_ENABLED)
347 
348  /**
349  * Draws the outline of a QR code given its pose and version
350  * @note This function is only for development purposes; do not use it in production code because it will be removed again
351  * @param anyCamera The camera profile that will be used for drawing, must be valid
352  * @param frame The frame into which the line will be drawn, must be valid, match the camera size, have its origin in the upper left corner, and have a pixel format that is compatible with RGB24
353  * @param version The version number of the QR code, range: [1, 40]
354  * @param code_T_camera The transformation that maps coordinates in the reference frame of the camera to that of the code, must be valid
355  */
356  static void drawQRCodeOutline(const AnyCamera& anyCamera, Frame& frame, const unsigned int version, const HomogenousMatrix4& code_T_camera);
357 
358 #endif // OCEAN_QRCODES_QRCODEDEBUGELEMENTS_ENABLED
359 
360  /**
361  * Converts a QR code into string (aka ASCII art)
362  * @param code The QR code that will be converted into string, must be valid
363  * @param border The border in multiples of modules around the ASCII representation of the QR code, range: [0, infinity)
364  * @return The QR code in ASCII representation; will be empty in case of a failure
365  */
366  static std::string toString(const QRCodeBase& code, const unsigned int border);
367 
368  /**
369  * Computes the number of pixel per module for a given observation of a QR code
370  * @param anyCamera The camera what was used for this observation, must be valid.
371  * @param world_T_camera The world pose of the camera, must be valid
372  * @param world_T_code The world pose of the QR code, must be valid
373  * @param codeSize The (display) size of the code in the real world (in meters), range: (0, infinity)
374  * @param version The version number of the QR code, range: [1, 40]
375  * @param minNumberPixelsPerModule The resulting minimum value for the number of pixels per module that has been found, will be ignored if `nullptr`
376  * @param maxNumberPixelsPerModule The resulting maximum value for the number of pixels per module that has been found, will be ignored if `nullptr`
377  * @param medianNumberPixelsPerModule The resulting median of all values for the number of pixels per module, will be ignored if `nullptr`
378  * @param avgNumberPixelsPerModule The resulting average of all values for the number of pixels per module, will be ignored if `nullptr`
379  * @return True if the computation was successful, otherwise false
380  */
381  static bool computeNumberPixelsPerModule(const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_camera, const HomogenousMatrix4& world_T_code, const Scalar codeSize, const unsigned int version, Scalar* minNumberPixelsPerModule, Scalar* maxNumberPixelsPerModule, Scalar* medianNumberPixelsPerModule, Scalar* avgNumberPixelsPerModule);
382 
383  /**
384  * Computes the average diagonal length of a module in pixels for a given coordinate system of a QR code
385  * @param anyCamera The camera what was used for this observation, must be valid
386  * @param flippedCamera_T_code The flipped camera pose of the code, must be valid
387  * @param coordinateSystem The coordinate system of the QR code, must be valid
388  * @param xModule The horizontal coordinate of the module, range: [0, no. modules of the corresponding code)
389  * @param yModule The vertical coordinate of the module, range: [0, no. modules of the corresponding code)
390  * @return The length of the module diagonal in pixels, range: [0, infinity)
391  */
392  static Scalar computeModuleDiagonalLength(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_code, const CoordinateSystem& coordinateSystem, const unsigned int xModule, const unsigned int yModule);
393 
394  /**
395  * Computes the contrast between fore- and background modules for a given observation of a QR code.
396  * @param anyCamera The camera what was used for this observation, must be valid.
397  * @param yFrame The grayscale frame in which the QR code has been observed, must be valid
398  * @param world_T_camera The world pose of the camera, must be valid
399  * @param code The code for which the contrast will be computed, must be valid
400  * @param world_T_code The world pose of the QR code, must be valid
401  * @param codeSize The (display) size of the code in the real world (in meters), range: (0, infinity)
402  * @param medianContrast The resulting construct of the median fore- and background values, will be ignored if `nullptr`
403  * @param averageContrast The resulting construct of the average fore- and background values, will be ignored if `nullptr`
404  * @return True if the computation was successful, otherwise false
405  */
406  static bool computeContrast(const AnyCamera& anyCamera, const Frame& yFrame, const HomogenousMatrix4& world_T_camera, const QRCode& code, const HomogenousMatrix4& world_T_code, const Scalar codeSize, unsigned int* medianContrast, unsigned int* averageContrast);
407 
408  /**
409  * Computes the tilt and view angles for an observation of a QR code
410  * The tilt angle is defined as the angle, `A`, between the normal on the code and the direction from the code center to the camera origin.
411  * \code
412  * camera x
413  * origin .
414  * .
415  * * * code normal
416  * \ |
417  * direction to \ +-|--------+
418  * camera origin \ A| /
419  * / \ | /
420  * / x /
421  * / code /
422  * / center /
423  * +----------+
424  * \endcode
425  * The view angle, `A`, is defined as the angle between the ray pointing from the camera center to the code center and the view direction of the camera.
426  * \code
427  * camera x------* view direction (neg. z-axis)
428  * origin \ A
429  * \
430  * \
431  * direction to *
432  * code center .+----------+
433  * . /
434  * / . /
435  * / x /
436  * / code /
437  * / center /
438  * +----------+
439  * \endcode
440  * @param world_T_camera The world pose of the camera, must be valid
441  * @param world_T_code The world pose of the QR code, must be valid
442  * @param tiltAngle The resulting angle at which the QR code is tilted away from the camera center, in radian
443  * @param viewAngle The resulting angle at which the camera is looking at the QR code, in radian
444  * @param distance The optionally resulting distance from the camera center to the code center, will be ignored if `nullptr`
445  * @return True if the computation was successful, otherwise false
446  */
447  static bool computeCodeTiltAndViewAngles(const HomogenousMatrix4& world_T_camera, const HomogenousMatrix4& world_T_code, Scalar& tiltAngle, Scalar& viewAngle, Scalar* distance = nullptr);
448 
449  /**
450  * Checks if a given QR code exists in a list of QR codes given their 6DOF poses and a stereo camera
451  * This function will check if the payload of a new code is identical with the payload of any code in a list of codes; for pairs of codes with
452  * identical payload, function checks if the projection of a new code overlaps with the projection of the other QR code. If both checks are true
453  * the function will return `true`.
454  * @param sharedAnyCameras The cameras that produced the input images, must have 2 elements, all elements must be valid
455  * @param world_T_device The transformation that maps points in the device coordinate system points to world points, must be valid
456  * @param device_T_cameras The transformation that converts points in the camera coordinate systems to device coordinates, `devicePoint = device_T_cameras[i] * cameraPoint`, must have the same number of elements as `yFrames`, all elements must be valid
457  * @param codes The list of existing QR codes that will be checked against, each element must be a valid QR code
458  * @param world_T_codes The world poses the of the above list of QR codes, number of elements will be identical to `codes`
459  * @param codeSizes The edge lengths of the above list of QR codes in meters, number of elements will be identical to `codes`, range of each value: (0, infinity)
460  * @param newCode The new QR code that will be checked, must be valid
461  * @param world_T_newCode The world pose the of the above QR code, must be valid
462  * @param newCodeSize The edge length of the above QR code in meters, range: (0, infinity)
463  * @param index The optionally returned index of the code in `codes` that is identical to `newCode`, will be ignored if `nullptr`
464  * @return True if an identical code was found, otherwise false
465  */
466  static bool containsCodeStereo(const SharedAnyCameras& sharedAnyCameras, const HomogenousMatrix4& world_T_device, const HomogenousMatrices4& device_T_cameras, const QRCodes& codes, const HomogenousMatrices4& world_T_codes, const Scalars& codeSizes, const QRCode& newCode, const HomogenousMatrix4& world_T_newCode, const Scalar newCodeSize, unsigned int* index = nullptr);
467 
468  /**
469  * Checks if a given QR code exists in a list of QR codes given their 6DOF poses and a mono camera
470  * This function will check if the payload of a new code is identical with the payload of any code in a list of codes; for pairs of codes with
471  * identical payload, function checks if the projection of a new code overlaps with the projection of the other QR code. If both checks are true
472  * the function will return `true`.
473  * @param anyCamera The camera that produced the input image, must be valid
474  * @param world_T_camera The transformation that maps points in the camera coordinate system points to world points, must be valid
475  * @param codes The list of existing QR codes that will be checked against, each element must be a valid QR code
476  * @param world_T_codes The world poses the of the above list of QR codes, number of elements will be identical to `codes`
477  * @param codeSizes The edge lengths of the above list of QR codes in meters, number of elements will be identical to `codes`, range of each value: (0, infinity)
478  * @param newCode The new QR code that will be checked, must be valid
479  * @param world_T_newCode The world pose the of the above QR code, must be valid
480  * @param newCodeSize The edge length of the above QR code in meters, range: (0, infinity)
481  * @param index The optionally returned index of the code in `codes` that is identical to `newCode`, will be ignored if `nullptr`
482  * @return True if an identical code was found, otherwise false
483  */
484  static bool containsCodeMono(const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_camera, const QRCodes& codes, const HomogenousMatrices4& world_T_codes, const Scalars& codeSizes, const QRCode& newCode, const HomogenousMatrix4& world_T_newCode, const Scalar newCodeSize, unsigned int* index = nullptr);
485 
486  /**
487  * Checks if a given QR code exists in a list of QR codes
488  * This function will check if the payload of a new code is identical with the payload of any code in a list of codes; if any is found, the function will return `true`.
489  * @param codes The list of existing QR codes that will be checked against, each element must be a valid QR code
490  * @param newCode The new QR code that will be checked, must be valid
491  * @return True if an identical code was found, otherwise false
492  */
493  static bool containsCode(const QRCodes& codes, const QRCode& newCode);
494 
495  /**
496  * Parses a Wi-Fi configuration from a QR code
497  * The following format is expected:
498  *
499  * <pre>
500  * WIFI:S:<SSID>;T:<WEP|WPA|blank>;P:<PASSWORD>;H:<true|false|blank>;;
501  * </pre>
502  *
503  * Special characters \;,": should be escaped with a backslash (\\‍). More details can be found
504  * here: https://github.com/zxing/zxing/wiki/Barcode-Contents#wi-fi-network-config-android-ios-11
505  * @param configString The string containing the configuration, must be valid and of the format mentioned above
506  * @param ssid The resulting SSID of the Wi-Fi network
507  * @param password The resulting password of the Wi-Fi network
508  * @param encryption The optionally resulting encryption type of the Wi-Fi network (either "", "WEP", or "WPA")
509  * @param isSsidHidden The optionally resulting value whether the SSID of the Wi-Fi network is hidden
510  * @return `PS_SUCCESS` if parsing finished successfully, otherwise a correspond error code
511  */
512  static ParsingStatus parseWifiConfig(const std::string& configString, std::string& ssid, std::string& password, std::string* encryption = nullptr, bool* isSsidHidden = nullptr);
513 
514  /**
515  * Returns a human-readable string for each possible parsing status
516  * @param status The status to be converted to a string
517  * @return The human-readable string
518  */
519  static std::string parsingStatusToString(const ParsingStatus status);
520 
521  protected:
522 
523  /**
524  * Escapes selected characters in a string
525  * @param string The string which will be checked for characters that need escaping, must be valid
526  * @param specialCharacters The string defining which characters to escape; duplicates will be ignored; must be valid
527  * @return A string with escaped characters
528  * @sa parseWifiConfig()
529  */
530  static std::string escapeSpecialCharacters(const std::string& string, const std::string& specialCharacters = "\\;,\":");
531 
532  /**
533  * Unescapes selected character from a string
534  * @param escapedString The string to be unescaped, must be valid
535  * @param string The resulting string without escaped characters
536  * @param specialCharacters The string defining which characters to unescape; duplicates will be ignored; must be valid
537  * @return True if the unescaping process was successful, otherwise false
538  * @sa parseWifiConfig()
539  */
540  static bool unescapeSpecialCharacters(const std::string& escapedString, std::string& string, const std::string& specialCharacters = "\\;,\":");
541 
542  /**
543  * Computes the image location of the center of a QR code given its world pose
544  * @param anyCamera The camera profile that will be used to draw the line, must be valid
545  * @param world_T_camera The transformation that maps points in the camera coordinate system points to world points, must be valid
546  * @param code The code for which the image location will be computed, must be valid
547  * @param world_T_code The world pose the QR code, must be valid
548  * @param codeSize The edge lengths of the QR code in meters, range: (0, infinity)
549  * @param imageCodeCenter The returning image location of the center of a QR code; value is only valid if this function returns `true`
550  * @param maxSquareRadius The optionally returning maximum square distance in pixels of the image location of the code and its four corners; value is only valid if this function returns `true`
551  * @return True, if code is in front of the camera and the image location of its center is inside the image boundaries, otherwise false
552  */
553  static bool computeCodeCenterInImage(const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_camera, const QRCode& code, const HomogenousMatrix4& world_T_code, const Scalar codeSize, Vector2& imageCodeCenter, Scalar* maxSquareRadius = nullptr);
554 };
555 
557 {
558  return scale_;
559 }
560 
562 {
563  const Scalar xObjectSpace = xScale_ * xCodeSpace - Scalar(scale_);
564  ocean_assert(Numeric::isInsideRange(Scalar(-scale_), xObjectSpace, Scalar(scale_)));
565 
566  return xObjectSpace;
567 }
568 
570 {
571  const Scalar yObjectSpace = yScale_ * yCodeSpace + Scalar(scale_);
572  ocean_assert(Numeric::isInsideRange(Scalar(-scale_), yObjectSpace, Scalar(scale_)));
573 
574  return yObjectSpace;
575 }
576 
578 {
579  ocean_assert(scale > Scalar(0));
580 
581  Vectors3 corners =
582  {
583  Vector3(-Scalar(scale), Scalar(scale), Scalar(0)), // top-left
584  Vector3(-Scalar(scale), -Scalar(scale), Scalar(0)), // bottom-left
585  Vector3( Scalar(scale), -Scalar(scale), Scalar(0)), // bottom-right
586  Vector3( Scalar(scale), Scalar(scale), Scalar(0)), // top-right
587  };
588 
589  return corners;
590 }
591 
592 inline void Utilities::drawObservation(Frame& frame, const LegacyQRCodeDetector2D::Observation& observation, const QRCode& code)
593 {
594  ocean_assert(frame.isValid());
595  ocean_assert(code.isValid());
596 
597  drawObservation(frame, observation.frame_H_code(), observation.finderPatterns(), code.version(), code.modules());
598 }
599 
600 inline void Utilities::drawObservations(Frame& frame, const LegacyQRCodeDetector2D::Observations& observations, const QRCodes& codes)
601 {
602  ocean_assert(frame.isValid());
603 
604  if (observations.size() != codes.size())
605  {
606  ocean_assert(false && "This should never happen!");
607  return;
608  }
609 
610  for (size_t i = 0; i < observations.size(); ++i)
611  {
612  drawObservation(frame, observations[i].frame_H_code(), observations[i].finderPatterns(), codes[i].version(), codes[i].modules());
613  }
614 }
615 
616 template <unsigned int tLineWidth>
617 void Utilities::drawLine(const AnyCamera& anyCamera, Frame& frame, const Vector2& pointA, const Vector2& pointB, const uint8_t* color, const size_t steps)
618 {
619  ocean_assert(anyCamera.isValid());
620  ocean_assert(frame.isValid());
621  ocean_assert(steps != 0);
622 
623  return Utilities::drawLine<tLineWidth>(anyCamera, frame, anyCamera.vector(pointA), anyCamera.vector(pointB), color, steps);
624 }
625 
626 template <unsigned int tLineWidth>
627 void Utilities::drawLine(const AnyCamera& anyCamera, Frame& frame, const Vector3& pointA, const Vector3& pointB, const uint8_t* color, const size_t steps)
628 {
629  static_assert(tLineWidth != 0 && tLineWidth % 2u == 1u, "Line width must be non-zero and odd");
630 
631  ocean_assert(anyCamera.isValid());
633  ocean_assert(steps != 0);
634 
635  const Vector3 step = (pointB - pointA) * (Scalar(1) / Scalar(steps));
636  ocean_assert(!step.isNull());
637 
638  color = color == nullptr ? CV::Canvas::green(frame.pixelFormat()) : color;
639 
640  Vector3 previousPlanePoint = pointA;
641  Vector2 previousImagePoint = anyCamera.projectToImage(previousPlanePoint);
642 
643  for (size_t s = 0; s < steps; ++s)
644  {
645  const Vector3 currentPlanePoint = previousPlanePoint + step;
646  const Vector2 currentImagePoint = anyCamera.projectToImage(currentPlanePoint);
647 
648  CV::Canvas::line<tLineWidth>(frame, previousImagePoint, currentImagePoint, color);
649 
650  previousPlanePoint = currentPlanePoint;
651  previousImagePoint = currentImagePoint;
652  }
653 }
654 
655 template <unsigned int tForegroundLineWidth, unsigned int tBackgroundLineWidth>
656 void Utilities::drawLineIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Vector3& objectPoint0, const Vector3& objectPoint1, const unsigned int segments, const uint8_t* foregroundColor, const uint8_t* backgroundColor)
657 {
658  static_assert(tForegroundLineWidth != 0u && tForegroundLineWidth % 2u == 1u, "The line width must be non-zero and odd.");
659  static_assert(tBackgroundLineWidth == 0u || tBackgroundLineWidth % 2u == 1u, "The line width must be either zero (in which case it will not be drawn) or non-zero and odd.");
660 
661  ocean_assert(frame && flippedCamera_T_world.isValid() && anyCamera.isValid());
662  ocean_assert(frame.width() == anyCamera.width() && frame.height() == anyCamera.height());
663  ocean_assert(segments >= 1u);
664 
665  const Scalar segmentFactor = Scalar(1) / Scalar(segments);
666 
667  if (backgroundColor && tBackgroundLineWidth != 0u)
668  {
669  Vector2 projectedStart = anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint0);
670 
671  for (unsigned int n = 0u; n < segments; ++n)
672  {
673  const Vector3 end = objectPoint0 + (objectPoint1 - objectPoint0) * Scalar(n + 1) * segmentFactor;
674  const Vector2 projectedEnd = anyCamera.projectToImageIF(flippedCamera_T_world, end);
675 
676  CV::Canvas::line<tBackgroundLineWidth>(frame, projectedStart.x(), projectedStart.y(), projectedEnd.x(), projectedEnd.y(), backgroundColor);
677 
678  projectedStart = projectedEnd;
679  }
680  }
681 
682  if (foregroundColor)
683  {
684  Vector2 projectedStart = anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint0);
685 
686  for (unsigned int n = 0u; n < segments; ++n)
687  {
688  const Vector3 end = objectPoint0 + (objectPoint1 - objectPoint0) * Scalar(n + 1) * segmentFactor;
689  const Vector2 projectedEnd = anyCamera.projectToImageIF(flippedCamera_T_world, end);
690 
691  CV::Canvas::line<tForegroundLineWidth>(frame, projectedStart.x(), projectedStart.y(), projectedEnd.x(), projectedEnd.y(), foregroundColor);
692 
693  projectedStart = projectedEnd;
694  }
695  }
696 }
697 
698 template <unsigned int tForegroundLineWidth, unsigned int tBackgroundLineWidth>
699 void Utilities::drawCoordinateSystemIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_coordinateSystem, const Scalar length)
700 {
701  static_assert(tForegroundLineWidth != 0u && tForegroundLineWidth % 2u == 1u, "The line width must be non-zero and odd.");
702  static_assert(tBackgroundLineWidth == 0u || tBackgroundLineWidth % 2u == 1u, "The line width must be either zero (in which case it will not be drawn) or non-zero and odd.");
703 
704  ocean_assert(frame && flippedCamera_T_world.isValid() && anyCamera.isValid() && world_T_coordinateSystem.isValid());
705  ocean_assert(frame.width() == anyCamera.width() && frame.height() == frame.height());
706 
707  const uint8_t* const red = CV::Canvas::red(frame.pixelFormat());
708  const uint8_t* const green = CV::Canvas::green(frame.pixelFormat());
709  const uint8_t* const blue = CV::Canvas::blue(frame.pixelFormat());
710  const uint8_t* const black = CV::Canvas::black(frame.pixelFormat());
711 
712  if (AnyCamera::isObjectPointInFrontIF(flippedCamera_T_world, world_T_coordinateSystem.translation()))
713  {
714  const Vector3 xAxis = world_T_coordinateSystem * Vector3(length, 0, 0);
715  const Vector3 yAxis = world_T_coordinateSystem * Vector3(0, length, 0);
716  const Vector3 zAxis = world_T_coordinateSystem * Vector3(0, 0, length);
717 
718  if (AnyCamera::isObjectPointInFrontIF(flippedCamera_T_world, xAxis))
719  {
720  drawLineIF<tForegroundLineWidth, tBackgroundLineWidth>(frame, flippedCamera_T_world, anyCamera, world_T_coordinateSystem.translation(), xAxis, /* segments */ 15u, red, black);
721  }
722 
723  if (AnyCamera::isObjectPointInFrontIF(flippedCamera_T_world, yAxis))
724  {
725  drawLineIF<tForegroundLineWidth, tBackgroundLineWidth>(frame, flippedCamera_T_world, anyCamera, world_T_coordinateSystem.translation(), yAxis, /* segments */ 15u, green, black);
726  }
727 
728  if (AnyCamera::isObjectPointInFrontIF(flippedCamera_T_world, zAxis))
729  {
730  drawLineIF<tForegroundLineWidth, tBackgroundLineWidth>(frame, flippedCamera_T_world, anyCamera, world_T_coordinateSystem.translation(), zAxis, /* segments */ 15u, blue, black);
731  }
732  }
733 }
734 
735 } // namespace QRCodes
736 
737 } // namespace Detector
738 
739 } // namespace CV
740 
741 } // namespace Ocean
This class implements the abstract base class for all AnyCamera objects.
Definition: AnyCamera.h:130
virtual unsigned int width() const =0
Returns the width of the camera image.
virtual VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual VectorT2< T > projectToImage(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual unsigned int height() const =0
Returns the height of the camera image.
virtual bool isValid() const =0
Returns whether this camera is valid.
virtual VectorT3< T > vector(const VectorT2< T > &distortedImagePoint, const bool makeUnitVector=true) const =0
Returns a vector starting at the camera's center and intersecting a given 2D point in the image.
static const uint8_t * green(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a green color.
static const uint8_t * red(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a red color.
static const uint8_t * black(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a black color.
static const uint8_t * blue(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a blue color.
Definition of a class for finder patterns of QR codes (squares in the top-left, top-right and bottom-...
Definition: FinderPatternDetector.h:58
Definition of an observation of QR code in 2D.
Definition: LegacyQRCodeDetector2D.h:73
const FinderPatternTriplet & finderPatterns() const
Returns a pointer to the finder patterns.
Definition: LegacyQRCodeDetector2D.h:275
const SquareMatrix3 & frame_H_code() const
Returns the homography that maps coordinates in the QR code grid to image coordinates.
Definition: LegacyQRCodeDetector2D.h:270
std::vector< Observation > Observations
Definition of a vector of observations.
Definition: LegacyQRCodeDetector2D.h:116
Base class for QR code implementations.
Definition: QRCodeBase.h:32
const std::vector< uint8_t > & modules() const
Returns the modules of this QR code The modules are stored in a vector and will have modulesPerSide()...
Definition: QRCodeBase.h:290
unsigned int version() const
Returns the version of the QR code.
Definition: QRCodeBase.h:305
std::vector< Observation > Observations
Definition of a vector of observations.
Definition: QRCodeDetector2D.h:92
Definition of a QR code.
Definition: QRCode.h:35
bool isValid() const override
Returns whether this is a valid QR code instance.
Definition: QRCode.h:93
Definition of a helper class to convert between the coordinate systems that are used for QR codes.
Definition: cv/detector/qrcodes/Utilities.h:115
Scalar convertCodeSpaceToObjectSpaceX(const Scalar xCodeSpace) const
Converts an x-coordinate from code space to object space.
Definition: cv/detector/qrcodes/Utilities.h:561
Scalar convertCodeSpaceToObjectSpaceY(const Scalar yCodeSpace) const
Converts an y-coordinate from code space to object space.
Definition: cv/detector/qrcodes/Utilities.h:569
static std::vector< Vectors3 > computeAlignmentPatternsInObjectSpace(const unsigned int version, const Scalar scale=Scalar(1))
Computes the locations of alignment patterns for a specific QR code version in object space Coordinat...
Scalar scale_
Global factor for coordinate scaling.
Definition: cv/detector/qrcodes/Utilities.h:213
Scalar scale() const
Returns the scaling factor that is used for coordinate scaling.
Definition: cv/detector/qrcodes/Utilities.h:556
static Vectors3 computeVersionInformationModulesInObjectSpace(const unsigned int version, const bool versionInformation1)
Computes the locations of the version information fields for a specific QR code version in object spa...
CoordinateSystem(const unsigned int version, const Scalar scale=Scalar(1))
Constructs an coordinate system object Coordinates are normalized to the range [-1,...
Scalar yScale_
The scale factor for y-coordinates.
Definition: cv/detector/qrcodes/Utilities.h:219
static Vectors3 computeFinderPatternCentersInObjectSpace(const unsigned int version, const Scalar scale=Scalar(1))
Computes the locations of the centers of the 3 finder patterns for a specific QR code version in obje...
Scalar xScale_
The scale factor for x-coordinates.
Definition: cv/detector/qrcodes/Utilities.h:216
static Vectors3 computeCornersInObjectSpace(const Scalar scale=Scalar(1))
Compute the locations of the four corners of a code in object space Coordinates are normalized to the...
Definition: cv/detector/qrcodes/Utilities.h:577
Definition of utility functions related to the detection of QR codes.
Definition: cv/detector/qrcodes/Utilities.h:41
static void drawObservation(Frame &frame, const SquareMatrix3 &frame_H_code, const FinderPatternTriplet &finderPatterns, const unsigned int version, const std::vector< uint8_t > &modules)
Draws an observation of a QR code into a given frame.
static bool computeCodeTiltAndViewAngles(const HomogenousMatrix4 &world_T_camera, const HomogenousMatrix4 &world_T_code, Scalar &tiltAngle, Scalar &viewAngle, Scalar *distance=nullptr)
Computes the tilt and view angles for an observation of a QR code The tilt angle is defined as the an...
static void drawLineIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &anyCamera, const Vector3 &objectPoint0, const Vector3 &objectPoint1, const unsigned int segments, const uint8_t *foregroundColor, const uint8_t *backgroundColor)
Draws a (projected) 3D line into a given frame.
Definition: cv/detector/qrcodes/Utilities.h:656
static Scalar computeModuleDiagonalLength(const AnyCamera &anyCamera, const HomogenousMatrix4 &flippedCamera_T_code, const CoordinateSystem &coordinateSystem, const unsigned int xModule, const unsigned int yModule)
Computes the average diagonal length of a module in pixels for a given coordinate system of a QR code...
static std::string parsingStatusToString(const ParsingStatus status)
Returns a human-readable string for each possible parsing status.
static ParsingStatus parseWifiConfig(const std::string &configString, std::string &ssid, std::string &password, std::string *encryption=nullptr, bool *isSsidHidden=nullptr)
Parses a Wi-Fi configuration from a QR code The following format is expected:
static bool containsCode(const QRCodes &codes, const QRCode &newCode)
Checks if a given QR code exists in a list of QR codes This function will check if the payload of a n...
static Frame draw(const QRCodeBase &code, const unsigned int border, const uint8_t foregroundColor=0u, const uint8_t backgroundColor=255u)
Draws an unscaled image of a QR code (FORMAT_Y8), i.e.
static bool computeContrast(const AnyCamera &anyCamera, const Frame &yFrame, const HomogenousMatrix4 &world_T_camera, const QRCode &code, const HomogenousMatrix4 &world_T_code, const Scalar codeSize, unsigned int *medianContrast, unsigned int *averageContrast)
Computes the contrast between fore- and background modules for a given observation of a QR code.
static bool containsCodeStereo(const SharedAnyCameras &sharedAnyCameras, const HomogenousMatrix4 &world_T_device, const HomogenousMatrices4 &device_T_cameras, const QRCodes &codes, const HomogenousMatrices4 &world_T_codes, const Scalars &codeSizes, const QRCode &newCode, const HomogenousMatrix4 &world_T_newCode, const Scalar newCodeSize, unsigned int *index=nullptr)
Checks if a given QR code exists in a list of QR codes given their 6DOF poses and a stereo camera Thi...
static bool containsCodeMono(const AnyCamera &anyCamera, const HomogenousMatrix4 &world_T_camera, const QRCodes &codes, const HomogenousMatrices4 &world_T_codes, const Scalars &codeSizes, const QRCode &newCode, const HomogenousMatrix4 &world_T_newCode, const Scalar newCodeSize, unsigned int *index=nullptr)
Checks if a given QR code exists in a list of QR codes given their 6DOF poses and a mono camera This ...
static Frame draw(const QRCodeBase &code, const unsigned int frameSize, const bool allowTrueMultiple, const unsigned int border, Worker *worker=nullptr, const uint8_t foregroundColor=0u, const uint8_t backgroundColor=255u)
Draws a scaled image of a QR code (FORMAT_Y8)
static bool unescapeSpecialCharacters(const std::string &escapedString, std::string &string, const std::string &specialCharacters="\\;,\":")
Unescapes selected character from a string.
static void drawObservations(Frame &frame, const LegacyQRCodeDetector2D::Observations &observations, const QRCodes &codes)
Draws observations of QR codes into a given frame.
Definition: cv/detector/qrcodes/Utilities.h:600
static void drawLine(const AnyCamera &anyCamera, Frame &frame, const Vector2 &pointA, const Vector2 &pointB, const uint8_t *color=nullptr, const size_t steps=10)
Draws a line between two 2D points into a frame with lens distortion.
Definition: cv/detector/qrcodes/Utilities.h:617
static void drawFinderPattern(Frame &frame, const FinderPattern &finderPattern, const uint8_t *color)
Draw the location of a finder pattern in a given frame.
static bool computeNumberPixelsPerModule(const AnyCamera &anyCamera, const HomogenousMatrix4 &world_T_camera, const HomogenousMatrix4 &world_T_code, const Scalar codeSize, const unsigned int version, Scalar *minNumberPixelsPerModule, Scalar *maxNumberPixelsPerModule, Scalar *medianNumberPixelsPerModule, Scalar *avgNumberPixelsPerModule)
Computes the number of pixel per module for a given observation of a QR code.
static void drawObservation(Frame &frame, const LegacyQRCodeDetector2D::Observation &observation, const QRCode &code)
Draws an observation of a QR code into a given frame.
Definition: cv/detector/qrcodes/Utilities.h:592
static bool computeCodeCenterInImage(const AnyCamera &anyCamera, const HomogenousMatrix4 &world_T_camera, const QRCode &code, const HomogenousMatrix4 &world_T_code, const Scalar codeSize, Vector2 &imageCodeCenter, Scalar *maxSquareRadius=nullptr)
Computes the image location of the center of a QR code given its world pose.
static void drawObservations(const AnyCamera &anyCamera, Frame &frame, const QRCodeDetector2D::Observations &observations, const QRCodes &codes)
Draws observations of QR codes into a given frame.
static std::string escapeSpecialCharacters(const std::string &string, const std::string &specialCharacters="\\;,\":")
Escapes selected characters in a string.
static void drawCoordinateSystemIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &anyCamera, const HomogenousMatrix4 &world_T_coordinateSystem, const Scalar length)
Draws a 3D coordinate system (projected) into a frame.
Definition: cv/detector/qrcodes/Utilities.h:699
static void drawQRCodeOutline(const AnyCamera &anyCamera, Frame &frame, const unsigned int version, const HomogenousMatrix4 &code_T_camera)
Draws the outline of a QR code given its pose and version.
ParsingStatus
Definition of return codes of the parsing function for the Wi-Fi configurations.
Definition: cv/detector/qrcodes/Utilities.h:48
@ PS_ERROR_INVALID_FIELD_DATA
Indicates that the content of a field is invalid, missing, or could not be processed correctly.
Definition: cv/detector/qrcodes/Utilities.h:56
@ PS_ERROR_DUPLICATE_FIELD_TYPE
Indicates that a field has been found multiple times when it should have been unique.
Definition: cv/detector/qrcodes/Utilities.h:60
@ PS_ERROR_INVALID_PREFIX
Indicates that the input has an invalid prefix.
Definition: cv/detector/qrcodes/Utilities.h:52
@ PS_ERROR_INVALID_FIELD_TYPE
Indicates that field type is unknown or invalid.
Definition: cv/detector/qrcodes/Utilities.h:58
@ PS_ERROR_INVALID_FIELD_FORMAT
Indicates that a field uses an invalid format, for example it isn't closed correctly.
Definition: cv/detector/qrcodes/Utilities.h:54
static std::string toString(const QRCodeBase &code, const unsigned int border)
Converts a QR code into string (aka ASCII art)
static bool isObjectPointInFrontIF(const HomogenousMatrixT4< T > &flippedCamera_T_world, const VectorT3< T > &objectPoint, const T epsilon=NumericT< T >::eps())
Determines whether a given 3D object point lies in front of a camera while the location of the camera...
Definition: Camera.h:811
This class implements Ocean's image class.
Definition: Frame.h:1760
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4416
@ FORMAT_RGB24
Pixel format with byte order RGB and 24 bits per pixel.
Definition: Frame.h:315
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3111
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition: Frame.h:3156
static bool arePixelFormatsCompatible(const PixelFormat pixelFormatA, const PixelFormat pixelFormatB)
Returns whether two given pixel formats are compatible.
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition: Frame.h:3121
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition: Frame.h:1018
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3116
VectorT3< T > translation() const
Returns the translation of the transformation.
Definition: HomogenousMatrix4.h:1381
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition: HomogenousMatrix4.h:1806
static constexpr bool isInsideRange(const T lower, const T value, const T upper, const T epsilon=NumericT< T >::eps())
Returns whether a value lies between a given range up to a provided epsilon border.
Definition: Numeric.h:2872
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
bool isNull() const
Returns whether this vector is a null vector up to a small epsilon.
Definition: Vector3.h:854
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
std::array< FinderPattern, 3 > FinderPatternTriplet
Definition of a 3-tuple of finder patterns.
Definition: FinderPatternDetector.h:198
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< HomogenousMatrix4 > HomogenousMatrices4
Definition of a vector holding HomogenousMatrix4 objects.
Definition: HomogenousMatrix4.h:73
std::vector< Scalar > Scalars
Definition of a vector holding Scalar objects.
Definition: Math.h:144
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition: Vector3.h:22
SharedAnyCamerasT< Scalar > SharedAnyCameras
Definition of a vector holding AnyCamera objects.
Definition: AnyCamera.h:90
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition: Vector3.h:65
std::vector< QRCode > QRCodes
Definition of a vector of QR codes.
Definition: QRCode.h:25
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15