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 * @return The 3D locations of the finder pattern corners in object space
287 */
289 };
290
291 public:
292
293 /**
294 * Draws an unscaled image of a QR code (FORMAT_Y8), i.e. one modules corresponds to one pixel
295 * @param code The QR code that will be drawn, must be valid
296 * @param border The border that should be drawn around the QR codes in multiples of modules, range: [0, infinity)
297 * @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
298 * @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
299 * @return The frame holding the image of the QR code, will be invalid in case of a failure
300 */
301 static Frame draw(const QRCodeBase& code, const unsigned int border, const uint8_t foregroundColor = 0u, const uint8_t backgroundColor = 255u);
302
303 /**
304 * Draws a scaled image of a QR code (FORMAT_Y8)
305 * @param code The QR code that will be drawn, must be valid
306 * @param frameSize The width and height of the resulting frame, range: [qrcode.modulesCount() + 2u * border, infinity)
307 * @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
308 * @param border The border that should be drawn around the QR codes in multiple of modules, range: [0, infinity)
309 * @param worker Optional worker that is used to draw the QR code
310 * @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
311 * @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
312 * @return The frame holding the image of the QR code, will be invalid in case of a failure
313 */
314 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);
315
316 /**
317 * Draws an observation of a QR code into a given frame.
318 * @param frame The frame in which the observation of a QR codes will be drawn, must be valid
319 * @param observation The observation of a QR codes that will be drawn, must be valid
320 * @param code The corresponding QR code
321 */
322 static inline void drawObservation(Frame& frame, const LegacyQRCodeDetector2D::Observation& observation, const QRCode& code);
323
324 /**
325 * Draws an observation of a QR code into a given frame.
326 * @param frame The frame in which the observation of a QR codes will be drawn, must be valid
327 * @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
328 * @param finderPatterns The three detected finder patterns that are part of the QR code and which will be drawn into the frame
329 * @param version The version of the QR code, range: [1, 40]
330 * @param modules The modules of the QR codes that will be drawn into the frame, must `QRCode::modulesPerSide(version) * QRCode::modulesPerSide(version)` elements
331 */
332 static void drawObservation(Frame& frame, const SquareMatrix3& frame_H_code, const FinderPatternTriplet& finderPatterns, const unsigned int version, const std::vector<uint8_t>& modules);
333
334 /**
335 * Draws observations of QR codes into a given frame.
336 * @param frame The frame in which the observations of the QR codes will be drawn, must be valid
337 * @param observations The observations of QR codes that will be drawn, must be valid
338 * @param codes The corresponding QR codes, must have the same size as `observations`
339 */
340 static inline void drawObservations(Frame& frame, const LegacyQRCodeDetector2D::Observations& observations, const QRCodes& codes);
341
342 /**
343 * Draws observations of QR codes into a given frame.
344 * @param anyCamera The camera that was used for the detection of the QR codes, must be valid
345 * @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
346 * @param observations The observations of QR codes that will be drawn, must have the same size as `codes`
347 * @param codes The corresponding QR codes, must have the same size as `observations`
348 */
349 static void drawObservations(const AnyCamera& anyCamera, Frame& frame, const QRCodeDetector2D::Observations& observations, const QRCodes& codes);
350
351 /**
352 * Draws observations of Micro QR codes into a given frame.
353 * @param anyCamera The camera that was used for the detection of the Micro QR codes, must be valid
354 * @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
355 * @param observations The observations of Micro QR codes that will be drawn, must have the same size as `codes`
356 * @param codes The corresponding Micro QR codes, must have the same size as `observations`
357 */
358 static void drawObservations(const AnyCamera& anyCamera, Frame& frame, const MicroQRCodeDetector2D::Observations& observations, const MicroQRCodes& codes);
359
360 /**
361 * Draws a QR code visualization into a given frame using 3D pose information.
362 * This function renders a QR code by projecting it from world space to image space, drawing:
363 * 1. A red outline around the QR code boundary
364 * 2. Individual modules
365 * 3. A 3D coordinate system at the center of the QR code
366 * @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
367 * @param camera The camera profile used for projecting 3D points to image coordinates, must be valid
368 * @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
369 * @param code The QR code that will be drawn, must be valid
370 * @param codeSize The physical size (edge length) of the QR code in world space units (typically meters), range: (0, infinity)
371 * @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
372 * @sa drawObservations(), drawCoordinateSystemIF()
373 */
374 static void drawQRCode(Frame& frame, const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const QRCode& code, const Scalar codeSize, const HomogenousMatrix4& world_T_code);
375
376 /**
377 * Draw the location of a finder pattern in a given frame.
378 * @param frame The frame in which the finder pattern will be drawn, must be valid
379 * @param finderPattern The finder pattern that will be drawn
380 * @param color The color to be used for drawing, one value for each channel of `frame`, must be valid
381 */
382 static void drawFinderPattern(Frame& frame, const FinderPattern& finderPattern, const uint8_t* color);
383
384 /**
385 * Draws a line between two 2D points into a frame with lens distortion
386 * @param anyCamera The camera profile that will be used to draw the line, must be valid
387 * @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
388 * @param pointA The first end point of the line segment
389 * @param pointB The second end point of the line segment
390 * @param color Optional color of the line segments
391 * @param steps Optional number of segments that the line will be split into, range: [1, infinity)
392 * @tparam tLineWidth The line of the width, range: [1, infinity), must be an odd value
393 */
394 template <unsigned int tLineWidth>
395 static void drawLine(const AnyCamera& anyCamera, Frame& frame, const Vector2& pointA, const Vector2& pointB, const uint8_t* color = nullptr, const size_t steps = 10);
396
397 /**
398 * Draws a line between two 3D points into a frame with lens distortion
399 * @param anyCamera The camera profile that will be used to draw the line, must be valid
400 * @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
401 * @param pointA The first end point of the line segment
402 * @param pointB The second end point of the line segment
403 * @param color Optional color of the line segments
404 * @param steps Optional number of segments that the line will be split into, range: [1, infinity)
405 * @tparam tLineWidth The line of the width, range: [1, infinity), must be an odd value
406 */
407 template <unsigned int tLineWidth>
408 static void drawLine(const AnyCamera& anyCamera, Frame& frame, const Vector3& pointA, const Vector3& pointB, const uint8_t* color = nullptr, const size_t steps = 10);
409
410 /**
411 * Draws a (projected) 3D line into a given frame.
412 * @param frame The frame in which the line will be painted, must be valid
413 * @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
414 * @param anyCamera The camera profile defining the projection, must be valid
415 * @param objectPoint0 The start 3D object point of the 3D line, defined in world
416 * @param objectPoint1 The end 3D object point of the 3D line, defined in world
417 * @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)
418 * @param foregroundColor The foreground color of the line, nullptr to skip the painting with the foreground color
419 * @param backgroundColor The background color of the line, nullptr to skip the painting with the background color
420 * @tparam tForegroundLineWidth The line width of the foreground line, range: [1, infinity); must be an odd value
421 * @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,
422 */
423 template <unsigned int tForegroundLineWidth, unsigned int tBackgroundLineWidth>
424 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);
425
426 /**
427 * Draws a 3D coordinate system (projected) into a frame.
428 * 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>
429 * @param frame The frame in which the coordinate system is painted, must be valid
430 * @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
431 * @param anyCamera The camera profile that is used to render the coordinate system
432 * @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
433 * @param length The length of the three axes of the coordinate system, defined in the units of the local coordinate system (coordinateSystem)
434 * @tparam tForegroundLineWidth The line width of the foreground line, range: [1, infinity); must be an odd value
435 * @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,
436 */
437 template <unsigned int tForegroundLineWidth, unsigned int tBackgroundLineWidth>
438 static void drawCoordinateSystemIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_coordinateSystem, const Scalar length);
439
440#if defined(OCEAN_QRCODES_QRCODEDEBUGELEMENTS_ENABLED)
441
442 /**
443 * Draws the outline of a QR code given its pose and version
444 * @note This function is only for development purposes; do not use it in production code because it will be removed again
445 * @param anyCamera The camera profile that will be used for drawing, must be valid
446 * @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
447 * @param version The version number of the QR code, range: [1, 40]
448 * @param code_T_camera The transformation that maps coordinates in the reference frame of the camera to that of the code, must be valid
449 */
450 static void drawQRCodeOutline(const AnyCamera& anyCamera, Frame& frame, const unsigned int version, const HomogenousMatrix4& code_T_camera);
451
452#endif // OCEAN_QRCODES_QRCODEDEBUGELEMENTS_ENABLED
453
454 /**
455 * Converts a QR code into string (aka ASCII art)
456 * @param code The QR code that will be converted into string, must be valid
457 * @param border The border in multiples of modules around the ASCII representation of the QR code, range: [0, infinity)
458 * @return The QR code in ASCII representation; will be empty in case of a failure
459 */
460 static std::string toString(const QRCodeBase& code, const unsigned int border);
461
462 /**
463 * Computes the number of pixel per module for a given observation of a QR code
464 * @param anyCamera The camera what was used for this observation, must be valid.
465 * @param world_T_camera The world pose of the camera, must be valid
466 * @param world_T_code The world pose of the QR code, must be valid
467 * @param codeSize The (display) size of the code in the real world (in meters), range: (0, infinity)
468 * @param version The version number of the QR code, range: [1, 40]
469 * @param minNumberPixelsPerModule The resulting minimum value for the number of pixels per module that has been found, will be ignored if `nullptr`
470 * @param maxNumberPixelsPerModule The resulting maximum value for the number of pixels per module that has been found, will be ignored if `nullptr`
471 * @param medianNumberPixelsPerModule The resulting median of all values for the number of pixels per module, will be ignored if `nullptr`
472 * @param avgNumberPixelsPerModule The resulting average of all values for the number of pixels per module, will be ignored if `nullptr`
473 * @return True if the computation was successful, otherwise false
474 */
475 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);
476
477 /**
478 * Computes the average diagonal length of a module in pixels for a given coordinate system of a QR code
479 * @param anyCamera The camera what was used for this observation, must be valid
480 * @param flippedCamera_T_code The flipped camera pose of the code, must be valid
481 * @param coordinateSystem The coordinate system of the QR code, must be valid
482 * @param xModule The horizontal coordinate of the module, range: [0, no. modules of the corresponding code)
483 * @param yModule The vertical coordinate of the module, range: [0, no. modules of the corresponding code)
484 * @return The length of the module diagonal in pixels, range: [0, infinity)
485 */
486 static Scalar computeModuleDiagonalLength(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_code, const CoordinateSystemBase& coordinateSystem, const unsigned int xModule, const unsigned int yModule);
487
488 /**
489 * Computes the contrast between fore- and background modules for a given observation of a QR code.
490 * @param anyCamera The camera what was used for this observation, must be valid.
491 * @param yFrame The grayscale frame in which the QR code has been observed, must be valid
492 * @param world_T_camera The world pose of the camera, must be valid
493 * @param code The code for which the contrast will be computed, must be valid
494 * @param world_T_code The world pose of the QR code, must be valid
495 * @param codeSize The (display) size of the code in the real world (in meters), range: (0, infinity)
496 * @param medianContrast The resulting construct of the median fore- and background values, will be ignored if `nullptr`
497 * @param averageContrast The resulting construct of the average fore- and background values, will be ignored if `nullptr`
498 * @return True if the computation was successful, otherwise false
499 */
500 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);
501
502 /**
503 * Computes the tilt and view angles for an observation of a QR code
504 * 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.
505 * \code
506 * camera x
507 * origin .
508 * .
509 * * * code normal
510 * \ |
511 * direction to \ +-|--------+
512 * camera origin \ A| /
513 * / \ | /
514 * / x /
515 * / code /
516 * / center /
517 * +----------+
518 * \endcode
519 * 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.
520 * \code
521 * camera x------* view direction (neg. z-axis)
522 * origin \ A
523 * \
524 * \
525 * direction to *
526 * code center .+----------+
527 * . /
528 * / . /
529 * / x /
530 * / code /
531 * / center /
532 * +----------+
533 * \endcode
534 * @param world_T_camera The world pose of the camera, must be valid
535 * @param world_T_code The world pose of the QR code, must be valid
536 * @param tiltAngle The resulting angle at which the QR code is tilted away from the camera center, in radian
537 * @param viewAngle The resulting angle at which the camera is looking at the QR code, in radian
538 * @param distance The optionally resulting distance from the camera center to the code center, will be ignored if `nullptr`
539 * @return True if the computation was successful, otherwise false
540 */
541 static bool computeCodeTiltAndViewAngles(const HomogenousMatrix4& world_T_camera, const HomogenousMatrix4& world_T_code, Scalar& tiltAngle, Scalar& viewAngle, Scalar* distance = nullptr);
542
543 /**
544 * Checks if a given QR code exists in a list of QR codes given their 6DOF poses and a stereo camera
545 * 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
546 * 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
547 * the function will return `true`.
548 * @param sharedAnyCameras The cameras that produced the input images, must have 2 elements, all elements must be valid
549 * @param world_T_device The transformation that maps points in the device coordinate system points to world points, must be valid
550 * @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
551 * @param codes The list of existing QR codes that will be checked against, each element must be a valid QR code
552 * @param world_T_codes The world poses the of the above list of QR codes, number of elements will be identical to `codes`
553 * @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)
554 * @param newCode The new QR code that will be checked, must be valid
555 * @param world_T_newCode The world pose the of the above QR code, must be valid
556 * @param newCodeSize The edge length of the above QR code in meters, range: (0, infinity)
557 * @param index The optionally returned index of the code in `codes` that is identical to `newCode`, will be ignored if `nullptr`
558 * @return True if an identical code was found, otherwise false
559 */
560 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);
561
562 /**
563 * Checks if a given QR code exists in a list of QR codes given their 6DOF poses and a mono camera
564 * 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
565 * 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
566 * the function will return `true`.
567 * @param anyCamera The camera that produced the input image, must be valid
568 * @param world_T_camera The transformation that maps points in the camera coordinate system points to world points, must be valid
569 * @param codes The list of existing QR codes that will be checked against, each element must be a valid QR code
570 * @param world_T_codes The world poses the of the above list of QR codes, number of elements will be identical to `codes`
571 * @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)
572 * @param newCode The new QR code that will be checked, must be valid
573 * @param world_T_newCode The world pose the of the above QR code, must be valid
574 * @param newCodeSize The edge length of the above QR code in meters, range: (0, infinity)
575 * @param index The optionally returned index of the code in `codes` that is identical to `newCode`, will be ignored if `nullptr`
576 * @return True if an identical code was found, otherwise false
577 */
578 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);
579
580 /**
581 * Checks if a given QR code exists in a list of QR codes
582 * 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`.
583 * @param codes The list of existing QR codes that will be checked against, each element must be a valid QR code
584 * @param newCode The new QR code that will be checked, must be valid
585 * @return True if an identical code was found, otherwise false
586 */
587 static bool containsCode(const QRCodes& codes, const QRCode& newCode);
588
589 /**
590 * Parses a Wi-Fi configuration from a QR code
591 * The following format is expected:
592 *
593 * <pre>
594 * WIFI:S:<SSID>;T:<WEP|WPA|blank>;P:<PASSWORD>;H:<true|false|blank>;;
595 * </pre>
596 *
597 * Special characters \;,": should be escaped with a backslash (\\‍). More details can be found
598 * here: https://github.com/zxing/zxing/wiki/Barcode-Contents#wi-fi-network-config-android-ios-11
599 * @param configString The string containing the configuration, must be valid and of the format mentioned above
600 * @param ssid The resulting SSID of the Wi-Fi network
601 * @param password The resulting password of the Wi-Fi network
602 * @param encryption The optionally resulting encryption type of the Wi-Fi network (either "", "WEP", or "WPA")
603 * @param isSsidHidden The optionally resulting value whether the SSID of the Wi-Fi network is hidden
604 * @return `PS_SUCCESS` if parsing finished successfully, otherwise a correspond error code
605 */
606 static ParsingStatus parseWifiConfig(const std::string& configString, std::string& ssid, std::string& password, std::string* encryption = nullptr, bool* isSsidHidden = nullptr);
607
608 /**
609 * Returns a human-readable string for each possible parsing status
610 * @param status The status to be converted to a string
611 * @return The human-readable string
612 */
613 static std::string parsingStatusToString(const ParsingStatus status);
614
615 protected:
616
617 /**
618 * Escapes selected characters in a string
619 * @param string The string which will be checked for characters that need escaping, must be valid
620 * @param specialCharacters The string defining which characters to escape; duplicates will be ignored; must be valid
621 * @return A string with escaped characters
622 * @sa parseWifiConfig()
623 */
624 static std::string escapeSpecialCharacters(const std::string& string, const std::string& specialCharacters = "\\;,\":");
625
626 /**
627 * Unescapes selected character from a string
628 * @param escapedString The string to be unescaped, must be valid
629 * @param string The resulting string without escaped characters
630 * @param specialCharacters The string defining which characters to unescape; duplicates will be ignored; must be valid
631 * @return True if the unescaping process was successful, otherwise false
632 * @sa parseWifiConfig()
633 */
634 static bool unescapeSpecialCharacters(const std::string& escapedString, std::string& string, const std::string& specialCharacters = "\\;,\":");
635
636 /**
637 * Computes the image location of the center of a QR code given its world pose
638 * @param anyCamera The camera profile that will be used to draw the line, must be valid
639 * @param world_T_camera The transformation that maps points in the camera coordinate system points to world points, must be valid
640 * @param code The code for which the image location will be computed, must be valid
641 * @param world_T_code The world pose the QR code, must be valid
642 * @param codeSize The edge lengths of the QR code in meters, range: (0, infinity)
643 * @param imageCodeCenter The returning image location of the center of a QR code; value is only valid if this function returns `true`
644 * @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`
645 * @return True, if code is in front of the camera and the image location of its center is inside the image boundaries, otherwise false
646 */
647 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);
648};
649
651{
652 return scale_;
653}
654
656{
657 const Scalar xObjectSpace = xScale_ * xCodeSpace - Scalar(scale_);
658 ocean_assert(Numeric::isInsideRange(Scalar(-scale_), xObjectSpace, Scalar(scale_)));
659
660 return xObjectSpace;
661}
662
664{
665 const Scalar yObjectSpace = yScale_ * yCodeSpace + Scalar(scale_);
666 ocean_assert(Numeric::isInsideRange(Scalar(-scale_), yObjectSpace, Scalar(scale_)));
667
668 return yObjectSpace;
669}
670
672{
673 ocean_assert(scale > Scalar(0));
674
675 Vectors3 corners =
676 {
677 Vector3(-Scalar(scale), Scalar(scale), Scalar(0)), // top-left
678 Vector3(-Scalar(scale), -Scalar(scale), Scalar(0)), // bottom-left
679 Vector3( Scalar(scale), -Scalar(scale), Scalar(0)), // bottom-right
680 Vector3( Scalar(scale), Scalar(scale), Scalar(0)), // top-right
681 };
682
683 return corners;
684}
685
686inline void Utilities::drawObservation(Frame& frame, const LegacyQRCodeDetector2D::Observation& observation, const QRCode& code)
687{
688 ocean_assert(frame.isValid());
689 ocean_assert(code.isValid());
690
691 drawObservation(frame, observation.frame_H_code(), observation.finderPatterns(), code.version(), code.modules());
692}
693
694inline void Utilities::drawObservations(Frame& frame, const LegacyQRCodeDetector2D::Observations& observations, const QRCodes& codes)
695{
696 ocean_assert(frame.isValid());
697
698 if (observations.size() != codes.size())
699 {
700 ocean_assert(false && "This should never happen!");
701 return;
702 }
703
704 for (size_t i = 0; i < observations.size(); ++i)
705 {
706 drawObservation(frame, observations[i].frame_H_code(), observations[i].finderPatterns(), codes[i].version(), codes[i].modules());
707 }
708}
709
710template <unsigned int tLineWidth>
711void Utilities::drawLine(const AnyCamera& anyCamera, Frame& frame, const Vector2& pointA, const Vector2& pointB, const uint8_t* color, const size_t steps)
712{
713 ocean_assert(anyCamera.isValid());
714 ocean_assert(frame.isValid());
715 ocean_assert(steps != 0);
716
717 return Utilities::drawLine<tLineWidth>(anyCamera, frame, anyCamera.vector(pointA), anyCamera.vector(pointB), color, steps);
718}
719
720template <unsigned int tLineWidth>
721void Utilities::drawLine(const AnyCamera& anyCamera, Frame& frame, const Vector3& pointA, const Vector3& pointB, const uint8_t* color, const size_t steps)
722{
723 static_assert(tLineWidth != 0 && tLineWidth % 2u == 1u, "Line width must be non-zero and odd");
724
725 ocean_assert(anyCamera.isValid());
727 ocean_assert(steps != 0);
728
729 const Vector3 step = (pointB - pointA) * (Scalar(1) / Scalar(steps));
730 ocean_assert(!step.isNull());
731
732 color = color == nullptr ? CV::Canvas::green(frame.pixelFormat()) : color;
733
734 Vector3 previousPlanePoint = pointA;
735 Vector2 previousImagePoint = anyCamera.projectToImage(previousPlanePoint);
736
737 for (size_t s = 0; s < steps; ++s)
738 {
739 const Vector3 currentPlanePoint = previousPlanePoint + step;
740 const Vector2 currentImagePoint = anyCamera.projectToImage(currentPlanePoint);
741
742 CV::Canvas::line<tLineWidth>(frame, previousImagePoint, currentImagePoint, color);
743
744 previousPlanePoint = currentPlanePoint;
745 previousImagePoint = currentImagePoint;
746 }
747}
748
749template <unsigned int tForegroundLineWidth, unsigned int tBackgroundLineWidth>
750void 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)
751{
752 static_assert(tForegroundLineWidth != 0u && tForegroundLineWidth % 2u == 1u, "The line width must be non-zero and odd.");
753 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.");
754
755 ocean_assert(frame && flippedCamera_T_world.isValid() && anyCamera.isValid());
756 ocean_assert(frame.width() == anyCamera.width() && frame.height() == anyCamera.height());
757 ocean_assert(segments >= 1u);
758
759 const Scalar segmentFactor = Scalar(1) / Scalar(segments);
760
761 if (backgroundColor && tBackgroundLineWidth != 0u)
762 {
763 Vector2 projectedStart = anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint0);
764
765 for (unsigned int n = 0u; n < segments; ++n)
766 {
767 const Vector3 end = objectPoint0 + (objectPoint1 - objectPoint0) * Scalar(n + 1) * segmentFactor;
768 const Vector2 projectedEnd = anyCamera.projectToImageIF(flippedCamera_T_world, end);
769
770 CV::Canvas::line<tBackgroundLineWidth>(frame, projectedStart.x(), projectedStart.y(), projectedEnd.x(), projectedEnd.y(), backgroundColor);
771
772 projectedStart = projectedEnd;
773 }
774 }
775
776 if (foregroundColor)
777 {
778 Vector2 projectedStart = anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint0);
779
780 for (unsigned int n = 0u; n < segments; ++n)
781 {
782 const Vector3 end = objectPoint0 + (objectPoint1 - objectPoint0) * Scalar(n + 1) * segmentFactor;
783 const Vector2 projectedEnd = anyCamera.projectToImageIF(flippedCamera_T_world, end);
784
785 CV::Canvas::line<tForegroundLineWidth>(frame, projectedStart.x(), projectedStart.y(), projectedEnd.x(), projectedEnd.y(), foregroundColor);
786
787 projectedStart = projectedEnd;
788 }
789 }
790}
791
792template <unsigned int tForegroundLineWidth, unsigned int tBackgroundLineWidth>
793void Utilities::drawCoordinateSystemIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_coordinateSystem, const Scalar length)
794{
795 static_assert(tForegroundLineWidth != 0u && tForegroundLineWidth % 2u == 1u, "The line width must be non-zero and odd.");
796 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.");
797
798 ocean_assert(frame && flippedCamera_T_world.isValid() && anyCamera.isValid() && world_T_coordinateSystem.isValid());
799 ocean_assert(frame.width() == anyCamera.width() && frame.height() == frame.height());
800
801 const uint8_t* const red = CV::Canvas::red(frame.pixelFormat());
802 const uint8_t* const green = CV::Canvas::green(frame.pixelFormat());
803 const uint8_t* const blue = CV::Canvas::blue(frame.pixelFormat());
804 const uint8_t* const black = CV::Canvas::black(frame.pixelFormat());
805
806 if (AnyCamera::isObjectPointInFrontIF(flippedCamera_T_world, world_T_coordinateSystem.translation()))
807 {
808 const Vector3 xAxis = world_T_coordinateSystem * Vector3(length, 0, 0);
809 const Vector3 yAxis = world_T_coordinateSystem * Vector3(0, length, 0);
810 const Vector3 zAxis = world_T_coordinateSystem * Vector3(0, 0, length);
811
812 if (AnyCamera::isObjectPointInFrontIF(flippedCamera_T_world, xAxis))
813 {
814 drawLineIF<tForegroundLineWidth, tBackgroundLineWidth>(frame, flippedCamera_T_world, anyCamera, world_T_coordinateSystem.translation(), xAxis, /* segments */ 15u, red, black);
815 }
816
817 if (AnyCamera::isObjectPointInFrontIF(flippedCamera_T_world, yAxis))
818 {
819 drawLineIF<tForegroundLineWidth, tBackgroundLineWidth>(frame, flippedCamera_T_world, anyCamera, world_T_coordinateSystem.translation(), yAxis, /* segments */ 15u, green, black);
820 }
821
822 if (AnyCamera::isObjectPointInFrontIF(flippedCamera_T_world, zAxis))
823 {
824 drawLineIF<tForegroundLineWidth, tBackgroundLineWidth>(frame, flippedCamera_T_world, anyCamera, world_T_coordinateSystem.translation(), zAxis, /* segments */ 15u, blue, black);
825 }
826 }
827}
828
829} // namespace QRCodes
830
831} // namespace Detector
832
833} // namespace CV
834
835} // 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:655
Scalar convertCodeSpaceToObjectSpaceY(const Scalar yCodeSpace) const
Converts an y-coordinate from code space to object space.
Definition cv/detector/qrcodes/Utilities.h:663
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:650
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:671
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:750
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:694
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:711
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:686
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:793
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:856
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