00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <aruco/board.h>
00029 #include <opencv2/calib3d/calib3d.hpp>
00030 #include <fstream>
00031 using namespace std;
00032 using namespace cv;
00033 namespace aruco {
00034
00039 BoardConfiguration::BoardConfiguration() {
00040 mInfoType=NONE;
00041 }
00046 BoardConfiguration::BoardConfiguration ( string filePath ) throw ( cv::Exception ) {
00047 mInfoType=NONE;
00048 readFromFile ( filePath );
00049 }
00054 BoardConfiguration::BoardConfiguration ( const BoardConfiguration &T ) : vector<MarkerInfo> ( T ) {
00055
00056 mInfoType=T.mInfoType;
00057 }
00058
00063 BoardConfiguration & BoardConfiguration ::operator= ( const BoardConfiguration &T ) {
00064
00065 vector<MarkerInfo>::operator= ( T );
00066 mInfoType=T.mInfoType;
00067 return *this;
00068 }
00073 void BoardConfiguration::saveToFile ( string sfile ) throw ( cv::Exception ) {
00074
00075 cv::FileStorage fs ( sfile,cv::FileStorage::WRITE );
00076 saveToFile ( fs );
00077
00078 }
00081 void BoardConfiguration::saveToFile ( cv::FileStorage &fs ) throw ( cv::Exception ) {
00082 fs<<"aruco_bc_nmarkers"<< ( int ) size();
00083 fs<<"aruco_bc_mInfoType"<< ( int ) mInfoType;
00084 fs<<"aruco_bc_markers"<<"[";
00085 for ( size_t i=0; i<size(); i++ ) {
00086 fs << "{:" << "id" << at ( i ).id ;
00087
00088 fs<<"corners"<< "[:";
00089 for ( int c=0; c<at ( i ).size(); c++ )
00090 fs<<at ( i ) [c];
00091 fs<<"]";
00092 fs << "}";
00093 }
00094 fs << "]";
00095 }
00096
00101 void BoardConfiguration::readFromFile ( string sfile ) throw ( cv::Exception ) {
00102 try{
00103 cv::FileStorage fs ( sfile,cv::FileStorage::READ );
00104 readFromFile ( fs );
00105 }catch (std::exception &ex){
00106 throw cv::Exception ( 81818,"BoardConfiguration::readFromFile",ex.what()+string(" file=)")+sfile ,__FILE__,__LINE__ );
00107 }
00108 }
00109
00110
00113 void BoardConfiguration::readFromFile ( cv::FileStorage &fs ) throw ( cv::Exception ) {
00114 int aux=0;
00115
00116 if ( fs["aruco_bc_nmarkers"].name() !="aruco_bc_nmarkers" )
00117 throw cv::Exception ( 81818,"BoardConfiguration::readFromFile","invalid file type" ,__FILE__,__LINE__ );
00118 fs["aruco_bc_nmarkers"]>>aux;
00119 resize ( aux );
00120 fs["aruco_bc_mInfoType"]>>mInfoType;
00121 cv::FileNode markers=fs["aruco_bc_markers"];
00122 int i=0;
00123 for ( FileNodeIterator it = markers.begin(); it!=markers.end(); ++it,i++ ) {
00124 at ( i ).id= ( *it ) ["id"];
00125 FileNode FnCorners= ( *it ) ["corners"];
00126 for ( FileNodeIterator itc = FnCorners.begin(); itc!=FnCorners.end(); ++itc ) {
00127 vector<float> coordinates3d;
00128 ( *itc ) >>coordinates3d;
00129 if ( coordinates3d.size() !=3 )
00130 throw cv::Exception ( 81818,"BoardConfiguration::readFromFile","invalid file type 3" ,__FILE__,__LINE__ );
00131 cv::Point3f point ( coordinates3d[0],coordinates3d[1],coordinates3d[2] );
00132 at ( i ).push_back ( point );
00133 }
00134 }
00135 }
00136
00139 int BoardConfiguration::getIndexOfMarkerId ( int id ) const
00140 {
00141
00142 for ( size_t i=0; i<size(); i++ )
00143 if ( at ( i ).id==id ) return i;
00144 return -1;
00145 }
00146
00149 const MarkerInfo& BoardConfiguration::getMarkerInfo ( int id ) const throw ( cv::Exception ) {
00150 for ( size_t i=0; i<size(); i++ )
00151 if ( at ( i ).id ==id ) return at ( i );
00152 throw cv::Exception ( 111,"BoardConfiguration::getMarkerInfo","Marker with the id given is not found",__FILE__,__LINE__ );
00153
00154 }
00155
00156
00159 void Board::glGetModelViewMatrix ( double modelview_matrix[16] ) throw ( cv::Exception ) {
00160
00161 bool invalid=false;
00162 for ( int i=0; i<3 && !invalid ; i++ ) {
00163 if ( Tvec.at<float> ( i,0 ) !=-999999 ) invalid|=false;
00164 if ( Rvec.at<float> ( i,0 ) !=-999999 ) invalid|=false;
00165 }
00166 if ( invalid ) throw cv::Exception ( 9002,"extrinsic parameters are not set","Marker::getModelViewMatrix",__FILE__,__LINE__ );
00167 Mat Rot ( 3,3,CV_32FC1 ),Jacob;
00168 Rodrigues ( Rvec, Rot, Jacob );
00169
00170 double para[3][4];
00171 for ( int i=0; i<3; i++ )
00172 for ( int j=0; j<3; j++ ) para[i][j]=Rot.at<float> ( i,j );
00173
00174 para[0][3]=Tvec.at<float> ( 0,0 );
00175 para[1][3]=Tvec.at<float> ( 1,0 );
00176 para[2][3]=Tvec.at<float> ( 2,0 );
00177 double scale=1;
00178
00179 modelview_matrix[0 + 0*4] = para[0][0];
00180
00181 modelview_matrix[0 + 1*4] = para[0][1];
00182 modelview_matrix[0 + 2*4] = para[0][2];
00183 modelview_matrix[0 + 3*4] = para[0][3];
00184
00185 modelview_matrix[1 + 0*4] = para[1][0];
00186 modelview_matrix[1 + 1*4] = para[1][1];
00187 modelview_matrix[1 + 2*4] = para[1][2];
00188 modelview_matrix[1 + 3*4] = para[1][3];
00189
00190 modelview_matrix[2 + 0*4] = -para[2][0];
00191 modelview_matrix[2 + 1*4] = -para[2][1];
00192 modelview_matrix[2 + 2*4] = -para[2][2];
00193 modelview_matrix[2 + 3*4] = -para[2][3];
00194 modelview_matrix[3 + 0*4] = 0.0;
00195 modelview_matrix[3 + 1*4] = 0.0;
00196 modelview_matrix[3 + 2*4] = 0.0;
00197 modelview_matrix[3 + 3*4] = 1.0;
00198 if ( scale != 0.0 ) {
00199 modelview_matrix[12] *= scale;
00200 modelview_matrix[13] *= scale;
00201 modelview_matrix[14] *= scale;
00202 }
00203
00204
00205 }
00206
00207
00208
00209
00210
00211 void Board::OgreGetPoseParameters ( double position[3], double orientation[4] ) throw ( cv::Exception ) {
00212
00213 bool invalid=false;
00214 for ( int i=0; i<3 && !invalid ; i++ ) {
00215 if ( Tvec.at<float> ( i,0 ) !=-999999 ) invalid|=false;
00216 if ( Rvec.at<float> ( i,0 ) !=-999999 ) invalid|=false;
00217 }
00218 if ( invalid ) throw cv::Exception ( 9003,"extrinsic parameters are not set","Marker::getModelViewMatrix",__FILE__,__LINE__ );
00219
00220
00221 position[0] = -Tvec.ptr<float> ( 0 ) [0];
00222 position[1] = -Tvec.ptr<float> ( 0 ) [1];
00223 position[2] = +Tvec.ptr<float> ( 0 ) [2];
00224
00225
00226 cv::Mat Rot ( 3,3,CV_32FC1 );
00227 cv::Rodrigues ( Rvec, Rot );
00228
00229
00230 double stAxes[3][3];
00231
00232 stAxes[0][0] = -Rot.at<float> ( 0,0 );
00233 stAxes[0][1] = -Rot.at<float> ( 1,0 );
00234 stAxes[0][2] = +Rot.at<float> ( 2,0 );
00235
00236 stAxes[1][0] = -Rot.at<float> ( 0,1 );
00237 stAxes[1][1] = -Rot.at<float> ( 1,1 );
00238 stAxes[1][2] = +Rot.at<float> ( 2,1 );
00239
00240 stAxes[2][0] = stAxes[0][1]*stAxes[1][2] - stAxes[0][2]*stAxes[1][1];
00241 stAxes[2][1] = - stAxes[0][0]*stAxes[1][2] + stAxes[0][2]*stAxes[1][0];
00242 stAxes[2][2] = stAxes[0][0]*stAxes[1][1] - stAxes[0][1]*stAxes[1][0];
00243
00244
00245 double axes[3][3];
00246 axes[0][0] = stAxes[0][0];
00247 axes[1][0] = stAxes[0][1];
00248 axes[2][0] = stAxes[0][2];
00249
00250 axes[0][1] = stAxes[1][0];
00251 axes[1][1] = stAxes[1][1];
00252 axes[2][1] = stAxes[1][2];
00253
00254 axes[0][2] = stAxes[2][0];
00255 axes[1][2] = stAxes[2][1];
00256 axes[2][2] = stAxes[2][2];
00257
00258
00259
00260 double fTrace = axes[0][0]+axes[1][1]+axes[2][2];
00261 double fRoot;
00262
00263 if ( fTrace > 0.0 ) {
00264
00265 fRoot = sqrt ( fTrace + 1.0 );
00266 orientation[0] = 0.5*fRoot;
00267 fRoot = 0.5/fRoot;
00268 orientation[1] = ( axes[2][1]-axes[1][2] ) *fRoot;
00269 orientation[2] = ( axes[0][2]-axes[2][0] ) *fRoot;
00270 orientation[3] = ( axes[1][0]-axes[0][1] ) *fRoot;
00271 } else {
00272
00273 static unsigned int s_iNext[3] = { 1, 2, 0 };
00274 unsigned int i = 0;
00275 if ( axes[1][1] > axes[0][0] )
00276 i = 1;
00277 if ( axes[2][2] > axes[i][i] )
00278 i = 2;
00279 unsigned int j = s_iNext[i];
00280 unsigned int k = s_iNext[j];
00281
00282 fRoot = sqrt ( axes[i][i]-axes[j][j]-axes[k][k] + 1.0 );
00283 double* apkQuat[3] = { &orientation[1], &orientation[2], &orientation[3] };
00284 *apkQuat[i] = 0.5*fRoot;
00285 fRoot = 0.5/fRoot;
00286 orientation[0] = ( axes[k][j]-axes[j][k] ) *fRoot;
00287 *apkQuat[j] = ( axes[j][i]+axes[i][j] ) *fRoot;
00288 *apkQuat[k] = ( axes[k][i]+axes[i][k] ) *fRoot;
00289 }
00290
00291
00292 }
00293
00296 void Board::draw ( cv::Mat &im,cv::Scalar color, int lineWidth,bool writeId ) {
00297 for ( size_t i=0; i<size(); i++ ) {
00298 at ( i ).draw ( im,color,lineWidth,writeId );
00299 }
00300 }
00301
00304 void Board::saveToFile ( string filePath ) throw ( cv::Exception ) {
00305 cv::FileStorage fs ( filePath,cv::FileStorage::WRITE );
00306
00307 fs<<"aruco_bo_rvec"<< Rvec;
00308 fs<<"aruco_bo_tvec"<< Tvec;
00309
00310 fs<<"aruco_bo_nmarkers"<< ( int ) size();
00311 fs<<"aruco_bo_markers"<< "[";
00312 for ( size_t i=0; i<size(); i++ ) {
00313 fs << "{:" << "id" << at ( i ).id ;
00314 fs<<"corners"<< "[:";
00315 for ( int c=0; c<at ( i ).size(); c++ )
00316 fs<<at ( i ) [c];
00317 fs<<"]";
00318 fs << "}";
00319 }
00320 fs << "]";
00321
00322 conf.saveToFile ( fs );
00323
00324
00325
00326
00327
00328 }
00331 void Board::readFromFile ( string filePath ) throw ( cv::Exception ) {
00332 cv::FileStorage fs ( filePath,cv::FileStorage::READ );
00333 if ( fs["aruco_bo_nmarkers"].name() !="aruco_bo_nmarkers" )
00334 throw cv::Exception ( 81818,"Board::readFromFile","invalid file type:" ,__FILE__,__LINE__ );
00335
00336
00337
00338 int aux=0;
00339
00340 fs["aruco_bo_nmarkers"]>>aux;
00341 resize ( aux );
00342 fs["aruco_bo_rvec"]>> Rvec;
00343 fs["aruco_bo_tvec"]>> Tvec;
00344
00345 cv::FileNode markers=fs["aruco_bo_markers"];
00346 int i=0;
00347 for ( FileNodeIterator it = markers.begin(); it!=markers.end(); ++it,i++ ) {
00348 at ( i ).id= ( *it ) ["id"];
00349 int ncorners= ( *it ) ["ncorners"];
00350 at ( i ).resize ( ncorners );
00351 FileNode FnCorners= ( *it ) ["corners"];
00352 int c=0;
00353 for ( FileNodeIterator itc = FnCorners.begin(); itc!=FnCorners.end(); ++itc,c++ ) {
00354 vector<float> coordinates2d;
00355 ( *itc ) >>coordinates2d;
00356 if ( coordinates2d.size() !=2 )
00357 throw cv::Exception ( 81818,"Board::readFromFile","invalid file type 2" ,__FILE__,__LINE__ );
00358 cv::Point2f point;
00359 point.x=coordinates2d[0];
00360 point.y=coordinates2d[1];
00361 at ( i ).push_back ( point );
00362 }
00363 }
00364
00365 conf.readFromFile ( fs );
00366
00367
00368 }
00369
00372 void BoardConfiguration::getIdList ( std::vector< int >& ids, bool append ) const
00373 {
00374 if ( !append ) ids.clear();
00375 for ( size_t i=0; i<size(); i++ )
00376 ids.push_back ( at ( i ).id );
00377 }
00378
00379 };