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