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/vslam.h>
00047 #include <posest/pe3d.h>
00048 #include <sba/sba.h>
00049 #include <sba/sba_file_io.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/legacy/legacy.hpp>
00059 #include <opencv2/nonfree/nonfree.hpp>
00060 
00061 using namespace std;
00062 using namespace sba;
00063 using namespace frame_common;
00064 using namespace Eigen;
00065 using namespace vslam;
00066 using namespace pcl;
00067 
00068 
00069 #define VISMATCH
00070 
00071 
00072 #include <sys/time.h>
00073 static double mstime()
00074 {
00075   timeval tv;
00076   gettimeofday(&tv,NULL);
00077   long long ts = tv.tv_sec;
00078   ts *= 1000000;
00079   ts += tv.tv_usec;
00080   return (double)ts*.001;
00081 }
00082 
00083 
00084 char *lreg, *rreg, *dreg;
00085 
00086 
00087 int getleft(struct dirent const *entry)
00088 {
00089   if (!fnmatch(lreg,entry->d_name,0))
00090     return 1;
00091   return 0;
00092 }
00093 
00094 int getright(struct dirent const *entry)
00095 {
00096   if (!fnmatch(rreg,entry->d_name,0))
00097     return 1;
00098   return 0;
00099 }
00100 
00101 
00102 int getidir(struct dirent const *entry)
00103 {
00104   if (!fnmatch(dreg,entry->d_name,0))
00105     return 1;
00106   return 0;
00107 }
00108 
00109 
00110 
00111 void publishRegisteredPointclouds(sba::SysSBA& sba, 
00112     std::vector<frame_common::Frame, Eigen::aligned_allocator<frame_common::Frame> >& frames, 
00113     ros::Publisher& pub)
00114 {
00115   pcl::PointCloud<pcl::PointXYZRGB> cloud;
00116   pcl::PointCloud<pcl::PointXYZRGB> registered_cloud;
00117 
00118   for(size_t i=0; i < frames.size(); i++)
00119   {
00120     
00121     if (sba.nodes.size() < i)
00122       break;
00123     if (frames[i].dense_pointcloud.points.size() <= 0)
00124       continue;
00125     Eigen::Quaterniond rot = sba.nodes[i].qrot;
00126     Eigen::Vector3d trans = sba.nodes[i].trans.head<3>();
00127     
00128     transformPointCloud<PointXYZRGB>(frames[i].dense_pointcloud, cloud, Vector3f(0,0,0), rot.cast<float>());
00129     transformPointCloud<PointXYZRGB>(cloud, cloud, trans.cast<float>(), Quaternionf(1, 0, 0, 0));
00130     
00131     Quaternionf qr = Quaternionf(.5, 0, 0, .5).normalized()*Quaternionf(.5, -.5, .5, -0.5).normalized(); 
00132     transformPointCloud<PointXYZRGB>(cloud, cloud, Vector3f(0,0,0), qr);
00133     
00134     registered_cloud.header = frames[i].dense_pointcloud.header;
00135     registered_cloud += cloud;
00136   }
00137   
00138   sensor_msgs::PointCloud2 cloud_out;
00139   pcl::toROSMsg (registered_cloud, cloud_out);
00140   cloud_out.header.frame_id = "/pgraph";
00141   pub.publish (cloud_out);
00142 }
00143 
00144 
00145 
00146 
00147 void
00148 drawgraph(const SysSBA &sba, const ros::Publisher &cam_pub, const ros::Publisher &pt_pub, 
00149           int dec)
00150 {
00151   visualization_msgs::Marker cammark, ptmark, cstmark;
00152   cammark.header.frame_id = "/pgraph";
00153   cammark.header.stamp = ros::Time();
00154   cammark.ns = "pgraph";
00155   cammark.id = 0;
00156   cammark.action = visualization_msgs::Marker::ADD;
00157   cammark.pose.position.x = 0;
00158   cammark.pose.position.y = 0;
00159   cammark.pose.position.z = 0;
00160   cammark.pose.orientation.x = 0.0;
00161   cammark.pose.orientation.y = 0.0;
00162   cammark.pose.orientation.z = 0.0;
00163   cammark.pose.orientation.w = 1.0;
00164   cammark.scale.x = 0.02;
00165   cammark.scale.y = 0.02;
00166   cammark.scale.z = 0.02;
00167   cammark.color.r = 0.0f;
00168   cammark.color.g = 1.0f;
00169   cammark.color.b = 1.0f;
00170   cammark.color.a = 1.0f;
00171   cammark.lifetime = ros::Duration();
00172   cammark.type = visualization_msgs::Marker::LINE_LIST;
00173 
00174   ptmark = cammark;
00175   ptmark.color.r = 1.0f;
00176   ptmark.color.g = 0.0f;
00177   ptmark.color.b = 0.0f;
00178   ptmark.color.a = 0.5f;
00179   ptmark.scale.x = 0.01;
00180   ptmark.scale.y = 0.01;
00181   ptmark.scale.z = 0.01;
00182   ptmark.type = visualization_msgs::Marker::POINTS;
00183 
00184   cstmark = cammark;
00185   cstmark.color.r = 1.0f;
00186   cstmark.color.g = 1.0f;
00187   cstmark.color.b = 0.0f;
00188   cstmark.color.a = 1.0f;
00189   cstmark.scale.x = 0.03;
00190   cstmark.scale.y = 0.1;
00191   cstmark.scale.z = 0.1;
00192   cstmark.type = visualization_msgs::Marker::LINE_LIST;
00193 
00194 
00195   
00196   int npts = sba.tracks.size();
00197 
00198   
00199   if (npts <= 0) return;
00200 
00201 
00202   ptmark.points.resize(npts/dec+1);
00203   for (int i=0, ii=0; i<npts; i+=dec, ii++)
00204     {
00205       const Vector4d &pt = sba.tracks[i].point;
00206       ptmark.points[ii].x = pt(0);
00207       ptmark.points[ii].y = pt(2);
00208       ptmark.points[ii].z = -pt(1);
00209     }
00210 
00211   
00212   int ncams = sba.nodes.size();
00213   cammark.points.resize(ncams*6);
00214   for (int i=0, ii=0; i<ncams; i++)
00215     {
00216       const Node &nd = sba.nodes[i];
00217       Vector3d opt;
00218       Matrix<double,3,4> tr;
00219       transformF2W(tr,nd.trans,Quaternion<double>(nd.qrot));
00220 
00221       cammark.points[ii].x = nd.trans.x();
00222       cammark.points[ii].y = nd.trans.z();
00223       cammark.points[ii++].z = -nd.trans.y();
00224       opt = tr*Vector4d(0,0,0.3,1);
00225       cammark.points[ii].x = opt.x();
00226       cammark.points[ii].y = opt.z();
00227       cammark.points[ii++].z = -opt.y();
00228 
00229       cammark.points[ii].x = nd.trans.x();
00230       cammark.points[ii].y = nd.trans.z();
00231       cammark.points[ii++].z = -nd.trans.y();
00232       opt = tr*Vector4d(0.2,0,0,1);
00233       cammark.points[ii].x = opt.x();
00234       cammark.points[ii].y = opt.z();
00235       cammark.points[ii++].z = -opt.y();
00236 
00237       cammark.points[ii].x = nd.trans.x();
00238       cammark.points[ii].y = nd.trans.z();
00239       cammark.points[ii++].z = -nd.trans.y();
00240       opt = tr*Vector4d(0,0.1,0,1);
00241       cammark.points[ii].x = opt.x();
00242       cammark.points[ii].y = opt.z();
00243       cammark.points[ii++].z = -opt.y();
00244     }
00245 
00246   
00247   int num_tracks = sba.tracks.size();
00248   int ii = cammark.points.size();
00249 
00250   for (int i=0; i < num_tracks; i++)
00251     {
00252       const ProjMap &prjs = sba.tracks[i].projections;
00253       for (ProjMap::const_iterator itr = prjs.begin(); itr != prjs.end(); itr++)
00254         {
00255           const Proj &prj = (*itr).second;
00256           if (prj.pointPlane)   
00257             {
00258               cammark.points.resize(ii+2);
00259               Point pt0 = sba.tracks[i].point;
00260               Vector3d plane_point = prj.plane_point;
00261               Vector3d plane_normal = prj.plane_normal;
00262               Eigen::Vector3d w = pt0.head<3>()-plane_point;
00263               
00264               Eigen::Vector3d projpt = pt0.head<3>() - (w.dot(plane_normal))*plane_normal;
00265               
00266               Vector3d pt1 = projpt;
00267                   
00268               cammark.points[ii].x = pt0.x();
00269               cammark.points[ii].y = pt0.z();
00270               cammark.points[ii++].z = -pt0.y();
00271               cammark.points[ii].x = pt1.x();
00272               cammark.points[ii].y = pt1.z();
00273               cammark.points[ii++].z = -pt1.y();
00274             }
00275         } 
00276     }
00277 
00278 
00279 #if 0
00280   
00281   int ncons = spa.p2cons.size();
00282   cstmark.points.resize(ncons*6);
00283 
00284   for (int i=0, ii=0; i<ncons; i++)
00285     {
00286       ConP2 &con = spa.p2cons[i];
00287       Node &nd0 = spa.nodes[con.ndr];
00288       Node &nd1 = spa.nodes[con.nd1];
00289 
00290       Node &nd = spa.nodes[i];
00291       Vector3d opt;
00292       Matrix<double,3,4> tr;
00293       transformF2W(tr,nd.trans,Quaternion<double>(nd.qrot));
00294 
00295       cstmark.points[ii].x = nd.trans.x();
00296       cstmark.points[ii].y = nd.trans.z();
00297       cstmark.points[ii++].z = -nd.trans.y();
00298       opt = tr*Vector4d(0,0,0.3,1);
00299       cstmark.points[ii].x = opt.x();
00300       cstmark.points[ii].y = opt.z();
00301       cstmark.points[ii++].z = -opt.y();
00302 
00303       cstmark.points[ii].x = nd.trans.x();
00304       cstmark.points[ii].y = nd.trans.z();
00305       cstmark.points[ii++].z = -nd.trans.y();
00306       opt = tr*Vector4d(0.2,0,0,1);
00307       cstmark.points[ii].x = opt.x();
00308       cstmark.points[ii].y = opt.z();
00309       cstmark.points[ii++].z = -opt.y();
00310 
00311       cstmark.points[ii].x = nd.trans.x();
00312       cstmark.points[ii].y = nd.trans.z();
00313       cstmark.points[ii++].z = -nd.trans.y();
00314       opt = tr*Vector4d(0,0.1,0,1);
00315       cstmark.points[ii].x = opt.x();
00316       cstmark.points[ii].y = opt.z();
00317       cstmark.points[ii++].z = -opt.y();
00318 
00319 #if 0
00320       cstmark.points[ii].x = nd0.trans.x();
00321       cstmark.points[ii].y= nd0.trans.z();
00322       cstmark.points[ii++].z = -nd0.trans.y();
00323       cstmark.points[ii].x = nd1.trans.x();
00324       cstmark.points[ii].y = nd1.trans.z();
00325       cstmark.points[ii++].z = -nd1.trans.y();
00326 #endif
00327     }
00328 #endif // SPA
00329 
00330   cam_pub.publish(cammark);
00331   pt_pub.publish(ptmark);
00332   
00333   
00334 }
00335 
00336 
00337 
00338 
00339 
00340 int main(int argc, char** argv)
00341 {
00342   if (argc < 8)
00343     {
00344       printf("Args are: <param file> <image dir> <left image file template> <right image file template> "
00345              "<vocab tree file> <vocab weights file> <calonder trees file>\n");
00346       exit(0);
00347     }
00348 
00349   
00350   fstream fstr;
00351   fstr.open(argv[1],fstream::in);
00352   if (!fstr.is_open())
00353     {
00354       printf("Can't open camera file %s\n",argv[1]);
00355       exit(0);
00356     }
00357   CamParams camp;
00358   fstr >> camp.fx;
00359   fstr >> camp.fy;
00360   fstr >> camp.cx;
00361   fstr >> camp.cy;
00362   fstr >> camp.tx;
00363 
00364   cout << "Cam params: " << camp.fx << " " << camp.fy << " " << camp.cx
00365        << " " << camp.cy << " " << camp.tx << endl;
00366 
00367 
00368   
00369   struct dirent **lims, **rims, **dirs;
00370   int nlim, nrim, ndirs;
00371   string dname = argv[2];
00372   if (!dname.compare(dname.size()-1,1,"/")) 
00373     dname.erase(dname.size()-1);
00374 
00375   string dirfn = dname.substr(dname.rfind("/")+1);
00376   string tdir = dname.substr(0,dname.rfind("/")+1);
00377   cout << "Top directory is " << tdir << endl;
00378   cout << "Search directory name is " << dirfn << endl;
00379   dreg = (char *)dirfn.c_str();
00380 
00381   ndirs = scandir(tdir.c_str(),&dirs,getidir,alphasort);
00382   printf("Found %d directories\n", ndirs);
00383   printf("%s\n",dirs[0]->d_name);
00384 
00385   
00386   vslam::VslamSystem vslam(argv[5], argv[6]);
00387   typedef cv::CalonderDescriptorExtractor<float> Calonder;
00388   typedef cv::SiftDescriptorExtractor Sift;
00389   
00390   vslam.frame_processor_.setFrameDescriptor(new Calonder(argv[7]));
00391   
00392 
00393   
00394   vslam.setPointcloudProc(boost::shared_ptr<frame_common::PointcloudProc>(new frame_common::PointcloudProc()));
00395   
00396   vslam.doPointPlane = false;
00397   
00398   
00399   vslam.setKeyDist(0.1);        
00400   vslam.setKeyAngle(0.05);      
00401   vslam.setKeyInliers(200);
00402   vslam.setHuber(40.0);          
00403   vslam.vo_.pose_estimator_->wy = 92;
00404   vslam.vo_.pose_estimator_->wx = 92;
00405   vslam.vo_.pose_estimator_->numRansac = 10000;
00406   vslam.vo_.sba.verbose = false;
00407   vslam.sba_.verbose = false;
00408 
00409   
00410   
00411   ros::init(argc, argv, "VisBundler");
00412   ros::NodeHandle nh ("~");
00413   ros::Publisher pt_pub = nh.advertise<visualization_msgs::Marker>("points", 0);
00414   ros::Publisher cam_pub = nh.advertise<visualization_msgs::Marker>("cameras", 0);
00415   ros::Publisher cst_pub = nh.advertise<visualization_msgs::Marker>("constraints", 0);
00416   ros::Publisher link_pub = nh.advertise<visualization_msgs::Marker>("links", 0);
00417   ros::Publisher pc_pub = nh.advertise<sensor_msgs::PointCloud2>("pointcloud", 1);
00418 
00419   
00420   srand(mstime());
00421 
00422   
00423 #ifdef VISMATCH  
00424   const std::string window_name = "VO tracks";
00425   cv::namedWindow(window_name,0);
00426   cv::Mat display;
00427 #endif
00428 
00429   int iter = 0;
00430   lreg = argv[3];
00431   rreg = argv[4];
00432 
00433 
00434   
00435   for (int dd=0; dd<ndirs; dd++)
00436     {
00437       char dir[2048];
00438       sprintf(dir,"%s%s",tdir.c_str(),dirs[dd]->d_name);
00439       printf("Current directory: %s\n", dir);
00440 
00441       
00442       nlim = scandir(dir,&lims,getleft,alphasort);
00443       printf("Found %d left images\n", nlim);
00444       printf("%s\n",lims[0]->d_name);
00445 
00446       nrim = scandir(dir,&rims,getright,alphasort);
00447       printf("Found %d disparity images\n", nrim);
00448       printf("%s\n",rims[0]->d_name);
00449 
00450       if (nlim != nrim)
00451         {
00452           printf("Number of left/disparity images does not match: %d vs. %d\n", nlim, nrim);
00453           exit(0);
00454         }
00455 
00456 
00457 
00458       
00459       for (int ii=0; ii<nlim; iter++, ii++)
00460         {
00461           
00462           char fn[2048];
00463           sprintf(fn,"%s/%s",dir,lims[ii]->d_name);
00464           cv::Mat image1 = cv::imread(fn,0);
00465           sprintf(fn,"%s/%s",dir,rims[ii]->d_name);
00466           cv::Mat image1r = cv::imread(fn,-1);
00467 
00468           printf("Image: %s\n", fn);
00469 #if 0
00470           printf("Image size: %d x %d\n", image1.cols, image1.rows);
00471           printf("Image size: %d x %d\n", image1r.cols, image1r.rows);
00472 #endif
00473 
00474           if (image1.rows == 0 || image1r.rows == 0)
00475             exit(0);
00476 
00477           
00478           
00479           
00480           bool is_keyframe = vslam.addFrame(camp, image1, image1r, 32.0, true); 
00481 
00482           usleep(10);
00483 
00484           if (is_keyframe)
00485             {
00486               vslam.sba_.doSBA(10,1e-4,SBA_SPARSE_CHOLESKY);
00487 
00489               int n = vslam.sba_.nodes.size();
00490               int np = vslam.sba_.tracks.size();
00491 
00492               
00493               
00494 #if 1
00495               if (n%1 == 0)
00496                 {
00497                   drawgraph(vslam.vo_.sba, cam_pub, pt_pub, 1); 
00498                   publishRegisteredPointclouds(vslam.vo_.sba, vslam.vo_.frames, pc_pub);
00499                   drawgraph(vslam.vo_.sba, cam_pub, pt_pub, 1); 
00500                   publishRegisteredPointclouds(vslam.vo_.sba, vslam.vo_.frames, pc_pub);
00501                   for (int i=0; i<5; i++)
00502                     {
00503                       
00504                       cout << i << endl;
00505                       vslam.vo_.sba.doSBA(1,1.0e-5,0);          
00506                       drawgraph(vslam.vo_.sba, cam_pub, pt_pub, 1); 
00507                       publishRegisteredPointclouds(vslam.vo_.sba, vslam.vo_.frames, pc_pub);
00508                       drawgraph(vslam.vo_.sba, cam_pub, pt_pub, 1); 
00509                       publishRegisteredPointclouds(vslam.vo_.sba, vslam.vo_.frames, pc_pub);
00510                     }
00511                 }
00512 #endif
00513 
00514               
00515               if (n > 10 && n%500 == 0)
00516                 {
00517                   char fn[1024];
00518                   sprintf(fn,"newcollege%d.g2o", n);
00519                   sba::writeGraphFile(fn,vslam.sba_);
00520                   sprintf(fn,"newcollege%dm.g2o", n);
00521                   sba::writeGraphFile(fn,vslam.sba_,true);
00522                   
00523                   
00524                   
00525                 }
00526 
00527 #if 1
00528               int nnsba = 10;
00529               if (n > 4 && n%nnsba == 0)
00530                 {
00531                   cout << "Running large SBA" << endl;
00532                   vslam.refine();
00533                 }
00534 #endif
00535             }
00536 
00537 #ifdef VISMATCH
00538           
00539           if (1)
00540             {
00541               drawVOtracks(image1, vslam.vo_.frames, display);
00542               cv::imshow(window_name, display);
00543               cv::waitKey(0);
00544             }
00545 #endif
00546 
00547           if (!nh.ok())
00548             return 0;
00549         }
00550     }
00551   return 0;
00552 }