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
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(const SysSBA &sba, const ros::Publisher &cam_pub, const ros::Publisher &pt_pub, int dec
00112 )
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.02;
00143 ptmark.scale.y = 0.02;
00144 ptmark.scale.z = 0.02;
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.03;
00153 cstmark.scale.y = 0.1;
00154 cstmark.scale.z = 0.1;
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 const 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 int ncams = sba.nodes.size();
00176 cammark.points.resize(ncams*6);
00177 for (int i=0, ii=0; i<ncams; i++)
00178 {
00179 const Node &nd = sba.nodes[i];
00180 Vector3d opt;
00181 Matrix<double,3,4> tr;
00182 transformF2W(tr,nd.trans,Quaternion<double>(nd.qrot));
00183
00184 cammark.points[ii].x = nd.trans.x();
00185 cammark.points[ii].y = nd.trans.z();
00186 cammark.points[ii++].z = -nd.trans.y();
00187 opt = tr*Vector4d(0,0,0.3,1);
00188 cammark.points[ii].x = opt.x();
00189 cammark.points[ii].y = opt.z();
00190 cammark.points[ii++].z = -opt.y();
00191
00192 cammark.points[ii].x = nd.trans.x();
00193 cammark.points[ii].y = nd.trans.z();
00194 cammark.points[ii++].z = -nd.trans.y();
00195 opt = tr*Vector4d(0.2,0,0,1);
00196 cammark.points[ii].x = opt.x();
00197 cammark.points[ii].y = opt.z();
00198 cammark.points[ii++].z = -opt.y();
00199
00200 cammark.points[ii].x = nd.trans.x();
00201 cammark.points[ii].y = nd.trans.z();
00202 cammark.points[ii++].z = -nd.trans.y();
00203 opt = tr*Vector4d(0,0.1,0,1);
00204 cammark.points[ii].x = opt.x();
00205 cammark.points[ii].y = opt.z();
00206 cammark.points[ii++].z = -opt.y();
00207 }
00208
00209 #if 0
00210
00211 int ncons = spa.p2cons.size();
00212 cstmark.points.resize(ncons*6);
00213
00214 for (int i=0, ii=0; i<ncons; i++)
00215 {
00216 ConP2 &con = spa.p2cons[i];
00217 Node &nd0 = spa.nodes[con.ndr];
00218 Node &nd1 = spa.nodes[con.nd1];
00219
00220 Node &nd = spa.nodes[i];
00221 Vector3d opt;
00222 Matrix<double,3,4> tr;
00223 transformF2W(tr,nd.trans,Quaternion<double>(nd.qrot));
00224
00225 cstmark.points[ii].x = nd.trans.x();
00226 cstmark.points[ii].y = nd.trans.z();
00227 cstmark.points[ii++].z = -nd.trans.y();
00228 opt = tr*Vector4d(0,0,0.3,1);
00229 cstmark.points[ii].x = opt.x();
00230 cstmark.points[ii].y = opt.z();
00231 cstmark.points[ii++].z = -opt.y();
00232
00233 cstmark.points[ii].x = nd.trans.x();
00234 cstmark.points[ii].y = nd.trans.z();
00235 cstmark.points[ii++].z = -nd.trans.y();
00236 opt = tr*Vector4d(0.2,0,0,1);
00237 cstmark.points[ii].x = opt.x();
00238 cstmark.points[ii].y = opt.z();
00239 cstmark.points[ii++].z = -opt.y();
00240
00241 cstmark.points[ii].x = nd.trans.x();
00242 cstmark.points[ii].y = nd.trans.z();
00243 cstmark.points[ii++].z = -nd.trans.y();
00244 opt = tr*Vector4d(0,0.1,0,1);
00245 cstmark.points[ii].x = opt.x();
00246 cstmark.points[ii].y = opt.z();
00247 cstmark.points[ii++].z = -opt.y();
00248
00249 #if 0
00250 cstmark.points[ii].x = nd0.trans.x();
00251 cstmark.points[ii].y= nd0.trans.z();
00252 cstmark.points[ii++].z = -nd0.trans.y();
00253 cstmark.points[ii].x = nd1.trans.x();
00254 cstmark.points[ii].y = nd1.trans.z();
00255 cstmark.points[ii++].z = -nd1.trans.y();
00256 #endif
00257 }
00258 #endif // SPA
00259
00260 cam_pub.publish(cammark);
00261 pt_pub.publish(ptmark);
00262
00263 }
00264
00265
00266
00267
00268
00269 int main(int argc, char** argv)
00270 {
00271 if (argc < 8)
00272 {
00273 printf("Args are: <param file> <image dir> <left image file template> <right image file template> "
00274 "<vocab tree file> <vocab weights file> <calonder trees file>\n");
00275 exit(0);
00276 }
00277
00278
00279 fstream fstr;
00280 fstr.open(argv[1],fstream::in);
00281 if (!fstr.is_open())
00282 {
00283 printf("Can't open camera file %s\n",argv[1]);
00284 exit(0);
00285 }
00286 CamParams camp;
00287 fstr >> camp.fx;
00288 fstr >> camp.fy;
00289 fstr >> camp.cx;
00290 fstr >> camp.cy;
00291 fstr >> camp.tx;
00292
00293 cout << "Cam params: " << camp.fx << " " << camp.fy << " " << camp.cx
00294 << " " << camp.cy << " " << camp.tx << endl;
00295
00296
00297
00298 struct dirent **lims, **rims, **dirs;
00299 int nlim, nrim, ndirs;
00300 string dname = argv[2];
00301 if (!dname.compare(dname.size()-1,1,"/"))
00302 dname.erase(dname.size()-1);
00303
00304 string dirfn = dname.substr(dname.rfind("/")+1);
00305 string tdir = dname.substr(0,dname.rfind("/")+1);
00306 cout << "Top directory is " << tdir << endl;
00307 cout << "Search directory name is " << dirfn << endl;
00308 dreg = (char *)dirfn.c_str();
00309
00310 ndirs = scandir(tdir.c_str(),&dirs,getidir,alphasort);
00311 printf("Found %d directories\n", ndirs);
00312 printf("%s\n",dirs[0]->d_name);
00313
00314
00315 vslam::VslamSystem vslam(argv[5], argv[6]);
00316 typedef cv::CalonderDescriptorExtractor<float> Calonder;
00317 vslam.frame_processor_.setFrameDescriptor(new Calonder(argv[7]));
00318
00319
00320 vslam.setKeyDist(0.4);
00321 vslam.setKeyAngle(0.2);
00322 vslam.setKeyInliers(300);
00323 vslam.setHuber(2.0);
00324
00325
00326
00327 vslam.vo_.sba.verbose = false;
00328 vslam.sba_.verbose = false;
00329
00330
00331 ros::init(argc, argv, "VisBundler");
00332 ros::NodeHandle nh ("~");
00333 ros::Publisher pt_pub = nh.advertise<visualization_msgs::Marker>("points", 0);
00334 ros::Publisher cam_pub = nh.advertise<visualization_msgs::Marker>("cameras", 0);
00335 ros::Publisher cst_pub = nh.advertise<visualization_msgs::Marker>("constraints", 0);
00336 ros::Publisher link_pub = nh.advertise<visualization_msgs::Marker>("links", 0);
00337
00338
00339 srand(mstime());
00340
00341
00342 #ifdef VISMATCH
00343 const std::string window_name = "VO tracks";
00344 cv::namedWindow(window_name,0);
00345 cv::Mat display;
00346 #endif
00347
00348 int iter = 0;
00349 lreg = argv[3];
00350 rreg = argv[4];
00351
00352
00353
00354 for (int dd=0; dd<ndirs; dd++)
00355 {
00356 char dir[2048];
00357 sprintf(dir,"%s%s",tdir.c_str(),dirs[dd]->d_name);
00358 printf("Current directory: %s\n", dir);
00359
00360
00361 nlim = scandir(dir,&lims,getleft,alphasort);
00362 printf("Found %d left images\n", nlim);
00363 printf("%s\n",lims[0]->d_name);
00364
00365 nrim = scandir(dir,&rims,getright,alphasort);
00366 printf("Found %d right images\n", nrim);
00367 printf("%s\n",rims[0]->d_name);
00368
00369 if (nlim != nrim)
00370 {
00371 printf("Number of left/right images does not match: %d vs. %d\n", nlim, nrim);
00372 exit(0);
00373 }
00374
00375
00376
00377
00378 for (int ii=0; ii<nlim; iter++, ii++)
00379 {
00380
00381 char fn[2048];
00382 sprintf(fn,"%s/%s",dir,lims[ii]->d_name);
00383 cv::Mat image1 = cv::imread(fn,0);
00384 sprintf(fn,"%s/%s",dir,rims[ii]->d_name);
00385 cv::Mat image1r = cv::imread(fn,0);
00386
00387 #if 0
00388 printf("Image size: %d x %d\n", image1.cols, image1.rows);
00389 printf("Image size: %d x %d\n", image1r.cols, image1r.rows);
00390 #endif
00391
00392 if (image1.rows == 0 || image1r.rows == 0)
00393 exit(0);
00394
00395
00396 bool is_keyframe = vslam.addFrame(camp, image1, image1r);
00397
00398 if (is_keyframe)
00399 {
00401 int n = vslam.sba_.nodes.size();
00402 int np = vslam.sba_.tracks.size();
00403
00404
00405 cout << "drawing with " << n << " nodes and " << np << " points..." << endl << endl;
00406 #if 1
00407 if (n%2 == 0)
00408 drawgraph(vslam.sba_, cam_pub, pt_pub, 1);
00409 #endif
00410
00411
00412 if (n > 10 && n%500 == 0)
00413 {
00414 char fn[1024];
00415 sprintf(fn,"newcollege%d.g2o", n);
00416 sba::writeGraphFile(fn,vslam.sba_);
00417 sprintf(fn,"newcollege%dm.g2o", n);
00418 sba::writeGraphFile(fn,vslam.sba_,true);
00419
00420
00421
00422 }
00423
00424 #if 1
00425 int nnsba = 10;
00426 if (n > 4 && n%nnsba == 0)
00427 {
00428 cout << "Running large SBA" << endl;
00429 vslam.refine();
00430 }
00431 #endif
00432 }
00433
00434 #ifdef VISMATCH
00435
00436 if (1)
00437 {
00438 drawVOtracks(image1, vslam.vo_.frames, display);
00439 cv::imshow(window_name, display);
00440 cv::waitKey(10);
00441 }
00442 #endif
00443
00444 if (!nh.ok())
00445 return 0;
00446 }
00447 }
00448 return 0;
00449 }