1 #include <visp3/core/vpConfig.h>
4 #include <visp3/detection/vpDetectorAprilTag.h>
6 #include <visp3/core/vpXmlParserCamera.h>
7 #include <visp3/gui/vpDisplayGDI.h>
8 #include <visp3/gui/vpDisplayOpenCV.h>
9 #include <visp3/gui/vpDisplayX.h>
10 #include <visp3/io/vpImageIo.h>
12 int main(
int argc,
const char **argv)
14 #ifdef ENABLE_VISP_NAMESPACE
18 #if defined(VISP_HAVE_APRILTAG) && (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV))
20 #ifdef ENABLE_VISP_NAMESPACE
23 std::string input_filename =
"AprilTag.pgm";
26 double tagSize = 0.053;
27 float quad_decimate = 1.0;
29 std::string intrinsic_file =
"";
30 std::string camera_name =
"";
31 bool display_tag =
false;
33 unsigned int thickness = 2;
34 bool z_aligned =
false;
36 for (
int i = 1; i < argc; i++) {
37 if (std::string(argv[i]) ==
"--pose_method" && i + 1 < argc) {
40 else if (std::string(argv[i]) ==
"--tag_size" && i + 1 < argc) {
41 tagSize = atof(argv[i + 1]);
43 else if (std::string(argv[i]) ==
"--input" && i + 1 < argc) {
44 input_filename = std::string(argv[i + 1]);
46 else if (std::string(argv[i]) ==
"--quad_decimate" && i + 1 < argc) {
47 quad_decimate =
static_cast<float>(atof(argv[i + 1]));
49 else if (std::string(argv[i]) ==
"--nthreads" && i + 1 < argc) {
50 nThreads = atoi(argv[i + 1]);
52 #if defined(VISP_HAVE_PUGIXML)
53 else if (std::string(argv[i]) ==
"--intrinsic" && i + 1 < argc) {
54 intrinsic_file = std::string(argv[i + 1]);
56 else if (std::string(argv[i]) ==
"--camera_name" && i + 1 < argc) {
57 camera_name = std::string(argv[i + 1]);
60 else if (std::string(argv[i]) ==
"--display_tag") {
63 else if (std::string(argv[i]) ==
"--color" && i + 1 < argc) {
64 color_id = atoi(argv[i + 1]);
66 else if (std::string(argv[i]) ==
"--thickness" && i + 1 < argc) {
67 thickness =
static_cast<unsigned int>(atoi(argv[i + 1]));
69 else if (std::string(argv[i]) ==
"--tag_family" && i + 1 < argc) {
72 else if (std::string(argv[i]) ==
"--z_aligned") {
75 else if (std::string(argv[i]) ==
"--help" || std::string(argv[i]) ==
"-h") {
76 std::cout <<
"Usage: " << argv[0]
77 <<
" [--input <input file>] [--tag_size <tag_size in m>]"
78 " [--quad_decimate <quad_decimate>] [--nthreads <nb>]"
79 " [--intrinsic <intrinsic file>] [--camera_name <camera name>]"
80 " [--pose_method <method> (0: HOMOGRAPHY, 1: HOMOGRAPHY_VIRTUAL_VS, "
81 " 2: DEMENTHON_VIRTUAL_VS, 3: LAGRANGE_VIRTUAL_VS, "
82 " 4: BEST_RESIDUAL_VIRTUAL_VS, 5: HOMOGRAPHY_ORTHOGONAL_ITERATION) (default: 0)]"
83 " [--tag_family <family> (0: TAG_36h11, 1: TAG_36h10 (DEPRECATED), 2: TAG_36ARTOOLKIT (DEPRECATED),"
84 " 3: TAG_25h9, 4: TAG_25h7 (DEPRECATED), 5: TAG_16h5, 6: TAG_CIRCLE21h7, 7: TAG_CIRCLE49h12,"
85 " 8: TAG_CUSTOM48h12, 9: TAG_STANDARD41h12, 10: TAG_STANDARD52h13) (default: 0)]"
86 " [--display_tag] [--color <color_id (0, 1, ...)>]"
87 " [--thickness <thickness>] [--z_aligned]"
96 #if defined(VISP_HAVE_PUGIXML)
98 if (!intrinsic_file.empty() && !camera_name.empty()) {
103 std::cout << cam << std::endl;
104 std::cout <<
"poseEstimationMethod: " << poseEstimationMethod << std::endl;
105 std::cout <<
"tagFamily: " << tagFamily << std::endl;
106 std::cout <<
"nThreads : " << nThreads << std::endl;
107 std::cout <<
"Z aligned: " << z_aligned << std::endl;
117 #elif defined(VISP_HAVE_GDI)
119 #elif defined(HAVE_OPENCV_HIGHGUI)
128 detector.setAprilTagQuadDecimate(quad_decimate);
129 detector.setAprilTagPoseEstimationMethod(poseEstimationMethod);
130 detector.setAprilTagNbThreads(nThreads);
132 detector.setZAlignedWithCameraAxis(z_aligned);
139 std::vector<vpHomogeneousMatrix> cMo_vec;
140 detector.detect(I, tagSize, cam, cMo_vec);
144 std::stringstream ss;
145 ss <<
"Detection time: " << t <<
" ms for " << detector.getNbObjects() <<
" tags";
149 for (
size_t i = 0; i < detector.getNbObjects(); i++) {
152 std::vector<vpImagePoint> p = detector.getPolygon(i);
153 vpRect bbox = detector.getBBox(i);
157 std::string message = detector.getMessage(i);
160 std::size_t tag_id_pos = message.find(
"id: ");
161 if (tag_id_pos != std::string::npos) {
162 int tag_id = atoi(message.substr(tag_id_pos + 4).c_str());
164 ss <<
"Tag id: " << tag_id;
168 for (
size_t j = 0; j < p.size(); j++) {
170 std::ostringstream number;
183 for (
size_t i = 0; i < cMo_vec.size(); i++) {
193 vpDisplayX d2(I_color, 50, 50);
194 #elif defined(VISP_HAVE_GDI)
196 #elif defined(HAVE_OPENCV_HIGHGUI)
203 std::vector<std::vector<vpImagePoint> > tagsCorners = detector.getTagsCorners();
204 tagsCorners.pop_back();
205 detector.displayTags(I_color, tagsCorners,
vpColor::none, 3);
208 detector.displayFrames(I_color, cMo_vec, cam, tagSize / 2,
vpColor::none, 3);
215 std::cerr <<
"Catch an exception: " << e.
getMessage() << std::endl;
Generic class defining intrinsic camera parameters.
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
@ perspectiveProjWithoutDistortion
Perspective projection without distortion model.
static vpColor getColor(const unsigned int &i)
static const vpColor none
static const vpColor blue
static const vpColor green
@ TAG_36h11
AprilTag 36h11 pattern (recommended)
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1, const vpImagePoint &offset=vpImagePoint(0, 0), const std::string &frameName="", const vpColor &textColor=vpColor::black, const vpImagePoint &textOffset=vpImagePoint(15, 15))
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emitted by ViSP classes.
const char * getMessage() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Defines a rectangle in the plane.
XML parser to load and save intrinsic camera parameters.
int parse(vpCameraParameters &cam, const std::string &filename, const std::string &camera_name, const vpCameraParameters::vpCameraParametersProjType &projModel, unsigned int image_width=0, unsigned int image_height=0, bool verbose=true)
VISP_EXPORT double measureTimeMs()