pe.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2009, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 
00036 #include <posest/pe.h>
00037 #include <sba/sba.h>
00038 #include <Eigen/SVD>
00039 #include <Eigen/LU>
00040 #include <iostream>
00041 
00042 
00043 using namespace Eigen;
00044 using namespace sba;
00045 using namespace frame_common;
00046 using namespace std;
00047 
00048 namespace pe
00049 {
00050   PoseEstimator::PoseEstimator(int NRansac, bool LMpolish, double mind,
00051                                    double maxidx, double maxidd) : testMode(false)
00052   {
00053     polish = LMpolish;
00054     numRansac = NRansac;
00055     minMatchDisp = mind;
00056     maxInlierXDist2 = maxidx*maxidx;
00057     maxInlierDDist2 = maxidd*maxidd;
00058     rot.setIdentity();
00059     trans.setZero();
00060     
00061     // matcher
00062     matcher = cv::Ptr<cv::DescriptorMatcher>(new cv::BFMatcher(cv::NORM_L2));
00063     wx = 92; wy = 48;
00064     windowed = true;
00065   }
00066 
00067 void PoseEstimator::matchFrames(const fc::Frame& f0, const fc::Frame& f1, std::vector<cv::DMatch>& fwd_matches)
00068   {
00069     cv::Mat mask;
00070     if (windowed)
00071       mask = cv::windowedMatchingMask(f0.kpts, f1.kpts, wx, wy);
00072 
00073     matcher->clear();
00074     matcher->match(f0.dtors, f1.dtors, fwd_matches, mask); 
00075   }
00076 
00077   //
00078   // find the best estimate for a geometrically-consistent match
00079   //   sets up frames internally using sparse stereo
00080   // NOTE: we do forward/reverse matching and save all unique matches
00081   //   sometimes forward works best, sometimes reverse
00082   // uses the SVD procedure for aligning point clouds
00083   // final SVD polishing step
00084   //
00085 
00086   int PoseEstimator::estimate(const Frame &f0, const Frame &f1)
00087   {
00088     // set up match lists
00089     matches.clear();
00090     inliers.clear();
00091 
00092     // do forward and reverse matches
00093     std::vector<cv::DMatch> fwd_matches, rev_matches;
00094     matchFrames(f0, f1, fwd_matches);
00095     matchFrames(f1, f0, rev_matches);
00096     //printf("**** Forward matches: %d, reverse matches: %d ****\n", (int)fwd_matches.size(), (int)rev_matches.size());
00097 
00098     // combine unique matches into one list
00099     for (int i = 0; i < (int)fwd_matches.size(); ++i) {
00100       if (fwd_matches[i].trainIdx >= 0)
00101         matches.push_back( cv::DMatch(i, fwd_matches[i].trainIdx, 0.f) );
00102     }
00103     for (int i = 0; i < (int)rev_matches.size(); ++i) {
00104       if (rev_matches[i].trainIdx >= 0 && i != fwd_matches[rev_matches[i].trainIdx].trainIdx)
00105         matches.push_back( cv::DMatch(rev_matches[i].trainIdx, i, 0.f) );
00106     }
00107     //printf("**** Total unique matches: %d ****\n", (int)matches.size());
00108     
00109     // do it
00110     return estimate(f0, f1, matches);
00111   }
00112 
00113   void PoseEstimator::setMatcher(const cv::Ptr<cv::DescriptorMatcher>& new_matcher)
00114   {
00115     matcher = new_matcher;
00116   }
00117   
00118   void PoseEstimator::setTestMode(bool mode)
00119   {
00120     testMode = mode;
00121   };
00122 }


posest
Author(s): Kurt Konolige
autogenerated on Thu Jan 2 2014 12:12:17