Merge pull request #22986 from AleksandrPanov:move_contrib_charuco_to_main_objdetect
[platform/upstream/opencv.git] / modules / objdetect / include / opencv2 / objdetect / aruco_detector.hpp
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html
4 #ifndef OPENCV_OBJDETECT_ARUCO_DETECTOR_HPP
5 #define OPENCV_OBJDETECT_ARUCO_DETECTOR_HPP
6
7 #include <opencv2/objdetect/aruco_dictionary.hpp>
8 #include <opencv2/objdetect/aruco_board.hpp>
9
10 namespace cv {
11 namespace aruco {
12
13 //! @addtogroup objdetect_aruco
14 //! @{
15
16 enum CornerRefineMethod{
17     CORNER_REFINE_NONE,     ///< Tag and corners detection based on the ArUco approach
18     CORNER_REFINE_SUBPIX,   ///< ArUco approach and refine the corners locations using corner subpixel accuracy
19     CORNER_REFINE_CONTOUR,  ///< ArUco approach and refine the corners locations using the contour-points line fitting
20     CORNER_REFINE_APRILTAG, ///< Tag and corners detection based on the AprilTag 2 approach @cite wang2016iros
21 };
22
23 /** @brief struct DetectorParameters is used by ArucoDetector
24  */
25 struct CV_EXPORTS_W_SIMPLE DetectorParameters {
26     CV_WRAP DetectorParameters() {
27         adaptiveThreshWinSizeMin = 3;
28         adaptiveThreshWinSizeMax = 23;
29         adaptiveThreshWinSizeStep = 10;
30         adaptiveThreshConstant = 7;
31         minMarkerPerimeterRate = 0.03;
32         maxMarkerPerimeterRate = 4.;
33         polygonalApproxAccuracyRate = 0.03;
34         minCornerDistanceRate = 0.05;
35         minDistanceToBorder = 3;
36         minMarkerDistanceRate = 0.05;
37         cornerRefinementMethod = CORNER_REFINE_NONE;
38         cornerRefinementWinSize = 5;
39         cornerRefinementMaxIterations = 30;
40         cornerRefinementMinAccuracy = 0.1;
41         markerBorderBits = 1;
42         perspectiveRemovePixelPerCell = 4;
43         perspectiveRemoveIgnoredMarginPerCell = 0.13;
44         maxErroneousBitsInBorderRate = 0.35;
45         minOtsuStdDev = 5.0;
46         errorCorrectionRate = 0.6;
47         aprilTagQuadDecimate = 0.0;
48         aprilTagQuadSigma = 0.0;
49         aprilTagMinClusterPixels = 5;
50         aprilTagMaxNmaxima = 10;
51         aprilTagCriticalRad = (float)(10* CV_PI /180);
52         aprilTagMaxLineFitMse = 10.0;
53         aprilTagMinWhiteBlackDiff = 5;
54         aprilTagDeglitch = 0;
55         detectInvertedMarker = false;
56         useAruco3Detection = false;
57         minSideLengthCanonicalImg = 32;
58         minMarkerLengthRatioOriginalImg = 0.0;
59     };
60
61     /** @brief Read a new set of DetectorParameters from FileNode (use FileStorage.root()).
62      */
63     CV_WRAP bool readDetectorParameters(const FileNode& fn);
64
65     /** @brief Write a set of DetectorParameters to FileStorage
66      */
67     CV_WRAP bool writeDetectorParameters(FileStorage& fs, const String& name = String());
68
69     /// minimum window size for adaptive thresholding before finding contours (default 3).
70     CV_PROP_RW int adaptiveThreshWinSizeMin;
71
72     /// maximum window size for adaptive thresholding before finding contours (default 23).
73     CV_PROP_RW int adaptiveThreshWinSizeMax;
74
75     /// increments from adaptiveThreshWinSizeMin to adaptiveThreshWinSizeMax during the thresholding (default 10).
76     CV_PROP_RW int adaptiveThreshWinSizeStep;
77
78     /// constant for adaptive thresholding before finding contours (default 7)
79     CV_PROP_RW double adaptiveThreshConstant;
80
81     /** @brief determine minimum perimeter for marker contour to be detected.
82      *
83      * This is defined as a rate respect to the maximum dimension of the input image (default 0.03).
84      */
85     CV_PROP_RW double minMarkerPerimeterRate;
86
87     /** @brief determine maximum perimeter for marker contour to be detected.
88      *
89      * This is defined as a rate respect to the maximum dimension of the input image (default 4.0).
90      */
91     CV_PROP_RW double maxMarkerPerimeterRate;
92
93     /// minimum accuracy during the polygonal approximation process to determine which contours are squares. (default 0.03)
94     CV_PROP_RW double polygonalApproxAccuracyRate;
95
96     /// minimum distance between corners for detected markers relative to its perimeter (default 0.05)
97     CV_PROP_RW double minCornerDistanceRate;
98
99     /// minimum distance of any corner to the image border for detected markers (in pixels) (default 3)
100     CV_PROP_RW int minDistanceToBorder;
101
102     /** @brief minimum mean distance beetween two marker corners to be considered imilar, so that the smaller one is removed.
103      *
104      * The rate is relative to the smaller perimeter of the two markers (default 0.05).
105      */
106     CV_PROP_RW double minMarkerDistanceRate;
107
108     /** @brief default value CORNER_REFINE_NONE */
109     CV_PROP_RW CornerRefineMethod cornerRefinementMethod;
110
111     /// window size for the corner refinement process (in pixels) (default 5).
112     CV_PROP_RW int cornerRefinementWinSize;
113
114     /// maximum number of iterations for stop criteria of the corner refinement process (default 30).
115     CV_PROP_RW int cornerRefinementMaxIterations;
116
117     /// minimum error for the stop cristeria of the corner refinement process (default: 0.1)
118     CV_PROP_RW double cornerRefinementMinAccuracy;
119
120     /// number of bits of the marker border, i.e. marker border width (default 1).
121     CV_PROP_RW int markerBorderBits;
122
123     /// number of bits (per dimension) for each cell of the marker when removing the perspective (default 4).
124     CV_PROP_RW int perspectiveRemovePixelPerCell;
125
126     /** @brief width of the margin of pixels on each cell not considered for the determination of the cell bit.
127      *
128      * Represents the rate respect to the total size of the cell, i.e. perspectiveRemovePixelPerCell (default 0.13)
129      */
130     CV_PROP_RW double perspectiveRemoveIgnoredMarginPerCell;
131
132     /** @brief  maximum number of accepted erroneous bits in the border (i.e. number of allowed white bits in the border).
133      *
134      * Represented as a rate respect to the total number of bits per marker (default 0.35).
135      */
136     CV_PROP_RW double maxErroneousBitsInBorderRate;
137
138     /** @brief minimun standard deviation in pixels values during the decodification step to apply Otsu
139      * thresholding (otherwise, all the bits are set to 0 or 1 depending on mean higher than 128 or not) (default 5.0)
140      */
141     CV_PROP_RW double minOtsuStdDev;
142
143     /// error correction rate respect to the maximun error correction capability for each dictionary (default 0.6).
144     CV_PROP_RW double errorCorrectionRate;
145
146     /** @brief April :: User-configurable parameters.
147      *
148      * Detection of quads can be done on a lower-resolution image, improving speed at a cost of
149      * pose accuracy and a slight decrease in detection rate. Decoding the binary payload is still
150      */
151     CV_PROP_RW float aprilTagQuadDecimate;
152
153     /// what Gaussian blur should be applied to the segmented image (used for quad detection?)
154     CV_PROP_RW float aprilTagQuadSigma;
155
156     // April :: Internal variables
157     /// reject quads containing too few pixels (default 5).
158     CV_PROP_RW int aprilTagMinClusterPixels;
159
160     /// how many corner candidates to consider when segmenting a group of pixels into a quad (default 10).
161     CV_PROP_RW int aprilTagMaxNmaxima;
162
163     /** @brief reject quads where pairs of edges have angles that are close to straight or close to 180 degrees.
164      *
165      * Zero means that no quads are rejected. (In radians) (default 10*PI/180)
166      */
167     CV_PROP_RW float aprilTagCriticalRad;
168
169     /// when fitting lines to the contours, what is the maximum mean squared error
170     CV_PROP_RW float aprilTagMaxLineFitMse;
171
172     /** @brief add an extra check that the white model must be (overall) brighter than the black model.
173      *
174      * When we build our model of black & white pixels, we add an extra check that the white model must be (overall)
175      * brighter than the black model. How much brighter? (in pixel values, [0,255]), (default 5)
176      */
177     CV_PROP_RW int aprilTagMinWhiteBlackDiff;
178
179     /// should the thresholded image be deglitched? Only useful for very noisy images (default 0).
180     CV_PROP_RW int aprilTagDeglitch;
181
182     /** @brief to check if there is a white marker.
183      *
184      * In order to generate a "white" marker just invert a normal marker by using a tilde, ~markerImage. (default false)
185      */
186     CV_PROP_RW bool detectInvertedMarker;
187
188     /** @brief enable the new and faster Aruco detection strategy.
189      *
190      * Proposed in the paper:
191      * Romero-Ramirez et al: Speeded up detection of squared fiducial markers (2018)
192      * https://www.researchgate.net/publication/325787310_Speeded_Up_Detection_of_Squared_Fiducial_Markers
193      */
194     CV_PROP_RW bool useAruco3Detection;
195
196     /// minimum side length of a marker in the canonical image. Latter is the binarized image in which contours are searched.
197     CV_PROP_RW int minSideLengthCanonicalImg;
198
199     /// range [0,1], eq (2) from paper. The parameter tau_i has a direct influence on the processing speed.
200     CV_PROP_RW float minMarkerLengthRatioOriginalImg;
201 };
202
203 /** @brief struct RefineParameters is used by ArucoDetector
204  */
205 struct CV_EXPORTS_W_SIMPLE RefineParameters {
206     CV_WRAP RefineParameters(float minRepDistance = 10.f, float errorCorrectionRate = 3.f, bool checkAllOrders = true);
207
208
209     /** @brief Read a new set of RefineParameters from FileNode (use FileStorage.root()).
210      */
211     CV_WRAP bool readRefineParameters(const FileNode& fn);
212
213     /** @brief Write a set of RefineParameters to FileStorage
214      */
215     CV_WRAP bool writeRefineParameters(FileStorage& fs, const String& name = String());
216
217     /** @brief minRepDistance minimum distance between the corners of the rejected candidate and the reprojected marker
218     in order to consider it as a correspondence.
219      */
220     CV_PROP_RW float minRepDistance;
221
222     /** @brief minRepDistance rate of allowed erroneous bits respect to the error correction capability of the used dictionary.
223      *
224      * -1 ignores the error correction step.
225      */
226     CV_PROP_RW float errorCorrectionRate;
227
228     /** @brief checkAllOrders consider the four posible corner orders in the rejectedCorners array.
229      *
230      * If it set to false, only the provided corner order is considered (default true).
231      */
232     CV_PROP_RW bool checkAllOrders;
233 };
234
235 /** @brief The main functionality of ArucoDetector class is detection of markers in an image with detectMarkers() method.
236  *
237  * After detecting some markers in the image, you can try to find undetected markers from this dictionary with
238  * refineDetectedMarkers() method.
239  *
240  * @see DetectorParameters, RefineParameters
241  */
242 class CV_EXPORTS_W ArucoDetector : public Algorithm
243 {
244 public:
245     /** @brief Basic ArucoDetector constructor
246      *
247      * @param dictionary indicates the type of markers that will be searched
248      * @param detectorParams marker detection parameters
249      * @param refineParams marker refine detection parameters
250      */
251     CV_WRAP ArucoDetector(const Dictionary &dictionary = getPredefinedDictionary(cv::aruco::DICT_4X4_50),
252                           const DetectorParameters &detectorParams = DetectorParameters(),
253                           const RefineParameters& refineParams = RefineParameters());
254
255     /** @brief Basic marker detection
256      *
257      * @param image input image
258      * @param corners vector of detected marker corners. For each marker, its four corners
259      * are provided, (e.g std::vector<std::vector<cv::Point2f> > ). For N detected markers,
260      * the dimensions of this array is Nx4. The order of the corners is clockwise.
261      * @param ids vector of identifiers of the detected markers. The identifier is of type int
262      * (e.g. std::vector<int>). For N detected markers, the size of ids is also N.
263      * The identifiers have the same order than the markers in the imgPoints array.
264      * @param rejectedImgPoints contains the imgPoints of those squares whose inner code has not a
265      * correct codification. Useful for debugging purposes.
266      *
267      * Performs marker detection in the input image. Only markers included in the specific dictionary
268      * are searched. For each detected marker, it returns the 2D position of its corner in the image
269      * and its corresponding identifier.
270      * Note that this function does not perform pose estimation.
271      * @note The function does not correct lens distortion or takes it into account. It's recommended to undistort
272      * input image with corresponging camera model, if camera parameters are known
273      * @sa undistort, estimatePoseSingleMarkers,  estimatePoseBoard
274      */
275     CV_WRAP void detectMarkers(InputArray image, OutputArrayOfArrays corners, OutputArray ids,
276                                OutputArrayOfArrays rejectedImgPoints = noArray()) const;
277
278     /** @brief Refind not detected markers based on the already detected and the board layout
279      *
280      * @param image input image
281      * @param board layout of markers in the board.
282      * @param detectedCorners vector of already detected marker corners.
283      * @param detectedIds vector of already detected marker identifiers.
284      * @param rejectedCorners vector of rejected candidates during the marker detection process.
285      * @param cameraMatrix optional input 3x3 floating-point camera matrix
286      * \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$
287      * @param distCoeffs optional vector of distortion coefficients
288      * \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6],[s_1, s_2, s_3, s_4]])\f$ of 4, 5, 8 or 12 elements
289      * @param recoveredIdxs Optional array to returns the indexes of the recovered candidates in the
290      * original rejectedCorners array.
291      *
292      * This function tries to find markers that were not detected in the basic detecMarkers function.
293      * First, based on the current detected marker and the board layout, the function interpolates
294      * the position of the missing markers. Then it tries to find correspondence between the reprojected
295      * markers and the rejected candidates based on the minRepDistance and errorCorrectionRate parameters.
296      * If camera parameters and distortion coefficients are provided, missing markers are reprojected
297      * using projectPoint function. If not, missing marker projections are interpolated using global
298      * homography, and all the marker corners in the board must have the same Z coordinate.
299      */
300     CV_WRAP void refineDetectedMarkers(InputArray image, const Board &board,
301                                        InputOutputArrayOfArrays detectedCorners,
302                                        InputOutputArray detectedIds, InputOutputArrayOfArrays rejectedCorners,
303                                        InputArray cameraMatrix = noArray(), InputArray distCoeffs = noArray(),
304                                        OutputArray recoveredIdxs = noArray()) const;
305
306     CV_WRAP const Dictionary& getDictionary() const;
307     CV_WRAP void setDictionary(const Dictionary& dictionary);
308
309     CV_WRAP const DetectorParameters& getDetectorParameters() const;
310     CV_WRAP void setDetectorParameters(const DetectorParameters& detectorParameters);
311
312     CV_WRAP const RefineParameters& getRefineParameters() const;
313     CV_WRAP void setRefineParameters(const RefineParameters& refineParameters);
314
315     /** @brief Stores algorithm parameters in a file storage
316     */
317     virtual void write(FileStorage& fs) const override;
318
319     /** @brief simplified API for language bindings
320     */
321     CV_WRAP inline void write(FileStorage& fs, const String& name) { Algorithm::write(fs, name); }
322
323     /** @brief Reads algorithm parameters from a file storage
324     */
325     CV_WRAP virtual void read(const FileNode& fn) override;
326 protected:
327     struct ArucoDetectorImpl;
328     Ptr<ArucoDetectorImpl> arucoDetectorImpl;
329 };
330
331 /** @brief Draw detected markers in image
332  *
333  * @param image input/output image. It must have 1 or 3 channels. The number of channels is not altered.
334  * @param corners positions of marker corners on input image.
335  * (e.g std::vector<std::vector<cv::Point2f> > ). For N detected markers, the dimensions of
336  * this array should be Nx4. The order of the corners should be clockwise.
337  * @param ids vector of identifiers for markers in markersCorners .
338  * Optional, if not provided, ids are not painted.
339  * @param borderColor color of marker borders. Rest of colors (text color and first corner color)
340  * are calculated based on this one to improve visualization.
341  *
342  * Given an array of detected marker corners and its corresponding ids, this functions draws
343  * the markers in the image. The marker borders are painted and the markers identifiers if provided.
344  * Useful for debugging purposes.
345  */
346 CV_EXPORTS_W void drawDetectedMarkers(InputOutputArray image, InputArrayOfArrays corners,
347                                       InputArray ids = noArray(), Scalar borderColor = Scalar(0, 255, 0));
348
349 /** @brief Generate a canonical marker image
350  *
351  * @param dictionary dictionary of markers indicating the type of markers
352  * @param id identifier of the marker that will be returned. It has to be a valid id in the specified dictionary.
353  * @param sidePixels size of the image in pixels
354  * @param img output image with the marker
355  * @param borderBits width of the marker border.
356  *
357  * This function returns a marker image in its canonical form (i.e. ready to be printed)
358  */
359 CV_EXPORTS_W void generateImageMarker(const Dictionary &dictionary, int id, int sidePixels, OutputArray img,
360                                       int borderBits = 1);
361
362 //! @}
363
364 }
365 }
366
367 #endif