33 #include <visp3/core/vpConfig.h>
35 #ifdef VISP_HAVE_APRILTAG
42 #include <apriltag_pose.h>
43 #include <common/homography.h>
49 #include <tagCircle21h7.h>
50 #include <tagStandard41h12.h>
51 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
52 #include <tagCircle49h12.h>
53 #include <tagCustom48h12.h>
54 #include <tagStandard41h12.h>
55 #include <tagStandard52h13.h>
61 #include <visp3/core/vpDisplay.h>
62 #include <visp3/core/vpPixelMeterConversion.h>
63 #include <visp3/core/vpPoint.h>
64 #include <visp3/detection/vpDetectorAprilTag.h>
65 #include <visp3/vision/vpPose.h>
69 #ifndef DOXYGEN_SHOULD_SKIP_THIS
70 class vpDetectorAprilTag::Impl
75 m_zAlignedWithCameraFrame(false)
79 m_tf = tag36h11_create();
83 m_tf = tag36h10_create();
90 m_tf = tag25h9_create();
94 m_tf = tag25h7_create();
98 m_tf = tag16h5_create();
102 m_tf = tagCircle21h7_create();
106 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
107 m_tf = tagCircle49h12_create();
112 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
113 m_tf = tagCustom48h12_create();
118 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
119 m_tf = tagStandard52h13_create();
124 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
125 m_tf = tagStandard41h12_create();
134 m_td = apriltag_detector_create();
135 apriltag_detector_add_family(m_td, m_tf);
144 m_tf(nullptr), m_detections(nullptr), m_zAlignedWithCameraFrame(o.m_zAlignedWithCameraFrame)
148 m_tf = tag36h11_create();
152 m_tf = tag36h10_create();
159 m_tf = tag25h9_create();
163 m_tf = tag25h7_create();
167 m_tf = tag16h5_create();
171 m_tf = tagCircle21h7_create();
175 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
176 m_tf = tagCircle49h12_create();
181 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
182 m_tf = tagCustom48h12_create();
187 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
188 m_tf = tagStandard52h13_create();
193 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
194 m_tf = tagStandard41h12_create();
203 m_td = apriltag_detector_copy(o.m_td);
204 apriltag_detector_add_family(m_td, m_tf);
210 if (o.m_detections !=
nullptr) {
211 m_detections = apriltag_detections_copy(o.m_detections);
218 apriltag_detector_destroy(m_td);
224 tag36h11_destroy(m_tf);
228 tag36h10_destroy(m_tf);
235 tag25h9_destroy(m_tf);
239 tag25h7_destroy(m_tf);
243 tag16h5_destroy(m_tf);
247 tagCircle21h7_destroy(m_tf);
251 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
252 tagCustom48h12_destroy(m_tf);
257 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
258 tagCustom48h12_destroy(m_tf);
263 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
264 tagStandard52h13_destroy(m_tf);
269 #if defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
270 tagStandard41h12_destroy(m_tf);
280 apriltag_detections_destroy(m_detections);
281 m_detections =
nullptr;
287 const unsigned int val_3 = 3;
288 for (
unsigned int i = 0; i < val_3; ++i) {
289 for (
unsigned int j = 0; j < val_3; ++j) {
290 cMo[i][j] = MATD_EL(pose.R, i, j);
292 cMo[i][val_3] = MATD_EL(pose.t, i, 0);
297 std::vector<std::vector<vpImagePoint> > &polygons, std::vector<std::string> &messages,
bool displayTag,
298 const vpColor color,
unsigned int thickness, std::vector<vpHomogeneousMatrix> *cMo_vec,
299 std::vector<vpHomogeneousMatrix> *cMo_vec2, std::vector<double> *projErrors,
300 std::vector<double> *projErrors2)
304 std::cerr <<
"TAG_36ARTOOLKIT detector is not available anymore." << std::endl;
307 #if !defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
310 std::cerr <<
"TAG_CIRCLE49h12, TAG_CUSTOM48h12, TAG_STANDARD41h12 and TAG_STANDARD52h13 are disabled."
316 const bool computePose = (cMo_vec !=
nullptr);
318 image_u8_t im = {
static_cast<int32_t
>(I.
getWidth()),
324 apriltag_detections_destroy(m_detections);
325 m_detections =
nullptr;
328 m_detections = apriltag_detector_detect(m_td, &im);
329 int nb_detections = zarray_size(m_detections);
330 bool detected = nb_detections > 0;
332 polygons.resize(
static_cast<size_t>(nb_detections));
333 messages.resize(
static_cast<size_t>(nb_detections));
334 m_tagsId.resize(
static_cast<size_t>(nb_detections));
336 int zarray_size_m_detections = zarray_size(m_detections);
337 for (
int i = 0; i < zarray_size_m_detections; ++i) {
338 apriltag_detection_t *det;
339 zarray_get(m_detections, i, &det);
341 std::vector<vpImagePoint> polygon;
342 const int polygonSize = 4;
343 for (
int j = 0; j < polygonSize; ++j) {
344 polygon.push_back(
vpImagePoint(det->p[j][1], det->p[j][0]));
346 polygons[
static_cast<size_t>(i)] = polygon;
347 std::stringstream ss;
349 messages[
static_cast<size_t>(i)] = ss.str();
350 m_tagsId[
static_cast<size_t>(i)] = det->id;
358 const unsigned int polyId0 = 0, polyId1 = 1, polyId2 = 2, polyId3 = 3;
359 vpDisplay::displayLine(I,
static_cast<int>(det->p[polyId0][1]),
static_cast<int>(det->p[polyId0][0]),
static_cast<int>(det->p[polyId1][1]),
static_cast<int>(det->p[polyId1][0]), Ox,
361 vpDisplay::displayLine(I,
static_cast<int>(det->p[polyId0][1]),
static_cast<int>(det->p[polyId0][0]),
static_cast<int>(det->p[polyId3][1]),
static_cast<int>(det->p[polyId3][0]), Oy,
363 vpDisplay::displayLine(I,
static_cast<int>(det->p[polyId1][1]),
static_cast<int>(det->p[polyId1][0]),
static_cast<int>(det->p[polyId2][1]),
static_cast<int>(det->p[polyId2][0]), Ox2,
365 vpDisplay::displayLine(I,
static_cast<int>(det->p[polyId2][1]),
static_cast<int>(det->p[polyId2][0]),
static_cast<int>(det->p[polyId3][1]),
static_cast<int>(det->p[polyId3][0]), Oy2,
372 if (
getPose(
static_cast<size_t>(i), tagSize, cam, cMo, cMo_vec2 ? &cMo2 :
nullptr, projErrors ? &err1 :
nullptr,
373 projErrors2 ? &err2 :
nullptr)) {
374 cMo_vec->push_back(cMo);
376 cMo_vec2->push_back(cMo2);
379 projErrors->push_back(err1);
382 projErrors2->push_back(err2);
395 size_t cmo_vec_size = cMo_vec.size();
396 for (
size_t i = 0; i < cmo_vec_size; ++i) {
405 size_t cmo_vec_size = cMo_vec.size();
406 for (
size_t i = 0; i < cmo_vec_size; ++i) {
413 const vpColor &color,
unsigned int thickness)
const
415 size_t tagscorners_size = tagsCorners.size();
416 for (
size_t i = 0; i < tagscorners_size; ++i) {
422 const std::vector<vpImagePoint> &corners = tagsCorners[i];
423 assert(corners.size() == 4);
424 const unsigned int cornerId0 = 0, cornerId1 = 1, cornerId2 = 2, cornerId3 = 3;
426 vpDisplay::displayLine(I,
static_cast<int>(corners[cornerId0].get_i()),
static_cast<int>(corners[cornerId0].get_j()),
static_cast<int>(corners[cornerId1].get_i()),
static_cast<int>(corners[cornerId1].get_j()),
428 vpDisplay::displayLine(I,
static_cast<int>(corners[cornerId0].get_i()),
static_cast<int>(corners[cornerId0].get_j()),
static_cast<int>(corners[cornerId3].get_i()),
static_cast<int>(corners[cornerId3].get_j()),
430 vpDisplay::displayLine(I,
static_cast<int>(corners[cornerId1].get_i()),
static_cast<int>(corners[cornerId1].get_j()),
static_cast<int>(corners[cornerId2].get_i()),
static_cast<int>(corners[cornerId2].get_j()),
432 vpDisplay::displayLine(I,
static_cast<int>(corners[cornerId2].get_i()),
static_cast<int>(corners[cornerId2].get_j()),
static_cast<int>(corners[cornerId3].get_i()),
static_cast<int>(corners[cornerId3].get_j()),
438 const vpColor &color,
unsigned int thickness)
const
440 size_t tagscorners_size = tagsCorners.size();
441 for (
size_t i = 0; i < tagscorners_size; ++i) {
447 const std::vector<vpImagePoint> &corners = tagsCorners[i];
448 assert(corners.size() == 4);
449 const unsigned int cornerId0 = 0, cornerId1 = 1, cornerId2 = 2, cornerId3 = 3;
451 vpDisplay::displayLine(I,
static_cast<int>(corners[cornerId0].get_i()),
static_cast<int>(corners[cornerId0].get_j()),
static_cast<int>(corners[cornerId1].get_i()),
static_cast<int>(corners[cornerId1].get_j()),
453 vpDisplay::displayLine(I,
static_cast<int>(corners[cornerId0].get_i()),
static_cast<int>(corners[cornerId0].get_j()),
static_cast<int>(corners[cornerId3].get_i()),
static_cast<int>(corners[cornerId3].get_j()),
455 vpDisplay::displayLine(I,
static_cast<int>(corners[cornerId1].get_i()),
static_cast<int>(corners[cornerId1].get_j()),
static_cast<int>(corners[cornerId2].get_i()),
static_cast<int>(corners[cornerId2].get_j()),
457 vpDisplay::displayLine(I,
static_cast<int>(corners[cornerId2].get_i()),
static_cast<int>(corners[cornerId2].get_j()),
static_cast<int>(corners[cornerId3].get_i()),
static_cast<int>(corners[cornerId3].get_j()),
465 if (m_detections ==
nullptr) {
470 std::cerr <<
"TAG_36ARTOOLKIT detector is not available anymore." << std::endl;
473 #if !defined(VISP_HAVE_APRILTAG_BIG_FAMILY)
476 std::cerr <<
"TAG_CIRCLE49h12, TAG_CUSTOM48h12, TAG_STANDARD41h12 and TAG_STANDARD52h13 are disabled."
482 apriltag_detection_t *det;
483 zarray_get(m_detections,
static_cast<int>(tagIndex), &det);
485 int nb_detections = zarray_size(m_detections);
486 if (tagIndex >=
static_cast<size_t>(nb_detections)) {
502 apriltag_detection_info_t info;
504 info.tagsize = tagSize;
511 getPoseWithOrthogonalMethod(info, cMo, cMo2, projErrors, projErrors2);
512 cMo_homography_ortho_iter = cMo;
521 apriltag_detection_info_t info;
523 info.tagsize = tagSize;
529 apriltag_pose_t pose;
530 estimate_pose_for_tag_homography(&info, &pose);
531 convertHomogeneousMatrix(pose, cMo);
533 matd_destroy(pose.R);
534 matd_destroy(pose.t);
536 cMo_homography = cMo;
544 double x = 0.0, y = 0.0;
545 std::vector<vpPoint> pts(4);
547 imPt.
set_uv(det->p[0][0], det->p[0][1]);
554 imPt.
set_uv(det->p[1][0], det->p[1][1]);
560 const int idCorner2 = 2;
562 imPt.
set_uv(det->p[idCorner2][0], det->p[idCorner2][1]);
568 const int idCorner3 = 3;
570 imPt.
set_uv(det->p[idCorner3][0], det->p[idCorner3][1]);
583 double residual_dementhon = std::numeric_limits<double>::max(),
584 residual_lagrange = std::numeric_limits<double>::max();
586 double residual_homography_ortho_iter = pose.
computeResidual(cMo_homography_ortho_iter);
596 std::vector<double> residuals;
597 residuals.push_back(residual_dementhon);
598 residuals.push_back(residual_lagrange);
599 residuals.push_back(residual_homography);
600 residuals.push_back(residual_homography_ortho_iter);
601 std::vector<vpHomogeneousMatrix> poses;
602 poses.push_back(cMo_dementhon);
603 poses.push_back(cMo_lagrange);
604 poses.push_back(cMo_homography);
605 poses.push_back(cMo_homography_ortho_iter);
607 std::ptrdiff_t minIndex = std::min_element(residuals.begin(), residuals.end()) - residuals.begin();
608 cMo = *(poses.begin() + minIndex);
623 double scale = tagSize / 2.0;
624 double data_p0[] = { -scale, scale, 0 };
625 double data_p1[] = { scale, scale, 0 };
626 double data_p2[] = { scale, -scale, 0 };
627 double data_p3[] = { -scale, -scale, 0 };
628 const unsigned int nbPoints = 4;
629 const int nbRows = 3;
630 matd_t *p[nbPoints] = { matd_create_data(nbRows, 1, data_p0), matd_create_data(nbRows, 1, data_p1),
631 matd_create_data(nbRows, 1, data_p2), matd_create_data(nbRows, 1, data_p3) };
633 for (
unsigned int i = 0; i < nbPoints; ++i) {
636 v[i] = matd_create_data(nbRows, 1, data_v);
639 apriltag_pose_t solution1, solution2;
640 const int nIters = 50;
641 const int nbCols = 3;
646 get_second_solution(v, p, &solution1, &solution2, nIters, &err2);
648 for (
unsigned int i = 0; i < nbPoints; ++i) {
654 convertHomogeneousMatrix(solution2, *cMo2);
656 matd_destroy(solution2.R);
657 matd_destroy(solution2.t);
660 matd_destroy(solution1.R);
661 matd_destroy(solution1.t);
669 if (projErrors2 && cMo2) {
673 if (!m_zAlignedWithCameraFrame) {
674 const unsigned int idX = 0, idY = 1, idZ = 2;
695 void getPoseWithOrthogonalMethod(apriltag_detection_info_t &info,
vpHomogeneousMatrix &cMo1,
698 apriltag_pose_t pose1, pose2;
700 const unsigned int nbIters = 50;
701 estimate_tag_pose_orthogonal_iteration(&info, &err_1, &pose1, &err_2, &pose2, nbIters);
702 if (err_1 <= err_2) {
703 convertHomogeneousMatrix(pose1, cMo1);
706 convertHomogeneousMatrix(pose2, *cMo2);
714 convertHomogeneousMatrix(pose2, cMo1);
716 convertHomogeneousMatrix(pose1, *cMo2);
720 matd_destroy(pose1.R);
721 matd_destroy(pose1.t);
723 matd_destroy(pose2.t);
725 matd_destroy(pose2.R);
735 bool getZAlignedWithCameraAxis() {
return m_zAlignedWithCameraFrame; }
737 bool getAprilTagDecodeSharpening(
double &decodeSharpening)
const
740 decodeSharpening = m_td->decode_sharpening;
746 bool getNbThreads(
int &nThreads)
const
749 nThreads = m_td->nthreads;
755 bool getQuadDecimate(
float &quadDecimate)
const
758 quadDecimate = m_td->quad_decimate;
764 bool getQuadSigma(
float &quadSigma)
const
767 quadSigma = m_td->quad_sigma;
773 bool getRefineEdges(
bool &refineEdges)
const
776 refineEdges = (m_td->refine_edges ? true :
false);
782 bool getZAlignedWithCameraAxis()
const {
return m_zAlignedWithCameraFrame; }
784 std::vector<int>
getTagsId()
const {
return m_tagsId; }
789 m_td->decode_sharpening = decodeSharpening;
793 void setNbThreads(
int nThreads)
796 m_td->nthreads = nThreads;
800 void setQuadDecimate(
float quadDecimate)
803 m_td->quad_decimate = quadDecimate;
807 void setQuadSigma(
float quadSigma)
810 m_td->quad_sigma = quadSigma;
814 void setRefineDecode(
bool) { }
816 void setRefineEdges(
bool refineEdges)
819 m_td->refine_edges = (refineEdges ? true :
false);
823 void setRefinePose(
bool) { }
832 m_zAlignedWithCameraFrame = zAlignedWithCameraFrame;
837 return m_zAlignedWithCameraFrame;
841 std::map<vpPoseEstimationMethod, vpPose::vpPoseMethodType> m_mapOfCorrespondingPoseMethods;
843 std::vector<int> m_tagsId;
845 apriltag_detector_t *m_td;
846 apriltag_family_t *m_tf;
847 zarray_t *m_detections;
848 bool m_zAlignedWithCameraFrame;
853 const unsigned int def_tagThickness = 2;
859 : m_displayTag(false), m_displayTagColor(
vpColor::none), m_displayTagThickness(def_tagThickness),
860 m_poseEstimationMethod(poseEstimationMethod), m_tagFamily(tagFamily), m_defaultCam(),
861 m_impl(new Impl(tagFamily, poseEstimationMethod))
865 :
vpDetectorBase(o), m_displayTag(false), m_displayTagColor(
vpColor::none), m_displayTagThickness(def_tagThickness),
866 m_poseEstimationMethod(o.m_poseEstimationMethod), m_tagFamily(o.m_tagFamily), m_defaultCam(),
867 m_impl(new Impl(*o.m_impl))
891 std::vector<vpHomogeneousMatrix> cMo_vec;
892 const double tagSize = 1.0;
918 std::vector<vpHomogeneousMatrix> &cMo_vec, std::vector<vpHomogeneousMatrix> *cMo_vec2,
919 std::vector<double> *projErrors, std::vector<double> *projErrors2)
949 m_impl->displayFrames(I, cMo_vec, cam, size, color, thickness);
965 m_impl->displayFrames(I, cMo_vec, cam, size, color, thickness);
977 const vpColor &color,
unsigned int thickness)
const
979 m_impl->displayTags(I, tagsCorners, color, thickness);
991 const vpColor &color,
unsigned int thickness)
const
993 m_impl->displayTags(I, tagsCorners, color, thickness);
1031 return m_impl->getPose(tagIndex, tagSize, cam, cMo, cMo2, projError, projError2);
1052 const std::map<int, double> &tagsSize)
const
1054 std::vector<std::vector<vpPoint> > tagsPoints3D;
1056 double default_size = -1;
1058 std::map<int, double>::const_iterator it = tagsSize.find(-1);
1059 if (it != tagsSize.end()) {
1060 default_size = it->second;
1063 size_t tagsid_size = tagsId.size();
1064 for (
size_t i = 0; i < tagsid_size; ++i) {
1065 it = tagsSize.find(tagsId[i]);
1066 double tagSize = default_size;
1067 if (it == tagsSize.end()) {
1068 if (default_size < 0) {
1070 "Tag with id %d has no 3D size or there is no default 3D size defined", tagsId[i]));
1074 tagSize = it->second;
1076 std::vector<vpPoint> points3D(4);
1077 const unsigned int idX = 0, idY = 1, idZ = 2, idHomogen = 3;
1078 const double middleFactor = 2.0;
1079 if (m_impl->getZAlignedWithCameraAxis()) {
1080 points3D[idX] =
vpPoint(-tagSize / middleFactor, tagSize / middleFactor, 0);
1081 points3D[idY] =
vpPoint(tagSize / middleFactor, tagSize / middleFactor, 0);
1082 points3D[idZ] =
vpPoint(tagSize / middleFactor, -tagSize / middleFactor, 0);
1083 points3D[idHomogen] =
vpPoint(-tagSize / middleFactor, -tagSize / middleFactor, 0);
1086 points3D[idX] =
vpPoint(-tagSize / middleFactor, -tagSize / middleFactor, 0);
1087 points3D[idY] =
vpPoint(tagSize / middleFactor, -tagSize / middleFactor, 0);
1088 points3D[idZ] =
vpPoint(tagSize / middleFactor, tagSize / middleFactor, 0);
1089 points3D[idHomogen] =
vpPoint(-tagSize / middleFactor, tagSize / middleFactor, 0);
1091 tagsPoints3D.push_back(points3D);
1094 return tagsPoints3D;
1113 return m_impl->setAprilTagDecodeSharpening(decodeSharpening);
1119 double decodeSharpening = 0.25;
1120 m_impl->getAprilTagDecodeSharpening(decodeSharpening);
1122 m_impl->getNbThreads(nThreads);
1123 float quadDecimate = 1;
1124 m_impl->getQuadDecimate(quadDecimate);
1125 float quadSigma = 0;
1126 m_impl->getQuadSigma(quadSigma);
1127 bool refineEdges =
true;
1128 m_impl->getRefineEdges(refineEdges);
1129 bool zAxis = m_impl->getZAlignedWithCameraAxis();
1133 m_impl->setAprilTagDecodeSharpening(decodeSharpening);
1134 m_impl->setNbThreads(nThreads);
1135 m_impl->setQuadDecimate(quadDecimate);
1136 m_impl->setQuadSigma(quadSigma);
1137 m_impl->setRefineEdges(refineEdges);
1138 m_impl->setZAlignedWithCameraAxis(zAxis);
1149 m_impl->setNbThreads(nThreads);
1161 m_impl->setPoseEstimationMethod(poseEstimationMethod);
1192 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1196 void vpDetectorAprilTag::setAprilTagRefineDecode(
bool refineDecode)
1198 m_impl->setRefineDecode(refineDecode);
1218 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1222 void vpDetectorAprilTag::setAprilTagRefinePose(
bool refinePose) { m_impl->setRefinePose(refinePose); }
1236 m_impl->setZAlignedWithCameraAxis(zAlignedWithCameraFrame);
1245 return m_impl->isZAlignedWithCameraAxis();
1248 #elif !defined(VISP_BUILD_SHARED_LIBS)
1251 void dummy_vpDetectorAprilTag() { }
Type * data
Address of the first element of the data array.
Generic class defining intrinsic camera parameters.
Class to define RGB colors available for display functionalities.
static const vpColor none
static const vpColor blue
static const vpColor yellow
static const vpColor green
@ BEST_RESIDUAL_VIRTUAL_VS
@ HOMOGRAPHY_ORTHOGONAL_ITERATION
void setZAlignedWithCameraAxis(bool zAlignedWithCameraFrame)
std::vector< std::vector< vpImagePoint > > getTagsCorners() const
void setAprilTagQuadDecimate(float quadDecimate)
friend void swap(vpDetectorAprilTag &o1, vpDetectorAprilTag &o2)
void displayFrames(const vpImage< unsigned char > &I, const std::vector< vpHomogeneousMatrix > &cMo_vec, const vpCameraParameters &cam, double size, const vpColor &color, unsigned int thickness=1) const
vpDetectorAprilTag & operator=(vpDetectorAprilTag o)
std::vector< std::vector< vpPoint > > getTagsPoints3D(const std::vector< int > &tagsId, const std::map< int, double > &tagsSize) const
vpDetectorAprilTag(const vpAprilTagFamily &tagFamily=TAG_36h11, const vpPoseEstimationMethod &poseEstimationMethod=HOMOGRAPHY_VIRTUAL_VS)
bool detect(const vpImage< unsigned char > &I) VP_OVERRIDE
unsigned int m_displayTagThickness
vpAprilTagFamily m_tagFamily
void setAprilTagRefineEdges(bool refineEdges)
bool isZAlignedWithCameraAxis() const
vpPoseEstimationMethod m_poseEstimationMethod
@ TAG_CIRCLE21h7
AprilTag Circle21h7 pattern.
@ TAG_25h7
DEPRECATED AND POOR DETECTION PERFORMANCE.
@ TAG_36ARTOOLKIT
DEPRECATED AND WILL NOT DETECT ARTOOLKIT TAGS.
@ TAG_25h9
AprilTag 25h9 pattern.
@ TAG_CUSTOM48h12
AprilTag Custom48h12 pattern.
@ TAG_36h11
AprilTag 36h11 pattern (recommended)
@ TAG_STANDARD52h13
AprilTag Standard52h13 pattern.
@ TAG_16h5
AprilTag 16h5 pattern.
@ TAG_STANDARD41h12
AprilTag Standard41h12 pattern.
@ TAG_CIRCLE49h12
AprilTag Circle49h12 pattern.
void setAprilTagQuadSigma(float quadSigma)
void setAprilTagNbThreads(int nThreads)
void setAprilTagPoseEstimationMethod(const vpPoseEstimationMethod &poseEstimationMethod)
std::vector< int > getTagsId() const
bool getPose(size_t tagIndex, double tagSize, const vpCameraParameters &cam, vpHomogeneousMatrix &cMo, vpHomogeneousMatrix *cMo2=nullptr, double *projError=nullptr, double *projError2=nullptr)
void displayTags(const vpImage< unsigned char > &I, const std::vector< std::vector< vpImagePoint > > &tagsCorners, const vpColor &color=vpColor::none, unsigned int thickness=1) const
void setAprilTagFamily(const vpAprilTagFamily &tagFamily)
virtual ~vpDetectorAprilTag() VP_OVERRIDE
vpColor m_displayTagColor
void setAprilTagDecodeSharpening(double decodeSharpening)
std::vector< std::string > m_message
Message attached to each object.
std::vector< std::vector< vpImagePoint > > m_polygon
For each object, defines the polygon that contains the object.
size_t m_nb_objects
Number of detected objects.
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
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))
error that can be emitted by ViSP classes.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpRotationMatrix getRotationMatrix() const
vpTranslationVector getTranslationVector() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void set_uv(double u, double v)
unsigned int getWidth() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
void set_x(double x)
Set the point x coordinate in the image plane.
void setWorldCoordinates(double oX, double oY, double oZ)
void set_y(double y)
Set the point y coordinate in the image plane.
Class used for pose computation from N points (pose from point only). Some of the algorithms implemen...
bool computePose(vpPoseMethodType method, vpHomogeneousMatrix &cMo, FuncCheckValidityPose func=nullptr)
void addPoints(const std::vector< vpPoint > &lP)
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the sum of squared residuals expressed in meter^2 for the pose matrix cMo.