Ocean
QRCodeDetector.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 
13 
14 #include "ocean/math/AnyCamera.h"
15 
16 namespace Ocean
17 {
18 
19 namespace CV
20 {
21 
22 namespace Detector
23 {
24 
25 namespace QRCodes
26 {
27 
28 /**
29  * This class implements common functionality of QR code detectors but is not a stand-alone detector
30  * @ingroup cvdetectorqrcodes
31  */
32 class OCEAN_CV_DETECTOR_QRCODES_EXPORT QRCodeDetector
33 {
34  protected:
35 
36  /**
37  * Estimates the range of version numbers based on pixel distances of pairs of finder patterns
38  * Estimates the version numbers along the line segments that connect the top-left and the top-right finder patterns (horizontal) as well as the top-left and bottom-left finder patterns (vertical).
39  * @param anyCamera The camera profile that produced the input image, must be valid
40  * @param finderPatterns The pointer to the triplet of finder patterns; must be valid and have 3 elements, the order must be top-left, bottom-left, top-right finder pattern
41  * @param maxAllowedVersionDifference The maximum difference between the vertical and horizontal estimate of the version numbers, range: [0, infinity)
42  * @param versionLow The returning minimum of all estimated version numbers
43  * @param versionHigh The returning maximum of all estimated version numbers
44  * @return True if the minimum and maximum version numbers do not exceed the maximum allowed difference, otherwise false
45  */
46  static bool computeProvisionalVersionRange(const AnyCamera& anyCamera, const FinderPattern* finderPatterns, const unsigned int maxAllowedVersionDifference, unsigned int& versionLow, unsigned int& versionHigh);
47 
48  /**
49  * Estimates the version numbers based on pixel distances of a pair of finder patterns
50  * @param centerA The center of the first finder pattern; this must be the undistorted location that has been projected into a plane
51  * @param centerB The center of the second finder pattern; this must be the undistorted location that has been projected into the same plane as the first center
52  * @param moduleSizeA The module size of the first finder pattern, range: (0, infinity)
53  * @param moduleSizeB The module size of the second finder pattern, range: (0, infinity)
54  * @param maxAllowedVersionDifference The maximum difference between the vertical and horizontal estimate of the version numbers, range: [0, infinity)
55  * @param versionLow The returning minimum of two estimated version numbers
56  * @param versionHigh The returning maximum of two estimated version numbers
57  * @return True if the minimum and maximum version numbers do not exceed the maximum allowed difference, otherwise false
58  */
59  static bool computeProvisionalVersion(const Vector3& centerA, const Vector3& centerB, const Scalar moduleSizeA, const Scalar moduleSizeB, const unsigned int maxAllowedVersionDifference, unsigned int& versionLow, unsigned int& versionHigh);
60 
61  /**
62  * Convert the module size in pixels of a finder pattern to the size in a given plane that contains undistorted points
63  * @param anyCamera The camera profile that produced the input image, must be valid
64  * @param plane The plane that contains undistorted points, must be valid
65  * @param imagePoint The location of the center of a finder pattern in the distorted image
66  * @param planePoint The location of the center of a finder pattern in the plane with undistorted points
67  * @param moduleSizeInImage The module size of the finder pattern that was measured in the distorted image, range: (0, infinity)
68  * @param moduleSizeInPlane The resulting module size of the finder pattern in the plane with undistorted points
69  * @return True on success, otherwise false
70  */
71  static bool computeModuleSizeInPlane(const AnyCamera& anyCamera, const Plane3& plane, const Vector2& imagePoint, const Vector3& planePoint, const Scalar moduleSizeInImage, Scalar& moduleSizeInPlane);
72 
73  /**
74  * Determines the version of the QR code symbols from the size and distance of its three finder patterns
75  * The version, `versionX`, is determined in the horizontal direction between centers of the top-left and the top-right finder patterns and their average module size. The version in the vertical direction is determined similary between the top-left and the bottom-left finder patterns, `versionY`.
76  * QR code versions 1-7 do not store version information in dedicated bit fields, only versions 7-40 do. Because of that both versions need to be identical for versions 1-7 in order to be considered as valid, but it is alright to be a little more lenient for the second category (allowing `versionX` and `versionY` to differ by up to 1 version).
77  * @note Make sure that the triplet is valid, otherwise the result will be undefined.
78  * @param topLeft The finder pattern in the top-left corner of the QR code, must be valid
79  * @param bottomLeft The finder pattern in the bottom-left corner of the QR code, must be valid
80  * @param topRight The finder pattern in the top-right corner of the QR code, must be valid
81  * @param versionX The resulting version determined from the top-left and top-right finder patterns
82  * @param versionY The resulting version determined from the top-left and bottom-left finder patterns
83  * @return True if both versions are below 7 and have the same value or if both versions are in the range [7, 40] and do not differ by more than 1, otherwise false
84  */
85  static bool computeProvisionalVersionRange(const FinderPattern& topLeft, const FinderPattern& bottomLeft, const FinderPattern& topRight, unsigned int& versionX, unsigned int& versionY);
86 
87  /**
88  * Extracts all modules of a QR code from an image
89  * @param anyCamera The camera profile that produced the input image, must be valid
90  * @param yFrame The frame in which QR codes will be detected, must be valid, match the camera size, have its origin in the upper left corner, and have a pixel format that is compatible with Y8
91  * @param width The width of the input frame, range: [29, infinity)
92  * @param height The height of the input frame, range: [29, infinity)
93  * @param paddingElements The number of padding elements of the input frame, range: [0, infinity)
94  * @param version The version number that the QR code candidate, range: [1, 40]
95  * @param code_T_camera The pose of the QR code candidate
96  * @param isNormalReflectance Indicates whether alignment patterns with normal or inverted reflectance are searched
97  * @param grayThreshold The gray value that has been determined as the separation between foreground and background modules (cf. `FinderPattern::grayThreshold()`), range: [0, 255]
98  * @param modules The resulting list of all extracted modules, will have `QRCode::modulesPerSide(version) * QRCode::modulesPerSide(version)` elements
99  * @param scale Optional scaling factor for the coordinates in the object space, range: (0, infinity)
100  * @return True if the extraction of all modules was successful, otherwise false
101  */
102  static bool extractModulesFromImage(const AnyCamera& anyCamera, const uint8_t* const yFrame, const unsigned int width, const unsigned int height, const unsigned int paddingElements, const unsigned int version, const HomogenousMatrix4& code_T_camera, const bool isNormalReflectance, const unsigned int grayThreshold, std::vector<uint8_t>& modules, const Scalar scale = Scalar(1));
103 
104  /**
105  * Computes poses of a QR code given a specific version number
106  * Given the locations of the three finder patterns up to 4 poses are possible (P3P). To reduce the number of possible poses, this function then tries to find an additional correspondence (an alignment pattern), if it exists. If no additional correspondence was found, all possible poses will be returned.
107  * @param anyCamera The camera profile that produced the input image, must be valid
108  * @param yFrame The frame in which QR codes will be detected, must be valid, match the camera size, have its origin in the upper left corner, and have a pixel format that is compatible with Y8
109  * @param width The width of the input frame, range: [29, infinity)
110  * @param height The height of the input frame, range: [29, infinity)
111  * @param paddingElements The number of padding elements of the input frame, range: [0, infinity)
112  * @param finderPatterns The pointer to the triplet of finder patterns; must be valid and have 3 elements, the order must be top-left, bottom-left, top-right finder pattern
113  * @param version The version number that the QR code is estimated to have, range: [1, 40]
114  * @param code_T_cameras The returning possible poses that have been identified, possible size: [0, 4] (optimally it is only 1)
115  * @param scale Optional scaling factor for the coordinates in the object space, range: (0, infinity)
116  * @return True if one or more poses have been found, otherwise false
117  */
118  static bool computePoses(const AnyCamera& anyCamera, const uint8_t* const yFrame, const unsigned int width, const unsigned int height, const unsigned int paddingElements, const FinderPattern* finderPatterns, const unsigned int version, HomogenousMatrices4& code_T_cameras, const Scalar scale = Scalar(1));
119 };
120 
121 } // namespace QRCodes
122 
123 } // namespace Detector
124 
125 } // namespace CV
126 
127 } // namespace Ocean
This class implements the abstract base class for all AnyCamera objects.
Definition: AnyCamera.h:130
Definition of a class for finder patterns of QR codes (squares in the top-left, top-right and bottom-...
Definition: FinderPatternDetector.h:58
This class implements common functionality of QR code detectors but is not a stand-alone detector.
Definition: QRCodeDetector.h:33
static bool computeProvisionalVersionRange(const FinderPattern &topLeft, const FinderPattern &bottomLeft, const FinderPattern &topRight, unsigned int &versionX, unsigned int &versionY)
Determines the version of the QR code symbols from the size and distance of its three finder patterns...
static bool computeModuleSizeInPlane(const AnyCamera &anyCamera, const Plane3 &plane, const Vector2 &imagePoint, const Vector3 &planePoint, const Scalar moduleSizeInImage, Scalar &moduleSizeInPlane)
Convert the module size in pixels of a finder pattern to the size in a given plane that contains undi...
static bool computePoses(const AnyCamera &anyCamera, const uint8_t *const yFrame, const unsigned int width, const unsigned int height, const unsigned int paddingElements, const FinderPattern *finderPatterns, const unsigned int version, HomogenousMatrices4 &code_T_cameras, const Scalar scale=Scalar(1))
Computes poses of a QR code given a specific version number Given the locations of the three finder p...
static bool extractModulesFromImage(const AnyCamera &anyCamera, const uint8_t *const yFrame, const unsigned int width, const unsigned int height, const unsigned int paddingElements, const unsigned int version, const HomogenousMatrix4 &code_T_camera, const bool isNormalReflectance, const unsigned int grayThreshold, std::vector< uint8_t > &modules, const Scalar scale=Scalar(1))
Extracts all modules of a QR code from an image.
static bool computeProvisionalVersionRange(const AnyCamera &anyCamera, const FinderPattern *finderPatterns, const unsigned int maxAllowedVersionDifference, unsigned int &versionLow, unsigned int &versionHigh)
Estimates the range of version numbers based on pixel distances of pairs of finder patterns Estimates...
static bool computeProvisionalVersion(const Vector3 &centerA, const Vector3 &centerB, const Scalar moduleSizeA, const Scalar moduleSizeB, const unsigned int maxAllowedVersionDifference, unsigned int &versionLow, unsigned int &versionHigh)
Estimates the version numbers based on pixel distances of a pair of finder patterns.
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< HomogenousMatrix4 > HomogenousMatrices4
Definition of a vector holding HomogenousMatrix4 objects.
Definition: HomogenousMatrix4.h:73
std::vector< QRCode > QRCodes
Definition of a vector of QR codes.
Definition: QRCode.h:25
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15