po_comparison.cpp
Go to the documentation of this file.
00001 /*
00002  * po_comparison.cpp
00003  *
00004  *  Created on: Mar 14, 2011
00005  *      Author: alex
00006  */
00007 #include <ros/ros.h>
00008 #include <visualization_msgs/Marker.h>
00009 #include <visualization_msgs/MarkerArray.h>
00010 #include <geometry_msgs/Point.h>
00011 
00012 #include <vslam_system/vslam.h>
00013 #include <posest/pe3d.h>
00014 #include <posest/peh.h>
00015 #include <sba/sba.h>
00016 #include <sba/sba_file_io.h>
00017 #include <frame_common/frame.h>
00018 #include <boost/shared_ptr.hpp>
00019 #include <cstdio>
00020 #include <fstream>
00021 #include <dirent.h>
00022 #include <fnmatch.h>
00023 
00024 #include <posest/pe3d.h>
00025 #include <opencv2/contrib/contrib.hpp>
00026 #include <opencv2/features2d/features2d.hpp>
00027 #include <opencv2/highgui/highgui.hpp>
00028 #include <opencv2/legacy/legacy.hpp>
00029 
00030 using namespace std;
00031 using namespace sba;
00032 using namespace frame_common;
00033 using namespace cv;
00034 using namespace vslam;
00035 
00036 // Names of left and right files in directory (with wildcards)
00037 char *lreg, *rreg, *dreg;
00038 
00039 // Filters for scandir
00040 int getleft(struct dirent const *entry)
00041 {
00042   if (!fnmatch(lreg, entry->d_name, 0))
00043     return 1;
00044   return 0;
00045 }
00046 
00047 int getright(struct dirent const *entry)
00048 {
00049   if (!fnmatch(rreg, entry->d_name, 0))
00050     return 1;
00051   return 0;
00052 }
00053 
00054 int getidir(struct dirent const *entry)
00055 {
00056   if (!fnmatch(dreg, entry->d_name, 0))
00057     return 1;
00058   return 0;
00059 }
00060 
00061 
00062 void project3dPoint(const Point3f& point, const Mat& rvec, const Mat& tvec, Point3f& modif_point)
00063 {
00064   Mat R(3, 3, CV_64FC1);
00065   Rodrigues(rvec, R);
00066   modif_point.x = R.at<double> (0, 0) * point.x + R.at<double> (0, 1) * point.y + R.at<double> (0, 2)
00067      * point.z + tvec.at<double> (0, 0);
00068   modif_point.y = R.at<double> (1, 0) * point.x + R.at<double> (1, 1) * point.y + R.at<double> (1, 2)
00069      * point.z + tvec.at<double> (1, 0);
00070   modif_point.z = R.at<double> (2, 0) * point.x + R.at<double> (2, 1) * point.y + R.at<double> (2, 2)
00071      * point.z + tvec.at<double> (2, 0);
00072 }
00073 
00074 
00075 void invert(Mat& rvec, Mat& tvec)
00076 {
00077   Mat R, RInv;
00078   Rodrigues(rvec,R);
00079   RInv = R.inv();
00080   Rodrigues(RInv, rvec);
00081   tvec = RInv*tvec;
00082   tvec = tvec*(-1);
00083 }
00084 
00085 int main(int argc, char** argv)
00086 {
00087   if (argc < 5)
00088   {
00089     printf("Args are: <param file> <image dir> <left image file template> <right image file template>\n");
00090     exit(0);
00091   }
00092 
00093   // get camera parameters, in the form: fx fy cx cy tx
00094   fstream fstr;
00095   fstr.open(argv[1], fstream::in);
00096   if (!fstr.is_open())
00097   {
00098     printf("Can't open camera file %s\n", argv[1]);
00099     exit(0);
00100   }
00101   CamParams camp;
00102   fstr >> camp.fx;
00103   fstr >> camp.fy;
00104   fstr >> camp.cx;
00105   fstr >> camp.cy;
00106   fstr >> camp.tx;
00107   Mat intrinsic = Mat::zeros(Size(3, 3), CV_64F);
00108   intrinsic.at<double>(0, 0) = camp.fx;
00109   intrinsic.at<double>(0, 2) = camp.cx;
00110   intrinsic.at<double>(1, 1) = camp.fy;
00111   intrinsic.at<double>(1, 2) = camp.cy;
00112   intrinsic.at<double>(2, 2) = 1.0;
00113 
00114   cout << "Cam params: " << camp.fx << " " << camp.fy << " " << camp.cx << " " << camp.cy << " " << camp.tx << endl;
00115 
00116   // set up directories
00117   struct dirent **lims, **rims, **dirs;
00118   int nlim, nrim, ndirs;
00119   string dname = argv[2];
00120   if (!dname.compare(dname.size() - 1, 1, "/")) // see if slash at end
00121     dname.erase(dname.size() - 1);
00122 
00123   string dirfn = dname.substr(dname.rfind("/") + 1);
00124   string tdir = dname.substr(0, dname.rfind("/") + 1);
00125   cout << "Top directory is " << tdir << endl;
00126   cout << "Search directory name is " << dirfn << endl;
00127   dreg = (char *)dirfn.c_str();
00128 
00129   ndirs = scandir(tdir.c_str(), &dirs, getidir, alphasort);
00130   printf("Found %d directories\n", ndirs);
00131   printf("%s\n", dirs[0]->d_name);
00132 
00133   const std::string window_name = "matches";
00134   cv::namedWindow(window_name, 0);
00135   cv::Mat display;
00136 
00137   int iter = 0;
00138   lreg = argv[3];
00139   rreg = argv[4];
00140 
00141   // loop over directories
00142   for (int dd = 0; dd < ndirs; dd++)
00143   {
00144     char dir[2048];
00145     sprintf(dir, "%s%s", tdir.c_str(), dirs[dd]->d_name);
00146     printf("Current directory: %s\n", dir);
00147 
00148     // get left/right image file names, sorted
00149     nlim = scandir(dir, &lims, getleft, alphasort);
00150     printf("Found %d left images\n", nlim);
00151     printf("%s\n", lims[0]->d_name);
00152 
00153     nrim = scandir(dir, &rims, getright, alphasort);
00154     printf("Found %d right images\n", nrim);
00155     printf("%s\n", rims[0]->d_name);
00156 
00157     if (nlim != nrim)
00158     {
00159       printf("Number of left/right images does not match: %d vs. %d\n", nlim, nrim);
00160       exit(0);
00161     }
00162 
00163     frame_common::Frame prevFrame;
00164     frame_common::FrameProc frameProcessor(5);
00165     typedef cv::CalonderDescriptorExtractor<float> Calonder;
00166     frameProcessor.setFrameDescriptor(new Calonder(argv[7]));
00167 
00168     pe::HowardStereoMatcher matcherError(0.01, 17);
00169 
00170     pe::PoseEstimator3d po(5000, true, 10.0, 3.0, 3.0);
00171     pe::PoseEstimatorH poh(5000, true, 10.0, 3.0, 3.0, 0.1, 40, 13);
00172 
00173     po.wx = poh.wx = 92;
00174     po.wy = poh.wy = 48;
00175 
00176     cv::TickMeter poMeter, howMeter;
00177 
00178     // loop over each stereo pair, adding it to the system
00179     for (int ii = 0; ii < nlim; iter++, ii++)
00180     {
00181       bool matched = false;
00182       // Load images
00183       char fn[2048];
00184       sprintf(fn, "%s/%s", dir, lims[ii]->d_name);
00185       printf("%s\n", fn);
00186       cv::Mat image1 = cv::imread(fn, 0);
00187       sprintf(fn, "%s/%s", dir, rims[ii]->d_name);
00188       printf("%s\n", fn);
00189       cv::Mat image1r = cv::imread(fn, 0);
00190       if (image1.rows == 0 || image1r.rows == 0)
00191          exit(0);
00192 
00193       Mat im; image1.copyTo(im);
00194       //bilateralFilter(im, image1, -1, 1, 1);
00195       Mat imr; image1r.copyTo(imr);
00196       //bilateralFilter(imr, image1r, -1, 1, 1);
00197       frame_common::Frame frame;
00198       poMeter.start();
00199       howMeter.start();
00200       frameProcessor.setStereoFrame(frame, image1, image1r, 0, false);
00201       poMeter.stop();
00202       howMeter.stop();
00203       frame.setCamParams(camp);
00204       frame.frameId = ii;
00205 
00206       vector<DMatch> matchesError;
00207       vector<Point3f> opointsError;
00208       vector<Point2f> ipointsError;
00209       if (!prevFrame.img.empty())
00210       {
00211         display.create(prevFrame.img.rows, prevFrame.img.cols + frame.img.cols, CV_8UC3);
00212         cv::Mat left = display(cv::Rect(0, 0, prevFrame.img.cols, prevFrame.img.rows));
00213         cvtColor(prevFrame.img, left, CV_GRAY2BGR);
00214         cv::Mat right = display(cv::Rect(prevFrame.img.cols, 0, frame.img.cols, frame.img.rows));
00215         cvtColor(frame.img, right, CV_GRAY2BGR);
00216         for (size_t i = 0; i < prevFrame.kpts.size(); ++i)
00217         {
00218           cv::Point pt1 = prevFrame.kpts[i].pt;
00219           cv::circle(display, pt1, 3, Scalar(255));
00220         }
00221         for (size_t i = 0; i < frame.kpts.size(); ++i)
00222         {
00223           cv::Point pt1(frame.kpts[i].pt.x+prevFrame.img.cols,frame.kpts[i].pt.y);
00224           cv::circle(display, pt1, 3, Scalar(255));
00225         }
00226 
00227         howMeter.start();
00228         matched = poh.estimate(prevFrame, frame);
00229         cout << "Inliers = " << poh.inliers.size() << endl;
00230         howMeter.stop();
00231 
00232         cout << "Matcher error" << endl;
00233         Mat mask = cv::windowedMatchingMask(prevFrame.kpts, frame.kpts, 92, 48);
00234         vector<int> filteredInidices;
00235         matcherError.match(prevFrame, frame, matchesError, filteredInidices, mask);
00236         cout << "Matches error size = " << filteredInidices.size() << endl;
00237 
00238         if (matched)
00239         {
00240           for (size_t i = 0; i < poh.inliers.size(); ++i)
00241           {
00242             if (prevFrame.goodPts[poh.inliers[i].queryIdx] && frame.goodPts[poh.inliers[i].trainIdx])
00243             {
00244               cv::Point pt1(prevFrame.kpts[poh.inliers[i].queryIdx].pt.x,prevFrame.kpts[poh.inliers[i].queryIdx].pt.y);
00245               cv::Point pt2(frame.kpts[poh.inliers[i].trainIdx].pt.x+prevFrame.img.cols,frame.kpts[poh.inliers[i].trainIdx].pt.y);
00246               cv::line(display, pt1, pt2, Scalar(0, 255));
00247             }
00248           }
00249 
00250           cout << "Matches Error size = " << filteredInidices.size() << endl;
00251           for (size_t i = 0; i < filteredInidices.size(); ++i)
00252           {
00253             if (prevFrame.goodPts[matchesError[filteredInidices[i]].queryIdx] && frame.goodPts[matchesError[filteredInidices[i]].trainIdx])
00254             {
00255               ipointsError.push_back(frame.kpts[matchesError[filteredInidices[i]].trainIdx].pt);
00256               Eigen::Vector4d vec = prevFrame.pts[matchesError[filteredInidices[i]].queryIdx];
00257               Point3f op(vec(0), vec(1), vec(2));
00258               opointsError.push_back(op);
00259               //cv::line(display, frame.kpts[matchesError[filteredInidices[i]].trainIdx].pt, cv::Point(prevFrame.kpts[matchesError[filteredInidices[i]].queryIdx].pt.x+prevFrame.img.cols,
00260                 //                          prevFrame.kpts[matchesError[filteredInidices[i]].queryIdx].pt.y), Scalar(0, 255));
00261             }
00262           }
00263         }
00264       }
00265 
00266       if (matched /*&& opointsError.size()*/)
00267       {
00268         Mat R(3,3, CV_64F);
00269         for (int j=0; j<poh.rot.cols(); ++j)
00270           for (int i=0; i<poh.rot.rows(); ++i)
00271             R.at<double>(i, j) = poh.rot(i, j);
00272         Mat tvec(3, 1, CV_64F);
00273         for (int j=0; j<3; ++j)
00274           tvec.at<double>(0,j) = poh.trans(j);
00275         Mat rvec;
00276         Rodrigues(R, rvec);
00277         invert(rvec, tvec);
00278         vector<Point2f> projectedPoints;
00279         Mat distCoeffs = Mat::zeros(Size(1, 5), CV_64F);
00280         projectPoints(Mat(opointsError), rvec, tvec, intrinsic, distCoeffs, projectedPoints);
00281         float reprojectionError = 0;
00282         for (size_t pointInd = 0; pointInd < projectedPoints.size(); pointInd++)
00283         {
00284           float error = norm(projectedPoints[pointInd] - ipointsError[pointInd]);
00285           if (error > reprojectionError)
00286             reprojectionError = error;
00287         }
00288         cout << endl << "Howard pose estimator" << endl;
00289         cout << "Reprojection error = " << reprojectionError << endl;
00290         cout << "Inliers size = " << poh.inliers.size() << endl;
00291         Mat Rinv;
00292         Rodrigues(rvec, Rinv);
00293         cout << Rinv << endl << tvec << endl;
00294 
00295 
00296         poMeter.start();
00297         po.estimate(prevFrame, frame);
00298         poMeter.stop();
00299 //        for (size_t i = 0; i < po.matches.size(); ++i)
00300 //        {
00301 //           if (prevFrame.goodPts[po.matches[i].queryIdx] && frame.goodPts[po.matches[i].trainIdx])
00302 //           {
00303 //             cv::Point pt1(prevFrame.kpts[po.matches[i].queryIdx].pt.x,prevFrame.kpts[po.matches[i].queryIdx].pt.y);
00304 //             cv::Point pt2(frame.kpts[po.matches[i].trainIdx].pt.x+prevFrame.img.cols,frame.kpts[po.matches[i].trainIdx].pt.y);
00305 //             //cv::line(display, pt1, pt2, Scalar(0,0,255));
00306 //           }
00307 //        }
00308         Mat poR;
00309         R.copyTo(poR);
00310         for (int j=0; j<po.rot.cols(); ++j)
00311           for (int i=0; i<po.rot.rows(); ++i)
00312             poR.at<double>(i, j) = po.rot(i, j);
00313         Mat t;
00314         tvec.copyTo(t);
00315         for (int j=0; j<3; ++j)
00316           t.at<double>(0,j) = po.trans(j);
00317         Mat r;
00318         Rodrigues(poR, r);
00319         invert(r, t);
00320         projectPoints(Mat(opointsError), r, t, intrinsic, Mat::zeros(Size(1, 5), CV_64F), projectedPoints);
00321         float reprojectionError3d = 0;
00322         for (size_t pointInd = 0; pointInd < projectedPoints.size(); pointInd++)
00323         {
00324           float error = norm(projectedPoints[pointInd] - ipointsError[pointInd]);
00325           if (error > reprojectionError3d)
00326             reprojectionError3d = error;
00327         }
00328         cout << endl << "3d pose estimator" << endl;
00329         cout << "Reprojection error = " << reprojectionError3d << endl;
00330         cout << "Inliers size = " << po.inliers.size() << ", matches = " << po.matches.size() << endl;
00331         Mat RR;
00332         Rodrigues(r, RR);
00333         cout << RR << endl << t << endl;
00334 
00335         cout << "Differences:" << endl;
00336         Mat Rdiff = Rinv - RR;
00337         float rdiff = norm(Rdiff, NORM_INF);
00338         cout << Rdiff << endl;
00339         cout << "R diff = " << rdiff << endl;
00340         cout << "tdiff = " << norm(tvec-t, NORM_INF) << endl;
00341         ofstream f;
00342         f.open("statistic.txt", fstream::app);
00343         f << ii << " " << rdiff << " " <<  norm(tvec-t, NORM_INF) << " " <<  reprojectionError << " " << reprojectionError3d << " " << poh.inliers.size() << " " << po.inliers.size() << endl;
00344         f.close();
00345 
00346 
00347         cv::imshow(window_name, display);
00348         cout << "How time = " << howMeter.getTimeMilli() / (float)(ii+1) << endl;
00349         cout << "Po time = " << poMeter.getTimeMilli() / (float)(ii+1) << endl;
00350         char key;
00351         while (true)
00352         {
00353           key = cv::waitKey(1);
00354           if (key == 32)
00355           {
00356             break;
00357           }
00358           else if (key == 27)
00359             return -1;
00360         }
00361         //cv::waitKey(30);
00362 
00363       }
00364       prevFrame = frame;
00365     }
00366   }
00367   return 0;
00368 }
00369 
00370 


vslam_system
Author(s): Kurt Konolige, Patrick Mihelich, Helen Oleynikova
autogenerated on Thu Jan 2 2014 12:12:31