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_DICTIONARY_HPP
5#define OPENCV_OBJDETECT_DICTIONARY_HPP
6
7#include <opencv2/core.hpp>
8
9namespace cv {
10namespace aruco {
11
12//! @addtogroup objdetect_aruco
13//! @{
14
15
16/** @brief Dictionary is a set of unique ArUco markers of the same size
17 *
18 * `bytesList` storing as 2-dimensions Mat with 4-th channels (CV_8UC4 type was used) and contains the marker codewords where:
19 * - bytesList.rows is the dictionary size
20 * - each marker is encoded using `nbytes = ceil(markerSize*markerSize/8.)` bytes
21 * - each row contains all 4 rotations of the marker, so its length is `4*nbytes`
22 * - the byte order in the bytesList[i] row:
23 * `//bytes without rotation/bytes with rotation 1/bytes with rotation 2/bytes with rotation 3//`
24 * So `bytesList.ptr(i)[k*nbytes + j]` is the j-th byte of i-th marker, in its k-th rotation.
25 * @note Python bindings generate matrix with shape of bytesList `dictionary_size x nbytes x 4`,
26 * but it should be indexed like C++ version. Python example for j-th byte of i-th marker, in its k-th rotation:
27 * `aruco_dict.bytesList[id].ravel()[k*nbytes + j]`
28 */
29class CV_EXPORTS_W_SIMPLE Dictionary {
30
31 public:
32 CV_PROP_RW Mat bytesList; ///< marker code information. See class description for more details
33 CV_PROP_RW int markerSize; ///< number of bits per dimension
34 CV_PROP_RW int maxCorrectionBits; ///< maximum number of bits that can be corrected
35
36 CV_WRAP Dictionary();
37
38 /** @brief Basic ArUco dictionary constructor
39 *
40 * @param bytesList bits for all ArUco markers in dictionary see memory layout in the class description
41 * @param _markerSize ArUco marker size in units
42 * @param maxcorr maximum number of bits that can be corrected
43 */
44 CV_WRAP Dictionary(const Mat &bytesList, int _markerSize, int maxcorr = 0);
45
46 /** @brief Read a new dictionary from FileNode.
47 *
48 * Dictionary example in YAML format:\n
49 * nmarkers: 35\n
50 * markersize: 6\n
51 * maxCorrectionBits: 5\n
52 * marker_0: "101011111011111001001001101100000000"\n
53 * ...\n
54 * marker_34: "011111010000111011111110110101100101"
55 */
56 CV_WRAP bool readDictionary(const cv::FileNode& fn);
57
58 /** @brief Write a dictionary to FileStorage, format is the same as in readDictionary().
59 */
60 CV_WRAP void writeDictionary(FileStorage& fs, const String& name = String());
61
62 /** @brief Given a matrix of bits. Returns whether if marker is identified or not.
63 *
64 * Returns reference to the marker id in the dictionary (if any) and its rotation.
65 */
66 CV_WRAP bool identify(const Mat &onlyBits, CV_OUT int &idx, CV_OUT int &rotation, double maxCorrectionRate) const;
67
68 /** @brief Returns Hamming distance of the input bits to the specific id.
69 *
70 * If `allRotations` flag is set, the four posible marker rotations are considered
71 */
72 CV_WRAP int getDistanceToId(InputArray bits, int id, bool allRotations = true) const;
73
74
75 /** @brief Generate a canonical marker image
76 */
77 CV_WRAP void generateImageMarker(int id, int sidePixels, OutputArray _img, int borderBits = 1) const;
78
79
80 /** @brief Transform matrix of bits to list of bytes with 4 marker rotations
81 */
82 CV_WRAP static Mat getByteListFromBits(const Mat &bits);
83
84
85 /** @brief Transform list of bytes to matrix of bits
86 */
87 CV_WRAP static Mat getBitsFromByteList(const Mat &byteList, int markerSize);
88};
89
90
91
92
93/** @brief Predefined markers dictionaries/sets
94 *
95 * Each dictionary indicates the number of bits and the number of markers contained
96 * - DICT_ARUCO_ORIGINAL: standard ArUco Library Markers. 1024 markers, 5x5 bits, 0 minimum
97 distance
98 */
99enum PredefinedDictionaryType {
100 DICT_4X4_50 = 0, ///< 4x4 bits, minimum hamming distance between any two codes = 4, 50 codes
101 DICT_4X4_100, ///< 4x4 bits, minimum hamming distance between any two codes = 3, 100 codes
102 DICT_4X4_250, ///< 4x4 bits, minimum hamming distance between any two codes = 3, 250 codes
103 DICT_4X4_1000, ///< 4x4 bits, minimum hamming distance between any two codes = 2, 1000 codes
104 DICT_5X5_50, ///< 5x5 bits, minimum hamming distance between any two codes = 8, 50 codes
105 DICT_5X5_100, ///< 5x5 bits, minimum hamming distance between any two codes = 7, 100 codes
106 DICT_5X5_250, ///< 5x5 bits, minimum hamming distance between any two codes = 6, 250 codes
107 DICT_5X5_1000, ///< 5x5 bits, minimum hamming distance between any two codes = 5, 1000 codes
108 DICT_6X6_50, ///< 6x6 bits, minimum hamming distance between any two codes = 13, 50 codes
109 DICT_6X6_100, ///< 6x6 bits, minimum hamming distance between any two codes = 12, 100 codes
110 DICT_6X6_250, ///< 6x6 bits, minimum hamming distance between any two codes = 11, 250 codes
111 DICT_6X6_1000, ///< 6x6 bits, minimum hamming distance between any two codes = 9, 1000 codes
112 DICT_7X7_50, ///< 7x7 bits, minimum hamming distance between any two codes = 19, 50 codes
113 DICT_7X7_100, ///< 7x7 bits, minimum hamming distance between any two codes = 18, 100 codes
114 DICT_7X7_250, ///< 7x7 bits, minimum hamming distance between any two codes = 17, 250 codes
115 DICT_7X7_1000, ///< 7x7 bits, minimum hamming distance between any two codes = 14, 1000 codes
116 DICT_ARUCO_ORIGINAL, ///< 6x6 bits, minimum hamming distance between any two codes = 3, 1024 codes
117 DICT_APRILTAG_16h5, ///< 4x4 bits, minimum hamming distance between any two codes = 5, 30 codes
118 DICT_APRILTAG_25h9, ///< 5x5 bits, minimum hamming distance between any two codes = 9, 35 codes
119 DICT_APRILTAG_36h10, ///< 6x6 bits, minimum hamming distance between any two codes = 10, 2320 codes
120 DICT_APRILTAG_36h11, ///< 6x6 bits, minimum hamming distance between any two codes = 11, 587 codes
121 DICT_ARUCO_MIP_36h12 ///< 6x6 bits, minimum hamming distance between any two codes = 12, 250 codes
122};
123
124
125/** @brief Returns one of the predefined dictionaries defined in PredefinedDictionaryType
126 */
127CV_EXPORTS Dictionary getPredefinedDictionary(PredefinedDictionaryType name);
128
129
130/** @brief Returns one of the predefined dictionaries referenced by DICT_*.
131 */
132CV_EXPORTS_W Dictionary getPredefinedDictionary(int dict);
133
134/** @brief Extend base dictionary by new nMarkers
135 *
136 * @param nMarkers number of markers in the dictionary
137 * @param markerSize number of bits per dimension of each markers
138 * @param baseDictionary Include the markers in this dictionary at the beginning (optional)
139 * @param randomSeed a user supplied seed for theRNG()
140 *
141 * This function creates a new dictionary composed by nMarkers markers and each markers composed
142 * by markerSize x markerSize bits. If baseDictionary is provided, its markers are directly
143 * included and the rest are generated based on them. If the size of baseDictionary is higher
144 * than nMarkers, only the first nMarkers in baseDictionary are taken and no new marker is added.
145 */
146CV_EXPORTS_W Dictionary extendDictionary(int nMarkers, int markerSize, const Dictionary &baseDictionary = Dictionary(),
147 int randomSeed=0);
148
149
150
151//! @}
152}
153}
154
155#endif
156

source code of opencv/modules/objdetect/include/opencv2/objdetect/aruco_dictionary.hpp