00001
00010 #ifndef VSLAM_FEATURE_MATCHING_H_INCLUDED
00011 #define VSLAM_FEATURE_MATCHING_H_INCLUDED
00012
00013 #include "utils.h"
00014 #include <vector>
00015 #include <iostream>
00016 #include <opencv2/core/core.hpp>
00017 #include <opencv2/imgproc/imgproc.hpp>
00018 #include <opencv2/highgui/highgui.hpp>
00019 #include <opencv2/features2d/features2d.hpp>
00020 #include <opencv2/calib3d/calib3d.hpp>
00021 #include <memory>
00022 #include "model_estimation.h"
00023 #include "sfm_utils.h"
00024
00025
00033
00040
00041
00051 class CV_EXPORTS VirtualFeatureDetector : public cv::FeatureDetector {
00052 protected:
00053 IdxPoint2dVec points;
00054
00059 virtual void detectImpl( const cv::Mat& image, vector<cv::KeyPoint>& keypoints,
00060 const cv::Mat& mask) const;
00061 public:
00062 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00063
00065 VirtualFeatureDetector(const IdxPoint2dVec & _points) : points(_points) {}
00066 };
00067
00068
00069
00078 class CV_EXPORTS NoisyVirtualFeatureDetector : public VirtualFeatureDetector {
00079 protected:
00080 double sigma;
00081 public:
00082 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00083
00085 NoisyVirtualFeatureDetector(const IdxPoint2dVec & _points, double _sigma = 1.0) :
00086 VirtualFeatureDetector(_points), sigma(_sigma) {
00087 boost::normal_distribution<double> nd(0.0, sigma);
00088 boost::variate_generator<boost::mt19937&,
00089 boost::normal_distribution<> > var_nd(rng_mt19937, nd);
00090 for(vector<cv::KeyPoint>::size_type i = 0; i < points.size(); i++){
00091 points[i].second(0) += var_nd();
00092 points[i].second(1) += var_nd();
00093 }
00094 }
00095 };
00096
00097
00106 class VirtualDescriptorExtractor : public cv::DescriptorExtractor{
00107 public:
00108 virtual int descriptorSize() const { return 1; };
00109 virtual int descriptorType() const { return CV_32SC1; };
00110 protected:
00111 virtual void computeImpl(
00112 const cv::Mat& image, vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors ) const;
00113 };
00114
00115
00125 class VirtualDescriptorMatcher : public cv::DescriptorMatcher {
00126 private:
00127 double inlier_p;
00128 public:
00130 VirtualDescriptorMatcher(double _inlier_p=1.0){
00131 inlier_p=_inlier_p;
00132 }
00133
00135 virtual bool isMaskSupported() const {return false; };
00136
00142 virtual cv::Ptr<cv::DescriptorMatcher> clone( bool emptyTrainData=false ) const;
00143
00144 protected:
00145
00146
00147
00148 virtual void knnMatchImpl( const cv::Mat& queryDescriptors,
00149 vector<vector<cv::DMatch> >& matches, int k,
00150 const vector<cv::Mat>& masks=vector<cv::Mat>(), bool compactResult=false);
00151
00153 virtual void radiusMatchImpl( const cv::Mat& queryDescriptors,
00154 vector<vector<cv::DMatch> >& matches, float maxDistance,
00155 const vector<cv::Mat>& masks=vector<cv::Mat>(), bool compactResult=false);
00156 };
00158
00159
00161
00162 struct RobustFeatureMatcherStats{
00163 int tq;
00164 int qt;
00165 int ratio_tq;
00166 int ratio_qt;
00167 int symetry;
00168 int ransac;
00169 int filter;
00170
00171 bool success;
00172 operator bool(){
00173 return success;
00174 }
00175 };
00176
00177
00179
00186 class RobustFeatureMatcher {
00187 private:
00188 float ratio;
00189 int ransac_iterations;
00190 double ransac_model_min_inliers_ratio;
00191 double max_outlier_removal_error;
00192 shared_ptr<cv::DescriptorMatcher> matcher;
00193 shared_ptr<EMatrixModelBuilder> mbuilder;
00195 shared_ptr<EMatrixModelBuilder> maximal_data_mbuilder;
00196
00197 public:
00198 typedef shared_ptr<EMatrixModelBuilder> MBuilderPtr;
00199
00206 RobustFeatureMatcher(
00207 shared_ptr<cv::DescriptorMatcher> _matcher,
00208 MBuilderPtr _mbuilder = MBuilderPtr(),
00209 MBuilderPtr _maximal_data_mbuilder = MBuilderPtr()) :
00210 ratio(0.75f), ransac_iterations(100), ransac_model_min_inliers_ratio(0.10),
00211 max_outlier_removal_error((M_PI / 180.0)*1.0),
00212 matcher(_matcher), mbuilder(_mbuilder),
00213 maximal_data_mbuilder(_maximal_data_mbuilder) {}
00214
00216 void setRanSaCModelMinInliersRatio(int ratio) {
00217 ransac_model_min_inliers_ratio = ratio;
00218 }
00219
00221 void setRansacIterationsNum(int num) {
00222 ransac_iterations = num;
00223 }
00224
00226 void setRatio(float r) {
00227 ratio= r;
00228 }
00229
00231 void setMaxOutlierRemovalError(double _e){
00232 max_outlier_removal_error=_e;
00233 }
00234
00236
00239 void nonsymetricalMatch(
00240 const std::vector<cv::KeyPoint>& train_keypoints,
00241 const std::vector<cv::KeyPoint>& query_keypoints,
00242 const cv::Mat& train_descriptors,
00243 const cv::Mat& query_descriptors,
00244 RobustFeatureMatcherStats& stats,
00245 vector<cv::DMatch>& matches);
00246
00250 void symaetricalMatch(
00251 const std::vector<cv::KeyPoint>& keypoints_c1,
00252 const std::vector<cv::KeyPoint>& keypoints_c2,
00253 const cv::Mat& descriptors_c1,
00254 const cv::Mat& descriptors_c2,
00255 RobustFeatureMatcherStats& stats,
00256 std::vector<cv::DMatch>& sym_matches_c1c2);
00257
00264 bool ransacTest(
00265 const ImageMatchVec& matches_c1c2,
00266 const vector<cv::DMatch>& dmatches_c1c2,
00267 RobustFeatureMatcherStats& stats,
00268 vector<cv::DMatch>& filtered_matches_c1c2,
00269 SE3& T_c1c2);
00270
00276 void outlierRemoval(
00277 const SE3& T_c1c2,
00278 const ImageMatchVec& matches_c1c2,
00279 const vector<cv::DMatch>& dmatches_c1c2,
00280 RobustFeatureMatcherStats& stats,
00281 vector<cv::DMatch>& filtered_matches_c1c2);
00282 protected:
00283 void ratioTest(
00284 std::vector<std::vector<cv::DMatch> > & matches0,
00285 std::vector<cv::DMatch> & matches);
00286
00287
00288
00289 void symmetryTest(
00290 const vector<cv::DMatch>& matches_c1c2,
00291 const vector<cv::DMatch>& matches_c2c1,
00292 int keypoints2_size,
00293 vector<cv::DMatch>& symMatches);
00294 };
00300 #endif