Ocean
MicroQRCodeDetector2D.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #pragma once
9 
11 
15 
16 #include "ocean/base/Frame.h"
17 
18 #include "ocean/math/AnyCamera.h"
19 #include "ocean/math/Vector2.h"
20 
21 namespace Ocean
22 {
23 
24 namespace CV
25 {
26 
27 namespace Detector
28 {
29 
30 namespace QRCodes
31 {
32 
33 /**
34  * This class implements a detector for Micro QR Codes.
35  * @ingroup cvdetectorqrcodes
36  */
37 class OCEAN_CV_DETECTOR_QRCODES_EXPORT MicroQRCodeDetector2D : public MicroQRCodeDetector
38 {
39  public:
40 
41  /**
42  * Definition of an observation of Micro QR code in 2D
43  */
45  {
46  public:
47 
48  /**
49  * Creates an invalid observation
50  */
51  Observation() = default;
52 
53  /**
54  * Creates an valid observation
55  * @param code_T_camera The transformation that maps 3D coordinates in the Micro QR code grid to the camera frame of reference, i.e., `imagePoint = anyCamera.projectToImage(code_T_camera, codePoint)`
56  * @param finderPattern The finder patterns of the Micro QR Code
57  */
58  inline explicit Observation(const HomogenousMatrix4& code_T_camera, const FinderPattern& finderPattern);
59 
60  /**
61  * Returns if the observation is valid
62  * @return True if the observation is valid, otherwise false
63  */
64  inline bool isValid() const;
65 
66  /**
67  * Returns the transformation that maps coordinates in the Micro QR code grid to coordinates in the reference frame of the camera
68  * @return The transformation
69  */
70  inline const HomogenousMatrix4& code_T_camera() const;
71 
72  /**
73  * Returns a pointer to the finder patterns
74  * @return The finder patterns
75  */
76  inline const FinderPattern& finderPattern() const;
77 
78  protected:
79 
80  /// The transformation that maps 3D coordinates in the Micro QR code grid to the camera frame of reference, i.e., `imagePoint = anyCamera.projectToImage(code_T_camera, codePoint)`
81  HomogenousMatrix4 code_T_camera_ = HomogenousMatrix4(false);
82 
83  /// The finder pattern of the Micro QR code
85  };
86 
87  /// Definition of a vector of observations
88  typedef std::vector<Observation> Observations;
89 
90  public:
91 
92  /**
93  * Detects Micro QR codes in an 8-bit grayscale image without lens distortion.
94  * Use this function for images without lens distortion, for example from pinhole cameras, screenshots, or similar.
95  * @param yFrame The frame in which Micro QR codes will be detected, must be valid, have its origin in the upper left corner, and have a pixel format that is compatible with Y8, minimum size is 15 x 15 pixels
96  * @param observations Optional observations of the detected Micro QR codes that will be returned, will be ignored for `nullptr`
97  * @param worker Optional worker instance for parallelization
98  * @param anyCamera The optionally returned camera profile that has been assumed internally
99  * @return The list of detected Micro QR codes
100  */
101  static inline MicroQRCodes detectMicroQRCodes(const Frame& yFrame, Observations* observations = nullptr, Worker* worker = nullptr, SharedAnyCamera* anyCamera = nullptr);
102 
103  /**
104  * Detects Micro QR codes in an 8-bit grayscale image with lens distortions
105  * Use this function for images with lens distortions, for example fisheye lenses on head-mounted devices (HMD). This requires a calibrated camera.
106  * @param anyCamera The camera profile that produced the input image, must be valid
107  * @param yFrame The frame in which Micro 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, minimum size is 15 x 15 pixels
108  * @param observations Optional observations of the detected Micro QR codes that will be returned, will be ignored for `nullptr`
109  * @param worker Optional worker instance for parallelization
110  * @return The list of detected Micro QR codes
111  */
112  static inline MicroQRCodes detectMicroQRCodes(const AnyCamera& anyCamera, const Frame& yFrame, Observations* observations = nullptr, Worker* worker = nullptr);
113 
114  /**
115  * Detects Micro QR codes in an 8-bit grayscale image
116  * @param anyCamera The camera profile that produced the input image, must be valid
117  * @param yFrame The frame in which Micro 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
118  * @param width The width of the input frame, range: [15, infinity)
119  * @param height The height of the input frame, range: [15, infinity)
120  * @param paddingElements The number of padding elements of the input frame, range: [0, infinity)
121  * @param observations Optional observations of the detected Micro QR codes that will be returned, will be ignored for `nullptr`
122  * @param worker Optional worker instance for parallelization
123  * @return The list of detected Micro QR codes
124  */
125  static MicroQRCodes detectMicroQRCodes(const AnyCamera& anyCamera, const uint8_t* const yFrame, const unsigned int width, const unsigned int height, const unsigned int paddingElements, Observations* observations = nullptr, Worker* worker = nullptr);
126 };
127 
128 inline MicroQRCodeDetector2D::Observation::Observation(const HomogenousMatrix4& code_T_camera, const FinderPattern& finderPattern) :
129  code_T_camera_(code_T_camera),
130  finderPattern_(finderPattern)
131 {
132  ocean_assert(isValid());
133 }
134 
136 {
137  return code_T_camera_.isValid();
138 }
139 
141 {
142  return code_T_camera_;
143 }
144 
146 {
147  return finderPattern_;
148 }
149 
150 inline MicroQRCodes MicroQRCodeDetector2D::detectMicroQRCodes(const Frame& yFrame, Observations* observations, Worker* worker, SharedAnyCamera* sharedAnyCamera)
151 {
153  {
154  ocean_assert(false && "Frame must be valid and an 8 bit grayscale image and the pixel origin must be the upper left corner");
155  return MicroQRCodes();
156  }
157 
158  Scalar fovX = Numeric::deg2rad(60);
159 
160  if (yFrame.height() > yFrame.width())
161  {
162  // Avoid large FOV values for pinhole cameras.
163  fovX = AnyCamera::fovY2X(fovX, Scalar(yFrame.width()) / Scalar(yFrame.height()));
164  }
165 
166  ocean_assert(fovX > Scalar(0));
167 
168  AnyCameraPinhole anyCamera(PinholeCamera(yFrame.width(), yFrame.height(), fovX));
169 
170  MicroQRCodes codes = detectMicroQRCodes(anyCamera, yFrame, observations, worker);
171 
172  if (sharedAnyCamera)
173  {
174  *sharedAnyCamera = std::make_shared<AnyCameraPinhole>(std::move(anyCamera));
175  }
176 
177  return codes;
178 }
179 
180 inline MicroQRCodes MicroQRCodeDetector2D::detectMicroQRCodes(const AnyCamera& anyCamera, const Frame& yFrame, Observations* observations, Worker* worker)
181 {
183  {
184  ocean_assert(false && "Frame must be valid and an 8 bit grayscale image and the pixel origin must be the upper left corner");
185  return MicroQRCodes();
186  }
187 
188  return detectMicroQRCodes(anyCamera, yFrame.constdata<uint8_t>(), yFrame.width(), yFrame.height(), yFrame.paddingElements(), observations, worker);
189 }
190 
191 } // namespace QRCodes
192 
193 } // namespace Detector
194 
195 } // namespace CV
196 
197 } // namespace Ocean
This class implements the abstract base class for all AnyCamera objects.
Definition: AnyCamera.h:130
This class implements a specialized AnyCamera object wrapping the actual camera model.
Definition: AnyCamera.h:494
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 Micro QR code in 2D.
Definition: MicroQRCodeDetector2D.h:45
FinderPattern finderPattern_
The finder pattern of the Micro QR code.
Definition: MicroQRCodeDetector2D.h:84
Observation()=default
Creates an invalid observation.
bool isValid() const
Returns if the observation is valid.
Definition: MicroQRCodeDetector2D.h:135
const HomogenousMatrix4 & code_T_camera() const
Returns the transformation that maps coordinates in the Micro QR code grid to coordinates in the refe...
Definition: MicroQRCodeDetector2D.h:140
const FinderPattern & finderPattern() const
Returns a pointer to the finder patterns.
Definition: MicroQRCodeDetector2D.h:145
This class implements a detector for Micro QR Codes.
Definition: MicroQRCodeDetector2D.h:38
std::vector< Observation > Observations
Definition of a vector of observations.
Definition: MicroQRCodeDetector2D.h:88
static MicroQRCodes detectMicroQRCodes(const AnyCamera &anyCamera, const uint8_t *const yFrame, const unsigned int width, const unsigned int height, const unsigned int paddingElements, Observations *observations=nullptr, Worker *worker=nullptr)
Detects Micro QR codes in an 8-bit grayscale image.
static MicroQRCodes detectMicroQRCodes(const Frame &yFrame, Observations *observations=nullptr, Worker *worker=nullptr, SharedAnyCamera *anyCamera=nullptr)
Detects Micro QR codes in an 8-bit grayscale image without lens distortion.
Definition: MicroQRCodeDetector2D.h:150
This class implements common functionality of Micro QR code detectors but is not a stand-alone detect...
Definition: MicroQRCodeDetector.h:33
static T fovY2X(const T fovY, const T aspectRatio)
Calculates the horizontal FOV from the vertical FOV and the aspect ratio of the camera image.
Definition: Camera.h:417
This class implements Ocean's image class.
Definition: Frame.h:1792
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition: Frame.h:4168
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4448
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition: Frame.h:4042
@ FORMAT_Y8
Pixel format for grayscale images with byte order Y and 8 bits per pixel.
Definition: Frame.h:594
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3143
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition: Frame.h:3188
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:3153
@ 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:3148
static constexpr T deg2rad(const T deg)
Converts deg to rad.
Definition: Numeric.h:3232
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::shared_ptr< AnyCamera > SharedAnyCamera
Definition of a shared pointer holding an AnyCamera object with Scalar precision.
Definition: AnyCamera.h:60
PinholeCameraT< Scalar > PinholeCamera
Definition of an pinhole camera object with Scalar precision.
Definition: PinholeCamera.h:32
HomogenousMatrixT4< Scalar > HomogenousMatrix4
Definition of the HomogenousMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag eit...
Definition: HomogenousMatrix4.h:37
std::vector< MicroQRCode > MicroQRCodes
Definition of a vector of Micro QR codes.
Definition: MicroQRCode.h:25
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