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 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 #include <ros/ros.h>
00042 #include <visualization_msgs/Marker.h>
00043 #include <visualization_msgs/MarkerArray.h>
00044 #include <geometry_msgs/Point.h>
00045 
00046 #include <vslam_system/vo.h>
00047 #include <vslam_system/place_recognizer.h>
00048 #include <posest/pe2d.h>
00049 #include <sba/sba.h>
00050 #include <frame_common/frame.h>
00051 #include <boost/shared_ptr.hpp>
00052 #include <cstdio>
00053 #include <fstream>
00054 #include <dirent.h>
00055 #include <fnmatch.h>
00056 
00057 #include <opencv/highgui.h>
00058 #include <opencv2/nonfree/nonfree.hpp>
00059 
00060 using namespace std;
00061 using namespace sba;
00062 using namespace frame_common;
00063 using namespace Eigen;
00064 using namespace vslam;
00065 
00066 
00067 #define VISMATCH
00068 
00069 
00070 #include <sys/time.h>
00071 static double mstime()
00072 {
00073   timeval tv;
00074   gettimeofday(&tv,NULL);
00075   long long ts = tv.tv_sec;
00076   ts *= 1000000;
00077   ts += tv.tv_usec;
00078   return (double)ts*.001;
00079 }
00080 
00081 
00082 char *lreg, *rreg, *dreg;
00083 
00084 
00085 int getleft(struct dirent const *entry)
00086 {
00087   if (!fnmatch(lreg,entry->d_name,0))
00088     return 1;
00089   return 0;
00090 }
00091 
00092 int getright(struct dirent const *entry)
00093 {
00094   if (!fnmatch(rreg,entry->d_name,0))
00095     return 1;
00096   return 0;
00097 }
00098 
00099 
00100 int getidir(struct dirent const *entry)
00101 {
00102   if (!fnmatch(dreg,entry->d_name,0))
00103     return 1;
00104   return 0;
00105 }
00106 
00107 
00108 
00109 
00110 void
00111 drawgraph(SysSBA &sba, SysSPA &spa, ros::Publisher &cam_pub, ros::Publisher &pt_pub, int dec,
00112           ros::Publisher &cst_pub, ros::Publisher &link_pub)
00113 {
00114   visualization_msgs::Marker cammark, ptmark, cstmark;
00115   cammark.header.frame_id = "/pgraph";
00116   cammark.header.stamp = ros::Time();
00117   cammark.ns = "pgraph";
00118   cammark.id = 0;
00119   cammark.action = visualization_msgs::Marker::ADD;
00120   cammark.pose.position.x = 0;
00121   cammark.pose.position.y = 0;
00122   cammark.pose.position.z = 0;
00123   cammark.pose.orientation.x = 0.0;
00124   cammark.pose.orientation.y = 0.0;
00125   cammark.pose.orientation.z = 0.0;
00126   cammark.pose.orientation.w = 1.0;
00127   cammark.scale.x = 0.02;
00128   cammark.scale.y = 0.02;
00129   cammark.scale.z = 0.02;
00130   cammark.color.r = 0.0f;
00131   cammark.color.g = 1.0f;
00132   cammark.color.b = 1.0f;
00133   cammark.color.a = 1.0f;
00134   cammark.lifetime = ros::Duration();
00135   cammark.type = visualization_msgs::Marker::LINE_LIST;
00136 
00137   ptmark = cammark;
00138   ptmark.color.r = 1.0f;
00139   ptmark.color.g = 0.0f;
00140   ptmark.color.b = 0.0f;
00141   ptmark.color.a = 0.5f;
00142   ptmark.scale.x = 0.2;
00143   ptmark.scale.y = 0.2;
00144   ptmark.scale.z = 0.2;
00145   ptmark.type = visualization_msgs::Marker::POINTS;
00146 
00147   cstmark = cammark;
00148   cstmark.color.r = 1.0f;
00149   cstmark.color.g = 1.0f;
00150   cstmark.color.b = 0.0f;
00151   cstmark.color.a = 1.0f;
00152   cstmark.scale.x = 0.06;
00153   cstmark.scale.y = 0.2;
00154   cstmark.scale.z = 0.2;
00155   cstmark.type = visualization_msgs::Marker::LINE_LIST;
00156 
00157 
00158   
00159   int npts = sba.tracks.size();
00160 
00161   cout << "Number of points to draw: " << npts << endl;
00162   if (npts <= 0) return;
00163 
00164 
00165   ptmark.points.resize(npts/dec+1);
00166   for (int i=0, ii=0; i<npts; i+=dec, ii++)
00167     {
00168       Vector4d &pt = sba.tracks[i].point;
00169       ptmark.points[ii].x = pt(0);
00170       ptmark.points[ii].y = pt(2);
00171       ptmark.points[ii].z = -pt(1);
00172 
00173 
00174     }
00175 
00176   
00177   int ncams = sba.nodes.size();
00178   cammark.points.resize(ncams*6);
00179   for (int i=0, ii=0; i<ncams; i++)
00180     {
00181       Node &nd = sba.nodes[i];
00182       Vector3d opt;
00183       Matrix<double,3,4> tr;
00184       transformF2W(tr,nd.trans,Quaternion<double>(nd.qrot));
00185 
00186       printf("camera transform: %f %f %f\n", nd.trans.x(),
00187              nd.trans.y(), nd.trans.z());
00188       cammark.points[ii].x = nd.trans.x();
00189       cammark.points[ii].y = nd.trans.z();
00190       cammark.points[ii++].z = -nd.trans.y();
00191       opt = tr*Vector4d(0,0,0.3,1);
00192       cammark.points[ii].x = opt.x();
00193       cammark.points[ii].y = opt.z();
00194       cammark.points[ii++].z = -opt.y();
00195 
00196       cammark.points[ii].x = nd.trans.x();
00197       cammark.points[ii].y = nd.trans.z();
00198       cammark.points[ii++].z = -nd.trans.y();
00199       opt = tr*Vector4d(0.2,0,0,1);
00200       cammark.points[ii].x = opt.x();
00201       cammark.points[ii].y = opt.z();
00202       cammark.points[ii++].z = -opt.y();
00203 
00204       cammark.points[ii].x = nd.trans.x();
00205       cammark.points[ii].y = nd.trans.z();
00206       cammark.points[ii++].z = -nd.trans.y();
00207       opt = tr*Vector4d(0,0.1,0,1);
00208       cammark.points[ii].x = opt.x();
00209       cammark.points[ii].y = opt.z();
00210       cammark.points[ii++].z = -opt.y();
00211     }
00212 
00213   
00214   int ncons = spa.p2cons.size();
00215   cstmark.points.resize(ncons*6);
00216 
00217   for (int i=0, ii=0; i<ncons; i++)
00218     {
00219       ConP2 &con = spa.p2cons[i];
00220       Node &nd0 = spa.nodes[con.ndr];
00221       Node &nd1 = spa.nodes[con.nd1];
00222 
00223       Node &nd = spa.nodes[i];
00224       Vector3d opt;
00225       Matrix<double,3,4> tr;
00226       transformF2W(tr,nd.trans,Quaternion<double>(nd.qrot));
00227 
00228       cstmark.points[ii].x = nd.trans.x();
00229       cstmark.points[ii].y = nd.trans.z();
00230       cstmark.points[ii++].z = -nd.trans.y();
00231       opt = tr*Vector4d(0,0,0.3,1);
00232       cstmark.points[ii].x = opt.x();
00233       cstmark.points[ii].y = opt.z();
00234       cstmark.points[ii++].z = -opt.y();
00235 
00236       cstmark.points[ii].x = nd.trans.x();
00237       cstmark.points[ii].y = nd.trans.z();
00238       cstmark.points[ii++].z = -nd.trans.y();
00239       opt = tr*Vector4d(0.2,0,0,1);
00240       cstmark.points[ii].x = opt.x();
00241       cstmark.points[ii].y = opt.z();
00242       cstmark.points[ii++].z = -opt.y();
00243 
00244       cstmark.points[ii].x = nd.trans.x();
00245       cstmark.points[ii].y = nd.trans.z();
00246       cstmark.points[ii++].z = -nd.trans.y();
00247       opt = tr*Vector4d(0,0.1,0,1);
00248       cstmark.points[ii].x = opt.x();
00249       cstmark.points[ii].y = opt.z();
00250       cstmark.points[ii++].z = -opt.y();
00251 
00252 #if 0
00253       cstmark.points[ii].x = nd0.trans.x();
00254       cstmark.points[ii].y= nd0.trans.z();
00255       cstmark.points[ii++].z = -nd0.trans.y();
00256       cstmark.points[ii].x = nd1.trans.x();
00257       cstmark.points[ii].y = nd1.trans.z();
00258       cstmark.points[ii++].z = -nd1.trans.y();
00259 #endif
00260     }
00261 
00262   cam_pub.publish(cammark);
00263   pt_pub.publish(ptmark);
00264   cst_pub.publish(cstmark);
00265 
00266 #if 0
00267   cv::namedWindow("1", 1);
00268   cv::waitKey();
00269 #endif
00270 }
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 double maxdist = 0.5;
00281 double maxang  = 10.0;          
00282 int mininls    = 30;          
00283 int ndi = 0;                    
00284 
00285 int main(int argc, char** argv)
00286 {
00287   if (argc < 5)
00288     {
00289       printf("Args are: <param file> <image dir> <left image file template> <right image file template> \n");
00290       exit(0);
00291     }
00292 
00293   
00294   fstream fstr;
00295   fstr.open(argv[1],fstream::in);
00296   if (!fstr.is_open())
00297     {
00298       printf("Can't open camera file %s\n",argv[1]);
00299       exit(0);
00300     }
00301   CamParams camp;
00302   fstr >> camp.fx;
00303   fstr >> camp.fy;
00304   fstr >> camp.cx;
00305   fstr >> camp.cy;
00306   fstr >> camp.tx;
00307 
00308   cout << "Cam params: " << camp.fx << " " << camp.fy << " " << camp.cx
00309        << " " << camp.cy << " " << camp.tx << endl;
00310 
00311 
00312   
00313   struct dirent **lims, **rims, **dirs;
00314   int nlim, nrim, ndirs;
00315   string dname = argv[2];
00316   if (!dname.compare(dname.size()-1,1,"/")) 
00317     dname.erase(dname.size()-1);
00318 
00319   string dirfn = dname.substr(dname.rfind("/")+1);
00320   string tdir = dname.substr(0,dname.rfind("/")+1);
00321   cout << "Top directory is " << tdir << endl;
00322   cout << "Search directory name is " << dirfn << endl;
00323   dreg = (char *)dirfn.c_str();
00324 
00325   ndirs = scandir(tdir.c_str(),&dirs,getidir,alphasort);
00326   printf("Found %d directories\n", ndirs);
00327   printf("%s\n",dirs[0]->d_name);
00328 
00329   
00330   cout << "Setting up frame processing..." << flush;
00331   FrameProc fp(15);
00332   fp.setFrameDetector(cv::Ptr<cv::FeatureDetector>(new cv::SurfFeatureDetector(200)));
00333   cout << "done" << endl;
00334   vector<Frame, Eigen::aligned_allocator<Frame> > frames; 
00335 
00336   SysSBA sba;                   
00337   sba.useCholmod(false);
00338 
00339   SysSPA spa;                   
00340   int spaFrameId = -1;          
00341   int ndi0 = 0;                 
00342   
00343   
00344   voSt vo(boost::shared_ptr<pe::PoseEstimator>(new pe::PoseEstimator2d), 40,10,mininls,maxdist,maxang); 
00345 
00346   std::vector<const Frame*> place_matches;
00348   pe::PoseEstimator3d pe(1000,true,10.0,3.0,3.0);
00349   pe.wx = 92;
00350   pe.wy = 48;
00351 
00352   
00353   ros::init(argc, argv, "VisBundler");
00354   ros::NodeHandle nh ("~");
00355   ros::Publisher pt_pub = nh.advertise<visualization_msgs::Marker>("points", 0);
00356   ros::Publisher cam_pub = nh.advertise<visualization_msgs::Marker>("cameras", 0);
00357   ros::Publisher cst_pub = nh.advertise<visualization_msgs::Marker>("constraints", 0);
00358   ros::Publisher link_pub = nh.advertise<visualization_msgs::Marker>("links", 0);
00359 
00360   
00361   srand(mstime());
00362 
00363   
00364 #ifdef VISMATCH
00365   const std::string window_name = "VO tracks";
00366   cv::namedWindow(window_name,0);
00367   cv::Mat display;
00368 #endif
00369 
00370   int iter = 0;
00371   lreg = argv[3];
00372   rreg = argv[4];
00373 
00374   
00375   for (int dd=0; dd<ndirs; dd++)
00376     {
00377       char dir[2048];
00378       sprintf(dir,"%s%s",tdir.c_str(),dirs[dd]->d_name);
00379       printf("Current directory: %s\n", dir);
00380 
00381       
00382       nlim = scandir(dir,&lims,getleft,alphasort);
00383       printf("Found %d left images\n", nlim);
00384       printf("%s\n",lims[0]->d_name);
00385 
00386       nrim = scandir(dir,&rims,getright,alphasort);
00387       printf("Found %d right images\n", nrim);
00388       printf("%s\n",rims[0]->d_name);
00389 
00390       if (nlim != nrim)
00391         {
00392           printf("Number of left/right images does not match: %d vs. %d\n", nlim, nrim);
00393           exit(0);
00394         }
00395 
00396       const int init_min_frame_count = 5;
00397 
00398       
00399       bool ret = false;
00400       for (int ii=0; ii<nlim; iter++, ii += ret ? 5 : 1)
00401         {
00402           if(ii > 0 && ii < init_min_frame_count)
00403           {
00404             continue;
00405           }
00406 
00407           
00408           char fn[2048];
00409           sprintf(fn,"%s/%s",dir,lims[ii]->d_name);
00410           cv::Mat image1 = cv::imread(fn,0);
00411           sprintf(fn,"%s/%s",dir,rims[ii]->d_name);
00412           cv::Mat image1r = cv::imread(fn,0);
00413 
00414 
00415           if (image1.rows == 0 || image1r.rows == 0)
00416             exit(0);
00417 
00418           double t0 = mstime();
00419           Frame f1;             
00420           f1.setCamParams(camp); 
00421 
00422           fp.setMonoFrame(f1,image1);
00423           f1.frameId = sba.nodes.size(); 
00424 
00425           f1.imgRight = cv::Mat();
00426 
00427           
00428           cout << "calling vo::addFrame" << endl;
00429           ret = vo.addFrame(f1);
00430 
00431           
00432           if (ret)
00433           {
00434             frames.push_back(f1);
00435             if(frames.size() > 1)
00436             {
00437               Frame& _fs = frames.back();
00438               Frame& _f0 = *(frames.end() - 2);
00439 
00440               if(vo.pose_estimator_->getMethod() == pe::PoseEstimator::SFM)
00441               {
00442 
00443                 cout << "frames.size() " << frames.size() << endl;
00444                 frames[0].pts = (vo.frames.end() - 2)->pts;
00445                 frames[0].goodPts = (vo.frames.end() - 2)->goodPts;
00446               }
00447 
00448               int count = 0;
00449               for(size_t i = 0; i < _f0.goodPts.size(); i++)
00450               {
00451                 if(_f0.goodPts[i]) count++;
00452               }
00453               printf("The number of good points: %d\n", count);
00454             }
00455             
00456             {
00457               vo.transferLatestFrame(frames,sba);
00458             }
00459           }
00460 
00461           if (frames.size() > 1 && vo.pose_estimator_->inliers.size() < mininls)
00462             cout << endl << "******** Bad image match: " << fn << endl << endl;
00463 
00464 
00465 
00466           if (ret)
00467             {
00468               int n = sba.nodes.size();
00469               int np = sba.tracks.size();
00470 
00471               
00472               cout << "drawing with " << n << " nodes and " << np << " points..." << endl << endl;
00473 #if 1
00474               if (n%2 == 0)
00475                 drawgraph(sba,spa,cam_pub,pt_pub,1,cst_pub,link_pub); 
00476 #endif
00477 
00478 #if 1
00479               int nnsba = 10;
00480               if (n > 4 && n%nnsba == 0)
00481                 {
00482                   cout << "Running large SBA" << endl;
00483 
00484                 }
00485 #endif
00486             }
00487 
00488 #ifdef VISMATCH
00489           
00490           if (ret || 1)
00491             {
00492               drawVOtracks(image1,vo.frames,display);
00493               cv::imshow(window_name, display);
00494               cv::waitKey(10);
00495             }
00496 #endif
00497 
00498           if (!nh.ok())
00499             return 0;
00500         }
00501     }
00502   return 0;
00503 }