aruco_dictionary.hpp 7.3 KB

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