32 #include <opencv2/highgui/highgui.hpp>    33 #include <opencv2/imgproc/imgproc.hpp>    36 using namespace aruco;
    53 class CmdLineParser{
int argc; 
char **argv; 
public: 
CmdLineParser(
int _argc,
char **_argv):argc(_argc),argv(_argv){}  
bool operator[] ( 
string param ) {
int idx=-1;  
for ( 
int i=0; i<argc && idx==-1; i++ ) 
if ( 
string ( argv[i] ) ==param ) idx=i;    
return ( idx!=-1 ) ;    } 
string operator()(
string param,
string defvalue=
"-1"){
int idx=-1;    
for ( 
int i=0; i<argc && idx==-1; i++ ) 
if ( 
string ( argv[i] ) ==param ) idx=i; 
if ( idx==-1 ) 
return defvalue;   
else  return ( argv[  idx+1] ); }};
    85 int main(
int argc, 
char **argv) {
    88         if (argc < 3|| cml[
"-h"]) {
    89             cerr << 
"Invalid number of arguments" << endl;
    90             cerr << 
"Usage: (in.avi|live) marksetconfig.yml  [optional_arguments] \n\t[-c camera_intrinsics.yml] \n\t[-s marker_size] \n\t[-pcd out_pcd_file_with_camera_poses] \n\t[-poses out_file_with_poses] \n\t[-corner <corner_refinement_method> (0: LINES(default),1 SUBPIX) ][-h]" << endl;
    98         if (
string(argv[1])== 
"live") {
   102         if (!
TheVideoCapturer.isOpened())  
throw std::runtime_error(
"Could not open video");
   110             TheCameraParameters.
resize(TheInputImage.size());
   114         if(dict.empty()) dict=
"ARUCO";
   116         if (stoi(cml(
"-corner",
"0"))==0)
   121             params.
_subpix_wsize= (15./2000.)*float(TheInputImage.cols) ;
   132             TheMSPoseTracker.
setParams(TheCameraParameters,TheMarkerMapConfig);
   137         cv::namedWindow(
"thres", 1);
   138         cv::namedWindow(
"in", 1);
   148         cout<<
"Press 's' to start/stop video"<<endl;
   154             vector<aruco::Marker> detected_markers=TheMarkerDetector.
detect(TheInputImage);
   156              for(
auto idx:TheMarkerMapConfig.
getIndices(detected_markers))
   159              if (TheMSPoseTracker.
isValid()){
   163                      cout<<
"pose rt="<<TheMSPoseTracker.
getRvec()<<
" "<<TheMSPoseTracker.
getTvec()<<endl;
   188     } 
catch (std::exception &ex)
   191         cout << 
"Exception :" << ex.what() << endl;
   221      for(
auto idx:TheMarkerMapConfig.
getIndices(detected_markers))
   224      if (TheMSPoseTracker.
isValid()){
   234 inline float SIGN(
float x) {
return (x >= 0.0
f) ? +1.0f : -1.0f;}
   235 inline float NORM(
float a, 
float b, 
float c, 
float d) {
return sqrt(a * a + b * b + c * c + d * d);}
   240     assert(M_in.total()==16);
   241     cv::Mat M;M_in.convertTo(M,CV_32F);
   243     float r11=M.at<
float>(0,0);
   244     float r12=M.at<
float>(0,1);
   245     float r13=M.at<
float>(0,2);
   246     float r21=M.at<
float>(1,0);
   247     float r22=M.at<
float>(1,1);
   248     float r23=M.at<
float>(1,2);
   249     float r31=M.at<
float>(2,0);
   250     float r32=M.at<
float>(2,1);
   251     float r33=M.at<
float>(2,2);
   255     double  q0 = ( r11 + r22 + r33 + 1.0f) / 4.0
f;
   256     double  q1 = ( r11 - r22 - r33 + 1.0f) / 4.0
f;
   257     double     q2 = (-r11 + r22 - r33 + 1.0f) / 4.0
f;
   258     double     q3 = (-r11 - r22 + r33 + 1.0f) / 4.0
f;
   259     if(q0 < 0.0
f) q0 = 0.0f;
   260     if(q1 < 0.0
f) q1 = 0.0f;
   261     if(q2 < 0.0
f) q2 = 0.0f;
   262     if(q3 < 0.0
f) q3 = 0.0f;
   267     if(q0 >= q1 && q0 >= q2 && q0 >= q3) {
   269         q1 *= 
SIGN(r32 - r23);
   270         q2 *= 
SIGN(r13 - r31);
   271         q3 *= 
SIGN(r21 - r12);
   272     } 
else if(q1 >= q0 && q1 >= q2 && q1 >= q3) {
   273         q0 *= 
SIGN(r32 - r23);
   275         q2 *= 
SIGN(r21 + r12);
   276         q3 *= 
SIGN(r13 + r31);
   277     } 
else if(q2 >= q0 && q2 >= q1 && q2 >= q3) {
   278         q0 *= 
SIGN(r13 - r31);
   279         q1 *= 
SIGN(r21 + r12);
   281         q3 *= 
SIGN(r32 + r23);
   282     } 
else if(q3 >= q0 && q3 >= q1 && q3 >= q2) {
   283         q0 *= 
SIGN(r21 - r12);
   284         q1 *= 
SIGN(r31 + r13);
   285         q2 *= 
SIGN(r32 + r23);
   288         cerr<<
"Coding error"<<endl;
   290     double r = 
NORM(q0, q1, q2, q3);
   305     std::ofstream file(filename);
   306     float qx,qy,qz,qw,tx,ty,tz;
   308         if ( !frame.second.empty()){
   310                 file<<frame.first<<
" "<<tx<<
" "<<ty<<
" "<<tz<<
" "<<qx<<
" "<<qy<<
" "<<qz<<
" "<<qw<<endl;
 std::map< int, cv::Mat > frame_pose_map
void setThresholdParams(double param1, double param2)
const cv::Mat getTvec() const 
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val)
void resize(cv::Size size)
string TheMarkerMapConfigFile
bool isExpressedInPixels() const 
void setCornerRefinementMethod(CornerRefinementMethod method, int val=-1)
bool isExpressedInMeters() const 
const cv::Mat getRvec() const 
void getThresholdParams(double ¶m1, double ¶m2) const 
CameraParameters TheCameraParameters
void setDictionary(std::string dict_type, float error_correction_rate=0)
std::vector< aruco::Marker > detect(const cv::Mat &input)
void readFromFile(string sfile)
static void draw3dAxis(cv::Mat &Image, const CameraParameters &CP, const cv::Mat &Rvec, const cv::Mat &Tvec, float axis_size)
cv::Mat getRTMatrix() const 
bool estimatePose(const vector< Marker > &v_m)
void readFromXMLFile(string filePath)
void cvTackBarEvents(int pos, void *)
void setParams(const CameraParameters &cam_params, const MarkerMap &msconf, float markerSize=-1)
MarkerMapPoseTracker TheMSPoseTracker
int main(int argc, char **argv)
MarkerMap convertToMeters(float markerSize)
MarkerMap TheMarkerMapConfig
void savePCDFile(string fpath, const aruco::MarkerMap &ms, const std::map< int, cv::Mat > frame_pose_map)
void getQuaternionAndTranslationfromMatrix44(const cv::Mat &M_in, float &qx, float &qy, float &qz, float &qw, float &tx, float &ty, float &tz)
Main class for marker detection. 
VideoCapture TheVideoCapturer
const cv::Mat & getThresholdedImage()
Parameters of the camera. 
std::string getDictionary() const 
MarkerDetector TheMarkerDetector
void savePosesToFile(string filename, const std::map< int, cv::Mat > &fmp)
std::vector< int > getIndices(vector< aruco::Marker > &markers)
const CwiseUnaryOp< internal::scalar_sqrt_op< Scalar >, const Derived > sqrt() const 
float NORM(float a, float b, float c, float d)
CornerRefinementMethod _cornerMethod
This class defines a set of markers whose locations are attached to a common reference system...