ndt_feature_viewer.cc
Go to the documentation of this file.
00001 // Visualizer of feature f2f registration.
00002 #include <iostream>
00003 #include <boost/thread/thread.hpp>
00004 #include <boost/program_options.hpp>
00005 
00006 #define DO_DEBUG_PROC
00007 
00008 #include <ndt_feature_reg/ndt_frame.h>
00009 #include <ndt_feature_reg/ndt_frame_proc.h>
00010 #include <ndt_feature_reg/ndt_frame_viewer.h>
00011 
00012 #include <ndt_map/depth_camera.h>
00013 #include <ndt_registration/ndt_matcher_d2d_feature.h>
00014 #include <ndt_map/pointcloud_utils.h>
00015 
00016 #include <cv.h>
00017 #include <highgui.h>
00018 
00019 #include <pcl/visualization/pcl_visualizer.h>
00020 #include <pcl/io/io.h>
00021 #include <pcl/io/pcd_io.h>
00022 #include <pcl/common/transforms.h>
00023 
00024 using namespace ndt_feature_reg;
00025 using namespace pcl;
00026 using namespace cv;
00027 using namespace std;
00028 using namespace lslgeneric;
00029 namespace po = boost::program_options;
00030 
00031 int main(int argc, char** argv)
00032 {
00033     cout << "--------------------------------------------------" << endl;
00034     cout << "Small test program of the frame matching between 2" << endl;
00035     cout << "pair of depth + std (RGB) images. Each image pair " << endl;
00036     cout << "is assumed to have 1-1 correspondance, meaning    " << endl;
00037     cout << "that for each pixel in the std image we have the  " << endl;
00038     cout << "corresponding depth / disparity pixel at the same " << endl;
00039     cout << "location in the depth image.                      " << endl;
00040     cout << "--------------------------------------------------" << endl;
00041 
00042     string std1_name, depth1_name, std2_name, depth2_name, pc1_name, pc2_name;
00043     double scale, max_inldist_xy, max_inldist_z;
00044     int nb_ransac;
00045     int support_size;
00046     double maxVar;
00047 
00048     po::options_description desc("Allowed options");
00049     desc.add_options()
00050     ("help", "produce help message")
00051     ("debug", "print debug output")
00052     ("visualize", "visualize the output")
00053     ("depth1", po::value<string>(&depth1_name), "first depth image")
00054     ("depth2", po::value<string>(&depth2_name), "second depth image")
00055     ("std1", po::value<string>(&std1_name), "first standard image")
00056     ("std2", po::value<string>(&std2_name), "second standard image")
00057 //        ("pc1", po::value<string>(&pc1_name), "first pointcloud")
00058 //        ("pc2", po::value<string>(&pc2_name), "second pointcloud")
00059     ("scale", po::value<double>(&scale)->default_value(0.0002), "depth scale (depth = scale * pixel value)")
00060     ("max_inldist_xy", po::value<double>(&max_inldist_xy)->default_value(0.1), "max inlier distance in xy related to the camera plane (in meters)")
00061     ("max_inldist_z", po::value<double>(&max_inldist_z)->default_value(0.1), "max inlier distance in z - depth (in meters)")
00062     ("nb_ransac", po::value<int>(&nb_ransac)->default_value(100), "max number of RANSAC iterations")
00063     ("ident", "don't use the pe matching as input to the registration")
00064 //        ("nb_points", po::value<int>(&nb_points)->default_value(21), "number of surrounding points")
00065     ("support_size", po::value<int>(&support_size)->default_value(5), "width of patch around each feature in pixels")
00066     ("maxVar", po::value<double>(&maxVar)->default_value(0.05), "max variance of ndt cells")
00067     ("skip_matching", "skip the matching step");
00068     ;
00069 
00070     po::variables_map vm;
00071     po::store(po::parse_command_line(argc, argv, desc), vm);
00072     po::notify(vm);
00073 
00074     if (vm.count("help"))
00075     {
00076         cout << desc << "\n";
00077         return 1;
00078     }
00079     bool debug = vm.count("debug");
00080     bool visualize = vm.count("visualize");
00081     bool ident = vm.count("ident");
00082     bool skip_matching = vm.count("skip_matching");
00083     if (debug)
00084         cout << "scale : " << scale << endl;
00085     if (!(vm.count("depth1") && vm.count("depth2")))
00086     {
00087         cout << "Check depth data input - quitting\n";
00088         return 1;
00089     }
00090 
00091     // TODO - this are the values from the Freiburg 1 camera.
00092     double fx = 517.3;
00093     double fy = 516.5;
00094     double cx = 318.6;
00095     double cy = 255.3;
00096     std::vector<double> dist(5);
00097     dist[0] = 0.2624;
00098     dist[1] = -0.9531;
00099     dist[2] = -0.0054;
00100     dist[3] = 0.0026;
00101     dist[4] = 1.1633;
00102     double ds = 1.035; // Depth scaling factor.
00103     lslgeneric::DepthCamera<pcl::PointXYZ> cameraParams;
00104 
00105     // Load the files.
00106     //pcl::PCDReader reader;
00107     double t0,t1,t2,t3;
00108 
00109     if (debug)
00110         cout << "loading imgs : " << std1_name << " and " << std2_name << endl;
00111 
00112     size_t support = support_size;
00113 
00114     NDTFrame *frame1 = new NDTFrame();
00115     NDTFrame *frame2 = new NDTFrame();
00116     frame1->img = cv::imread(std1_name, 0);
00117     frame2->img = cv::imread(std2_name, 0);
00118     frame1->supportSize = support;
00119     frame2->supportSize = support;
00120     frame1->maxVar = maxVar;
00121     frame2->maxVar = maxVar;
00122 
00123     /*     cout<<"img channels "<<frame1.img.channels()<<endl;
00124          cout<<"img depth "<<frame1.img.depth()<<endl;
00125          cout<<"img channels "<<frame2.img.channels()<<endl;
00126     */
00127     NDTFrameProc proc(nb_ransac, max_inldist_xy, max_inldist_z);
00128 
00129     if (debug)
00130         cout << "loading depth img : " << depth1_name << " and " << depth2_name << endl;
00131 
00132     t0 = getDoubleTime();
00133     frame1->depth_img = cv::imread(depth1_name, CV_LOAD_IMAGE_ANYDEPTH); // CV_LOAD_IMAGE_ANYDEPTH is important to load the 16bits image
00134     frame2->depth_img = cv::imread(depth2_name, CV_LOAD_IMAGE_ANYDEPTH);
00135     t1 = getDoubleTime();
00136 
00137     bool isFloat = (frame1->depth_img.depth() == CV_32F);
00138     cameraParams = DepthCamera<pcl::PointXYZ>(fx,fy,cx,cy,dist,ds*scale,isFloat);
00139     cameraParams.setupDepthPointCloudLookUpTable(frame1->depth_img.size());
00140 
00141     frame1->cameraParams = cameraParams;
00142     frame2->cameraParams = cameraParams;
00143     t2 = getDoubleTime();
00144     cout << "load: " << t1-t0 << endl;
00145     cout << "lookup: " << t2-t1 << endl;
00146 
00147     t1 = getDoubleTime();
00148     proc.addFrameIncremental(frame1,skip_matching);
00149     proc.addFrameIncremental(frame2,skip_matching);
00150     t2 = getDoubleTime();
00151     cout<<"add frames: "<<t2-t1 <<endl;
00152 
00153     /*
00154      proc.addFrame(frame1);
00155      proc.addFrame(frame2);
00156      t1 = getDoubleTime();
00157      proc.processFrames(skip_matching);
00158      t2 = getDoubleTime();
00159      cout<<"process per frame: "<<(t2-t1)/2<<endl;
00160 
00161      */
00162     NDTFrameViewer viewer(&proc);
00163 
00164     viewer.showFeaturePC();
00165     viewer.showMatches(proc.pe.inliers);
00166 
00167     while (!viewer.wasStopped ())
00168     {
00169         viewer.spinOnce();
00170         boost::this_thread::sleep (boost::posix_time::microseconds (100000));
00171     }
00172     return 0;
00173 
00174     /*
00175     proc.detectKeypoints(frame1);
00176     proc.detectKeypoints(frame2);
00177 
00178     t1 = getDoubleTime();
00179     proc.calcDescriptors(frame1);
00180     proc.calcDescriptors(frame2);
00181     t2 = getDoubleTime();
00182     cout <<" calc descriptors: "<<t2-t1<<endl;
00183 
00184     if (debug)
00185           cout << "Computing NDT ..." << endl;
00186     t1 = getDoubleTime();
00187     frame1.computeNDT();
00188     frame2.computeNDT();
00189     t2 = getDoubleTime();
00190     cout << "compute NDT : " << t2 - t1 << endl;
00191     if (debug)
00192           cout << " - done." << endl;
00193 
00194     NDTFrameViewer<pcl::PointXYZ> viewer(&frame1, &frame2, proc);
00195 
00196     // Do the feature matching
00197     t1 = getDoubleTime();
00198     PoseEstimator<pcl::PointXYZ,pcl::PointXYZ> pe(nb_ransac, max_inldist_xy, max_inldist_z);
00199     frame1.assignPts();
00200     frame2.assignPts();
00201 
00202     pe.estimate(frame1, frame2);
00203     t2 = getDoubleTime();
00204     cout<<" pose estimation: "<<t2-t1<<endl;
00205 
00206     if (visualize)
00207     {
00208      cv::Mat display;
00209      drawMatches(frame1.img, frame1.kpts, frame2.img, frame2.kpts, pe.inliers, display);
00210      const std::string window_name = "matches";
00211      cv::namedWindow(window_name,0);
00212      cv::imshow(window_name, display);
00213      cv::waitKey(0);
00214     }
00215 
00216     #if 0
00217     // -------------------------- only the pe --------------------------
00218     pcl::PointCloud<pcl::PointXYZ> tmp;
00219     pcl::transformPointCloud<pcl::PointXYZ> (frame2.pc, tmp, pe.getTransform());
00220     frame2.pc.swap(tmp);
00221     // -----------------------------------------------------------------
00222     #endif
00223 
00224     // View the pe estimate...
00225     Eigen::Matrix3d rot = pe.rot;
00226     Eigen::Vector3d trans = pe.trans;
00227     Eigen::Affine3d transl_transform = (Eigen::Affine3d)Eigen::Translation3d(trans);
00228     Eigen::Affine3d rot_transform = (Eigen::Affine3d)Eigen::Matrix3d(rot);
00229     Eigen::Transform<double,3,Eigen::Affine,Eigen::ColMajor> transform = transl_transform*rot_transform;
00230 
00231     std::vector<std::pair<int,int> > corr = convertMatches(pe.inliers);
00232     NDTMatcherFeatureD2D<pcl::PointXYZ,pcl::PointXYZ> matcher_feat(corr);
00233     cout << "Matching ..." << endl;
00234     t1 = getDoubleTime();
00235     if (ident)
00236      transform.setIdentity();
00237     if (!skip_matching)
00238      matcher_feat.match(frame1.ndt_map, frame2.ndt_map, transform, true); //true = use initial guess
00239     t2 = getDoubleTime();
00240     cout << "Matching ... - done" << endl;
00241     std::cout << "ndt2ndt matching : " << t2 - t1 << std::endl;
00242 
00243     transformPointCloudInPlace(transform, frame2.pc);
00244 
00245     viewer.showFeaturePC();
00246     viewer.showMatches(pe.inliers);
00247 
00248     while (!viewer.wasStopped ())
00249     {
00250      viewer.spinOnce();
00251      boost::this_thread::sleep (boost::posix_time::microseconds (100000));
00252     }
00253     return 0;
00254     */
00255 }


ndt_feature_reg
Author(s): Henrik Andreasson, Todor Stoyanov, Jari Saarinen
autogenerated on Wed Aug 26 2015 15:25:07