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 }