37#include <visp3/core/vpConfig.h>
39#if defined(VISP_HAVE_PUGIXML)
41#include <visp3/core/vpIoTools.h>
42#include <visp3/core/vpXmlParserCamera.h>
43#include <visp3/detection/vpDetectorAprilTag.h>
44#include <visp3/gui/vpDisplayFactory.h>
45#include <visp3/io/vpVideoReader.h>
47#if defined(ENABLE_VISP_NAMESPACE)
51void usage(
const char **argv,
int error)
53 std::cout <<
"Synopsis" << std::endl
55 <<
" [--tag-size <size>]"
56 <<
" [--tag-z-aligned]"
57 <<
" [--input <images filename>]"
58 <<
" [--intrinsic <xml file>]"
59 <<
" [--camera-name <name>]"
60 <<
" [--output <poses filename>]"
61#if defined(VISP_HAVE_MODULE_GUI)
62 <<
" [--no-interactive]"
64 <<
" [--help, -h]" << std::endl
66 std::cout <<
"Description" << std::endl
67 <<
" Compute the pose of a 36h11 Apriltag in a sequence of images." << std::endl
68 <<
" Consider that only one tag is present in each image." << std::endl
70 <<
" --tag-size <size>" << std::endl
71 <<
" Apriltag size in [m]." << std::endl
72 <<
" Default: 0.03" << std::endl
74 <<
" --tag-z-aligned" << std::endl
75 <<
" When enabled, tag z-axis and camera z-axis are aligned." << std::endl
76 <<
" Default: false" << std::endl
78 <<
" --input <images filename>" << std::endl
79 <<
" Generic name of the images to process." << std::endl
80 <<
" Default: empty" << std::endl
81 <<
" Example: \"image-%d.jpg\"" << std::endl
83 <<
" --intrinsic <xml file>" << std::endl
84 <<
" XML file that contains camera intrinsic parameters. " << std::endl
85 <<
" Default: \"camera.xml\"" << std::endl
87 <<
" --camera-name <name>" << std::endl
88 <<
" Camera name in the XML file that contains camera intrinsic parameters." << std::endl
89 <<
" Default: \"Camera\"" << std::endl
91 <<
" --output <poses filename>" << std::endl
92 <<
" Generic name of the yaml files that contains the resulting tag poses." << std::endl
93 <<
" Default: \"pose_cPo_%d.yaml\"" << std::endl
95#if defined(VISP_HAVE_MODULE_GUI)
96 <<
" --no-interactive" << std::endl
97 <<
" To compute the tag poses without interactive validation by the user." << std::endl
100 <<
" --help, -h" << std::endl
101 <<
" Print this helper message." << std::endl
104 std::cout <<
"Example" << std::endl
107 <<
" --input image-%d.jpg" << std::endl
111 std::cout <<
"Error" << std::endl
113 <<
"Unsupported parameter " << argv[
error] << std::endl;
117int main(
int argc,
const char **argv)
119 double opt_tag_size = 0.048;
120 std::string opt_input_img_files =
"";
121 std::string opt_intrinsic_file =
"camera.xml";
122 std::string opt_camera_name =
"Camera";
123 std::string opt_output_pose_files =
"pose_cPo_%d.yaml";
124 bool opt_interactive =
true;
129 float quad_decimate = 1.0;
131 bool display_tag =
true;
132 bool opt_tag_z_aligned =
false;
136 for (
int i = 1;
i < argc; ++
i) {
137 if (std::string(argv[i]) ==
"--tag-size" && i + 1 < argc) {
138 opt_tag_size = atof(argv[++i]);
140 else if (std::string(argv[i]) ==
"--tag-z-aligned") {
141 opt_tag_z_aligned =
true;
143 else if (std::string(argv[i]) ==
"--input" && i + 1 < argc) {
144 opt_input_img_files = std::string(argv[++i]);
146 else if (std::string(argv[i]) ==
"--intrinsic" && i + 1 < argc) {
147 opt_intrinsic_file = std::string(argv[++i]);
149 else if (std::string(argv[i]) ==
"--output" && i + 1 < argc) {
150 opt_output_pose_files = std::string(argv[++i]);
152 else if (std::string(argv[i]) ==
"--camera-name" && i + 1 < argc) {
153 opt_camera_name = std::string(argv[++i]);
155#if defined(VISP_HAVE_MODULE_GUI)
156 else if (std::string(argv[i]) ==
"--no-interactive") {
157 opt_interactive =
false;
160 else if (std::string(argv[i]) ==
"--help" || std::string(argv[i]) ==
"-h") {
171 std::cout <<
"Camera parameters file " << opt_intrinsic_file <<
" doesn't exist." << std::endl;
172 std::cout <<
"Use --help option to see how to set its location..." << std::endl;
176 if (opt_input_img_files.empty()) {
177 std::cout <<
"Input images location empty." << std::endl;
178 std::cout <<
"Use --help option to see how to set input image location..." << std::endl;
185 std::cout <<
"Create output directory: " << output_parent << std::endl;
197 std::cout <<
"Parameters:" << std::endl;
198 std::cout <<
" Apriltag " << std::endl;
199 std::cout <<
" Size [m] : " << opt_tag_size << std::endl;
200 std::cout <<
" Z aligned : " << (opt_tag_z_aligned ?
"true" :
"false") << std::endl;
201 std::cout <<
" Input images location : " << opt_input_img_files << std::endl;
204 std::cout <<
" Camera intrinsics " << std::endl;
205 std::cout <<
" Param file name [.xml]: " << opt_intrinsic_file << std::endl;
206 std::cout <<
" Camera name : " << opt_camera_name << std::endl;
207 std::cout <<
" Output camera poses : " << opt_output_pose_files << std::endl;
208 std::cout <<
" Interactive mode : " << (opt_interactive ?
"yes" :
"no") << std::endl << std::endl;
210#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
211 std::shared_ptr<vpDisplay> display;
216#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
222 detector.setAprilTagQuadDecimate(quad_decimate);
223 detector.setAprilTagPoseEstimationMethod(pose_estimation_method);
224 detector.setDisplayTag(display_tag,
vpColor::none, thickness);
225 detector.setZAlignedWithCameraAxis(opt_tag_z_aligned);
229 if (!opt_intrinsic_file.empty() && !opt_camera_name.empty()) {
232 std::cout <<
"Unable to parse parameters with distortion for camera \"" << opt_camera_name <<
"\" from "
233 << opt_intrinsic_file <<
" file" << std::endl;
234 std::cout <<
"Attempt to find parameters without distortion" << std::endl;
236 if (
parser.parse(cam, opt_intrinsic_file, opt_camera_name,
238 std::cout <<
"Unable to parse parameters without distortion for camera \"" << opt_camera_name <<
"\" from "
239 << opt_intrinsic_file <<
" file" << std::endl;
244 std::cout <<
"Camera parameters used to compute the pose:\n" <<
cam << std::endl;
249 std::cout <<
"Process image: " << reader.
getFrameName() << std::endl;
253#if defined(VISP_HAVE_MODULE_GUI)
257 std::vector<vpHomogeneousMatrix> cMo_vec;
258 detector.detect(I_gray, opt_tag_size, cam, cMo_vec);
260 bool found = (detector.getNbObjects() == 1) ? true :
false;
266 pose_vec.saveYAML(filename, pose_vec);
269#if defined(VISP_HAVE_MODULE_GUI)
270 if (opt_interactive) {
286 }
while (!quit && !reader.
end());
288#if defined(VISP_HAVE_MODULE_GUI)
289 if (opt_interactive) {
290#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
299 std::cout <<
"Catch an exception: " <<
e.getMessage() << std::endl;
307#if !defined(VISP_HAVE_PUGIXML)
308 std::cout <<
"pugixml built-in 3rdparty is requested to compute tag poses." << std::endl;
Generic class defining intrinsic camera parameters.
@ perspectiveProjWithDistortion
Perspective projection with distortion model.
@ perspectiveProjWithoutDistortion
Perspective projection without distortion model.
static const vpColor none
@ TAG_36h11
AprilTag 36h11 pattern (recommended).
Class that defines generic functionalities for display.
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 setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
static void flush(const vpImage< unsigned char > &I)
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.
Implementation of an homogeneous matrix and operations on such kind of matrices.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Definition of the vpImage class member functions.
Implementation of a pose vector and operations on poses.
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void open(vpImage< vpRGBa > &I) VP_OVERRIDE
void setFileName(const std::string &filename)
long getFirstFrameIndex()
std::string getFrameName() const
long getFrameIndex() const
void acquire(vpImage< vpRGBa > &I) VP_OVERRIDE
XML parser to load and save intrinsic camera parameters.
std::shared_ptr< vpDisplay > createDisplay()
Return a smart pointer vpDisplay specialization if a GUI library is available or nullptr otherwise.
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.