35 #include <visp3/core/vpConfig.h> 37 #ifdef VISP_HAVE_APRILTAG 41 #include <common/homography.h> 45 #include <tag36artoolkit.h> 49 #include <visp3/core/vpDisplay.h> 50 #include <visp3/core/vpPixelMeterConversion.h> 51 #include <visp3/core/vpPoint.h> 52 #include <visp3/detection/vpDetectorAprilTag.h> 53 #include <visp3/vision/vpPose.h> 55 #ifndef DOXYGEN_SHOULD_SKIP_THIS 56 class vpDetectorAprilTag::Impl
65 m_tf = tag36h11_create();
69 m_tf = tag36h10_create();
73 m_tf = tag36artoolkit_create();
77 m_tf = tag25h9_create();
81 m_tf = tag25h7_create();
85 m_tf = tag16h5_create();
93 m_td = apriltag_detector_create();
94 apriltag_detector_add_family(m_td, m_tf);
102 apriltag_detector_destroy(m_td);
106 tag36h11_destroy(m_tf);
110 tag36h10_destroy(m_tf);
114 tag36artoolkit_destroy(m_tf);
118 tag25h9_destroy(m_tf);
122 tag25h7_destroy(m_tf);
126 tag16h5_destroy(m_tf);
135 std::vector<std::string> &messages,
const bool computePose,
const bool displayTag)
139 image_u8_t im = {(int32_t)I.
getWidth(),
144 zarray_t *detections = apriltag_detector_detect(m_td, &im);
145 int nb_detections = zarray_size(detections);
146 bool detected = nb_detections > 0;
148 polygons.resize((
size_t)nb_detections);
149 messages.resize((
size_t)nb_detections);
151 for (
int i = 0; i < zarray_size(detections); i++) {
152 apriltag_detection_t *det;
153 zarray_get(detections, i, &det);
155 std::vector<vpImagePoint> polygon;
156 for (
int j = 0; j < 4; j++) {
157 polygon.push_back(
vpImagePoint(det->p[j][1], det->p[j][0]));
159 polygons[i] = polygon;
160 std::stringstream ss;
162 messages[i] = ss.str();
178 double fx = m_cam.get_px(), fy = m_cam.get_py();
179 double cx = m_cam.get_u0(), cy = m_cam.get_v0();
181 matd_t *M = homography_to_pose(det->H, fx, fy, cx, cy, m_tagSize / 2);
183 for (
int i = 0; i < 3; i++) {
184 for (
int j = 0; j < 3; j++) {
185 cMo[i][j] = MATD_EL(M, i, j);
187 cMo[i][3] = MATD_EL(M, i, 3);
196 double x = 0.0, y = 0.0;
197 std::vector<vpPoint> pts(4);
199 imPt.
set_uv(det->p[0][0], det->p[0][1]);
206 imPt.
set_uv(det->p[1][0], det->p[1][1]);
213 imPt.
set_uv(det->p[2][0], det->p[2][1]);
220 imPt.
set_uv(det->p[3][0], det->p[3][1]);
233 double residual_dementhon = std::numeric_limits<double>::max(),
234 residual_lagrange = std::numeric_limits<double>::max();
245 if (residual_dementhon < residual_lagrange) {
246 if (residual_dementhon < residual_homography) {
249 cMo = cMo_homography;
251 }
else if (residual_lagrange < residual_homography) {
263 m_tagPoses.push_back(cMo);
267 apriltag_detections_destroy(detections);
272 void getTagPoses(std::vector<vpHomogeneousMatrix> &tagPoses)
const { tagPoses = m_tagPoses; }
276 void setNbThreads(
const int nThreads) { m_td->nthreads = nThreads; }
278 void setQuadDecimate(
const float quadDecimate) { m_td->quad_decimate = quadDecimate; }
280 void setQuadSigma(
const float quadSigma) { m_td->quad_sigma = quadSigma; }
282 void setRefineDecode(
const bool refineDecode) { m_td->refine_decode = refineDecode ? 1 : 0; }
284 void setRefineEdges(
const bool refineEdges) { m_td->refine_edges = refineEdges ? 1 : 0; }
286 void setRefinePose(
const bool refinePose) { m_td->refine_pose = refinePose ? 1 : 0; }
288 void setTagSize(
const double tagSize) { m_tagSize = tagSize; }
294 std::map<vpPoseEstimationMethod, vpPose::vpPoseMethodType> m_mapOfCorrespondingPoseMethods;
297 std::vector<vpHomogeneousMatrix> m_tagPoses;
299 apriltag_detector_t *m_td;
300 apriltag_family_t *m_tf;
302 #endif // DOXYGEN_SHOULD_SKIP_THIS 310 m_impl(new Impl(tagFamily, poseEstimationMethod))
347 std::vector<vpHomogeneousMatrix> &cMo_vec)
353 m_impl->setTagSize(tagSize);
354 m_impl->setCameraParameters(cam);
357 m_impl->getTagPoses(cMo_vec);
370 m_impl->setNbThreads(nThreads);
381 m_impl->setPoseEstimationMethod(poseEstimationMethod);
459 #elif !defined(VISP_BUILD_SHARED_LIBS) 462 void dummy_vpDetectorAprilTag() {}
void setAprilTagQuadDecimate(const float quadDecimate)
void setAprilTagRefineEdges(const bool refineEdges)
void setAprilTagPoseEstimationMethod(const vpPoseEstimationMethod &poseEstimationMethod)
Implementation of an homogeneous matrix and operations on such kind of matrices.
Type * bitmap
points toward the bitmap
void addPoints(const std::vector< vpPoint > &lP)
error that can be emited by ViSP classes.
void set_x(const double x)
Set the point x coordinate in the image plane.
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Point coordinates conversion from pixel coordinates to normalized coordinates in meter...
static const vpColor green
Class that defines what is a point.
size_t m_nb_objects
Number of detected objects.
Class used for pose computation from N points (pose from point only). Some of the algorithms implemen...
Generic class defining intrinsic camera parameters.
void set_y(const double y)
Set the point y coordinate in the image plane.
bool computePose(vpPoseMethodType method, vpHomogeneousMatrix &cMo, bool(*func)(vpHomogeneousMatrix *)=NULL)
vpPoseEstimationMethod m_poseEstimationMethod
void setWorldCoordinates(const double oX, const double oY, const double oZ)
unsigned int getHeight() const
void setAprilTagRefineDecode(const bool refineDecode)
std::vector< std::vector< vpImagePoint > > m_polygon
vpDetectorAprilTag(const vpAprilTagFamily &tagFamily=TAG_36h11, const vpPoseEstimationMethod &poseEstimationMethod=HOMOGRAPHY_VIRTUAL_VS)
void set_uv(const double u, const double v)
void setAprilTagQuadSigma(const float quadSigma)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the residual expressed in meter for the pose matrix 'cMo'.
static const vpColor yellow
unsigned int getWidth() const
std::vector< std::string > m_message
Message attached to each object.
vpAprilTagFamily m_tagFamily
void setAprilTagRefinePose(const bool refinePose)
virtual ~vpDetectorAprilTag()
void setAprilTagNbThreads(const int nThreads)
static const vpColor blue
bool detect(const vpImage< unsigned char > &I)