Commit 81d7d980 authored by catree's avatar catree

Add AprilTag dictionaries to be able to detect AprilTag markers. Add ArUco and…

Add AprilTag dictionaries to be able to detect AprilTag markers. Add ArUco and AprilTag 2 citations.
parent c5404095
@article{Aruco2014,
title = "Automatic generation and detection of highly reliable fiducial markers under occlusion ",
journal = "Pattern Recognition ",
volume = "47",
number = "6",
pages = "2280 - 2292",
year = "2014",
issn = "0031-3203",
doi = "http://dx.doi.org/10.1016/j.patcog.2014.01.005",
url = "http://www.sciencedirect.com/science/article/pii/S0031320314000235",
author = "S. Garrido-Jurado and R. Mu\~noz-Salinas and F.J. Madrid-Cuevas and M.J. Mar\'in-Jim\'enez"
}
@inproceedings{wang2016iros,
AUTHOR = {John Wang and Edwin Olson},
TITLE = {{AprilTag} 2: Efficient and robust fiducial detection},
BOOKTITLE = {Proceedings of the {IEEE/RSJ} International Conference on Intelligent
Robots and Systems {(IROS)}},
YEAR = {2016},
MONTH = {October},
}
......@@ -49,14 +49,16 @@ the use of this software, even if advised of the possibility of such damage.
* These markers are useful for easy, fast and robust camera pose estimation.ç
*
* The main functionalities are:
* - Detection of markers in a image
* - Detection of markers in an image
* - Pose estimation from a single marker or from a board/set of markers
* - Detection of ChArUco board for high subpixel accuracy
* - Camera calibration from both, ArUco boards and ChArUco boards.
* - Detection of ChArUco diamond markers
* The samples directory includes easy examples of how to use the module.
*
* The implementation is based on the ArUco Library by R. Muñoz-Salinas and S. Garrido-Jurado.
* The implementation is based on the ArUco Library by R. Muñoz-Salinas and S. Garrido-Jurado @cite Aruco2014.
*
* Markers can also be detected based on the AprilTag 2 @cite wang2016iros fiducial detection method.
*
* @sa S. Garrido-Jurado, R. Muñoz-Salinas, F. J. Madrid-Cuevas, and M. J. Marín-Jiménez. 2014.
* "Automatic generation and detection of highly reliable fiducial markers under occlusion".
......@@ -77,10 +79,10 @@ namespace aruco {
//! @{
enum CornerRefineMethod{
CORNER_REFINE_NONE, // default corners
CORNER_REFINE_SUBPIX, // refine the corners using subpix
CORNER_REFINE_CONTOUR, // refine the corners using the contour-points
CORNER_REFINE_APRILTAG, // detect corners using the AprilTag2 approach
CORNER_REFINE_NONE, ///< Tag and corners detection based on the ArUco approach
CORNER_REFINE_SUBPIX, ///< ArUco approach and refine the corners locations using corner subpixel accuracy
CORNER_REFINE_CONTOUR, ///< ArUco approach and refine the corners locations using the contour-points line fitting
CORNER_REFINE_APRILTAG, ///< Tag and corners detection based on the AprilTag 2 approach @cite wang2016iros
};
/**
......
......@@ -155,7 +155,11 @@ enum CV_EXPORTS_W_SIMPLE PREDEFINED_DICTIONARY_NAME {
DICT_7X7_100,
DICT_7X7_250,
DICT_7X7_1000,
DICT_ARUCO_ORIGINAL
DICT_ARUCO_ORIGINAL,
DICT_APRILTAG_16h5, ///< 4x4 bits, minimum hamming distance between any two codes = 5, 30 codes
DICT_APRILTAG_25h9, ///< 5x5 bits, minimum hamming distance between any two codes = 9, 35 codes
DICT_APRILTAG_36h10, ///< 6x6 bits, minimum hamming distance between any two codes = 10, 2320 codes
DICT_APRILTAG_36h11 ///< 6x6 bits, minimum hamming distance between any two codes = 11, 587 codes
};
......
......@@ -50,13 +50,16 @@ const char* keys =
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20}"
"{v | | Input from video file, if ommited, input comes from camera }"
"{ci | 0 | Camera id if input doesnt come from video (-v) }"
"{c | | Camera intrinsic parameters. Needed for camera pose }"
"{l | 0.1 | Marker side lenght (in meters). Needed for correct scale in camera pose }"
"{dp | | File of marker detector parameters }"
"{r | | show rejected candidates too }";
"{r | | show rejected candidates too }"
"{refine | | Corner refinement: CORNER_REFINE_NONE=0, CORNER_REFINE_SUBPIX=1,"
"CORNER_REFINE_CONTOUR=2, CORNER_REFINE_APRILTAG=3}";
}
/**
......@@ -127,7 +130,12 @@ int main(int argc, char *argv[]) {
return 0;
}
}
detectorParams->cornerRefinementMethod = aruco::CORNER_REFINE_SUBPIX; // do corner refinement in markers
if (parser.has("refine")) {
//override cornerRefinementMethod read from config file
detectorParams->cornerRefinementMethod = parser.get<int>("refine");
}
std::cout << "Corner refinement method (0: None, 1: Subpixel, 2:contour, 3: AprilTag 2): " << detectorParams->cornerRefinementMethod << std::endl;
int camId = parser.get<int>("ci");
......
......@@ -41,6 +41,7 @@ the use of this software, even if advised of the possibility of such damage.
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include "predefined_dictionaries.hpp"
#include "predefined_dictionaries_apriltag.hpp"
#include "opencv2/core/hal/hal.hpp"
namespace cv {
......@@ -291,6 +292,11 @@ const Dictionary DICT_7X7_100_DATA = Dictionary(Mat(100, (7*7 + 7)/8 ,CV_8UC4, (
const Dictionary DICT_7X7_250_DATA = Dictionary(Mat(250, (7*7 + 7)/8 ,CV_8UC4, (uchar*)DICT_7X7_1000_BYTES), 7, 8);
const Dictionary DICT_7X7_1000_DATA = Dictionary(Mat(1000, (7*7 + 7)/8 ,CV_8UC4, (uchar*)DICT_7X7_1000_BYTES), 7, 6);
const Dictionary DICT_APRILTAG_16h5_DATA = Dictionary(Mat(30, (4*4 + 7)/8, CV_8UC4, (uchar*)DICT_APRILTAG_16h5_BYTES), 4, 0);
const Dictionary DICT_APRILTAG_25h9_DATA = Dictionary(Mat(35, (5*5 + 7)/8, CV_8UC4, (uchar*)DICT_APRILTAG_25h9_BYTES), 5, 0);
const Dictionary DICT_APRILTAG_36h10_DATA = Dictionary(Mat(2320, (6*6 + 7)/8, CV_8UC4, (uchar*)DICT_APRILTAG_36h10_BYTES), 6, 0);
const Dictionary DICT_APRILTAG_36h11_DATA = Dictionary(Mat(587, (6*6 + 7)/8, CV_8UC4, (uchar*)DICT_APRILTAG_36h11_BYTES), 6, 0);
Ptr<Dictionary> getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME name) {
switch(name) {
......@@ -334,6 +340,15 @@ Ptr<Dictionary> getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME name) {
case DICT_7X7_1000:
return makePtr<Dictionary>(DICT_7X7_1000_DATA);
case DICT_APRILTAG_16h5:
return makePtr<Dictionary>(DICT_APRILTAG_16h5_DATA);
case DICT_APRILTAG_25h9:
return makePtr<Dictionary>(DICT_APRILTAG_25h9_DATA);
case DICT_APRILTAG_36h10:
return makePtr<Dictionary>(DICT_APRILTAG_36h10_DATA);
case DICT_APRILTAG_36h11:
return makePtr<Dictionary>(DICT_APRILTAG_36h11_DATA);
}
return makePtr<Dictionary>(DICT_4X4_50_DATA);
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment