geometric_hash.h
Go to the documentation of this file.
00001 /*
00002  *  geometric_hash.h
00003  *  edge_matcher
00004  *
00005  *  Created by Victor  Eruhimov on 11/1/09.
00006  *  Copyright 2009 Argus Corp. All rights reserved.
00007  *
00008  */
00009 
00010 #if !defined(_GEOMETRIC_HASH)
00011 #define _GEOMETRIC_HASH
00012 
00013 #include <math.h>
00014 
00015 #include <cv.h>
00016 #include <cv.hpp>
00017 
00018 #include <vector>
00019 #include <map>
00020 #include <list>
00021 #include <utility>
00022 
00023 #include "one_way_descriptor_base.h"
00024 #include "features.h"
00025 
00026 /*class AffineBasis
00027 {
00028 public:
00029     virtual cv::Point2f getOrigin() const = 0;
00030     virtual void getBasis(cv::Point2f* basis) const = 0;
00031     virtual cv::Point2f getCoords(cv::Point2f point) const = 0;
00032 };*/
00033 
00035 /*{
00036     return sqrt(float(p.x*p.x) + p.y*p.y);
00037 //}*/
00038 
00039 #define PI 3.1415926
00040 
00041 class AffineBasis
00042 {
00043 protected:
00044     int model_id;
00045     cv::Point2f origin;
00046     cv::Point2f basis[2];
00047 
00048 public:
00049     AffineBasis(cv::Point2f _origin, const cv::Point2f* _basis, int _model_id)
00050     {
00051         origin = _origin;
00052         basis[0] = _basis[0];
00053         basis[1] = _basis[1];
00054         model_id = _model_id;
00055     };
00056     AffineBasis(cv::Point2f _origin, cv::Point2f point1, cv::Point2f point2, int _model_id)
00057     {
00058         origin = _origin;
00059         basis[0] = point1 - origin;
00060         basis[1] = point2 - origin;
00061         model_id = _model_id;
00062     };
00063 
00064     ~AffineBasis() {};
00065 
00066     cv::Point2f getOrigin() const {return origin;};
00067     void getBasis(cv::Point2f* _basis) const
00068     {
00069         _basis[0] = basis[0];
00070         _basis[1] = basis[1];
00071     };
00072 
00073     cv::Point2f getCoords(cv::Point2f point) const;
00074     cv::Point2f getPoint(cv::Point2f coords) const;
00075 
00076     int getModelID() const {return model_id;};
00077 
00078     float getAngle() const {return acos(basis[0].dot(basis[1])/(length(basis[0])*length(basis[1])));};
00079 };
00080 
00081 typedef int ModelBasisID;
00082 
00083 class GeometricHash
00084 {
00085 protected:
00086     cv::Size size;
00087     cv::Point2f range[2]; // 0 is minimum, 1 is maximum
00088     std::vector<AffineBasis> bases;
00089     std::vector<std::list<ModelBasisID> > hash;
00090     std::list<ModelBasisID> empty_list;
00091 
00092     int getBin(cv::Point2f coords) const;
00093 
00094 public:
00095     GeometricHash(cv::Size _size, cv::Point2f range_min, cv::Point2f range_max);
00096     ModelBasisID addBasis(const AffineBasis& basis);
00097     const std::vector<AffineBasis>& getBases() const;
00098     void addEntry(const ModelBasisID& basisID, cv::Point2f point);
00099     const std::list<ModelBasisID>& getEntries(cv::Point2f point) const;
00100 
00101 };
00102 
00103 class GeometricHash3D
00104 {
00105 protected:
00106     cv::Point3i size;
00107     cv::Point3f range[2]; // 0 is minimum, 1 is maximum
00108     std::vector<AffineBasis> bases;
00109     std::vector<std::list<ModelBasisID> > hash;
00110     std::list<ModelBasisID> empty_list;
00111 
00112     int getBin(cv::Point3f coords) const;
00113 
00114 public:
00115     GeometricHash3D(cv::Point3i _size, const cv::Point3f* _range);
00116     ModelBasisID addBasis(const AffineBasis& basis);
00117     const std::vector<AffineBasis>& getBases() const;
00118     void addEntry(const ModelBasisID& basisID, CvSeq* seq, int idx_offset, int idx_point);
00119     const std::list<ModelBasisID>& getEntries(cv::Point3f point) const;
00120 };
00121 
00122 class EdgeMatcher
00123 {
00124 protected:
00125     std::vector<CvSeq*> edges;
00126     GeometricHash3D hash;
00127     static const float min_angle;
00128 
00129 public:
00130     typedef std::map<int,std::pair<int,int> > ModelVotes;
00131 
00132     EdgeMatcher(cv::Point3f _size, const cv::Point3f* _range) : hash(_size, _range) {};
00133 
00134     int addModel(CvSeq* edge);
00135     void addModelBasis(CvSeq* edge, int idx_origin, const AffineBasis& basis);
00136     AffineBasis match(CvSeq* edge, std::map<int,std::pair<int,int> >& votes) const;
00137     void aggregateVotes(const std::vector<int>& basis_votes, std::map<int,std::pair<int,int> >& agg_votes) const;
00138     void matchBasis(CvSeq* edge, const AffineBasis& basis, int idx_origin, std::vector<int>& votes) const;
00139     CvSeq* getModel(int modelID) {return edges[modelID];};
00140     CvSeq* getModelByBasisID(int basis_id) const {return edges[hash.getBases()[basis_id].getModelID()];};
00141     const AffineBasis& getBasis(int basis_id) const {return hash.getBases()[basis_id];};
00142     const GeometricHash3D& getHash() const {return hash;};
00143 
00144     static bool votes_greater(const std::pair<int,std::pair<int,int> >& elem1, const std::pair<int,std::pair<int,int> >& elem2)
00145     {
00146         return elem1.second.second < elem2.second.second;
00147     }
00148 };
00149 
00150 AffineBasis getPointEdgeBasis(cv::Point2f point, CvSeq* edge, int i, int modelID);
00151 float fitEdges(CvSeq* model, const AffineBasis& model_basis, CvSeq* test, const AffineBasis& test_basis);
00152 float fitEdgesSym(CvSeq* model_seq, const AffineBasis& model_basis, CvSeq* test_seq, const AffineBasis& test_basis);
00153 float fitPoints(const std::vector<cv::Point2f>& set1, const std::vector<cv::Point2f>& set2);
00154 float fitPointsSym(const std::vector<cv::Point2f>& set1, const std::vector<cv::Point2f>& set2);
00155 CvSeq* mapContour(CvSeq* contour, AffineBasis src, AffineBasis dst, CvMemStorage* storage);
00156 void mapPoints(const std::vector<cv::Point2f>& src, const AffineBasis& src_basis, const AffineBasis& dst_basis, std::vector<cv::Point2f>& dst);
00157 void mapPoints(const std::vector<KeyPointEx>& src, const AffineBasis& src_basis, const AffineBasis& dst_basis, std::vector<KeyPointEx>& dst);
00158 
00159 class PointEdgeMatcher : public EdgeMatcher
00160 {
00161 public:
00162     typedef std::pair<cv::Point2f,CvSeq*> Model;
00163 
00164 private:
00165     std::vector<Model> models;
00166 
00167 public:
00168     PointEdgeMatcher(cv::Point3f _size, const cv::Point3f* _range) : EdgeMatcher(_size, _range) {};
00169 
00170     int addModel(const Model& model);
00171     const Model& getModel(int model_id) {return models[model_id];};
00172     const Model& getModelByBasisID(int basis_id) const {return models[hash.getBases()[basis_id].getModelID()];};
00173     AffineBasis match(cv::Point2f point, CvSeq* edge, std::map<int,std::pair<int, int> >& votes) const;
00174 };
00175 
00176 float calcAffineSeqDist(const AffineBasis& basis, CvSeq* seq, int idx1, int idx2, int is_mapped = 0);
00177 
00178 class PointMatcher
00179 {
00180 public:
00181     struct PointMatcherParams
00182     {
00183         PointMatcherParams(float _min_angle = 0.5f, float _max_basis_length = 100.0f, float _min_basis_length = 10.0f,
00184             int _min_hash_votes = 3, float _min_validated_votes = 5.0f, float _min_distortion_ratio = 0.8f) : 
00185             min_angle(_min_angle), max_basis_length(_max_basis_length), min_basis_length(_min_basis_length), 
00186             min_hash_votes(_min_hash_votes), min_validated_votes(_min_validated_votes), min_distortion_ratio(_min_distortion_ratio) {};
00187 
00188         float min_angle;
00189         float max_basis_length;
00190         float min_basis_length;
00191         int min_hash_votes;
00192         float min_validated_votes;
00193         float min_distortion_ratio;
00194     };
00195 
00196 protected:
00197     GeometricHash hash;
00198     std::vector<KeyPointEx> template_points;
00199     PointMatcherParams params;
00200 
00201 public:
00202     typedef std::map<int,std::pair<int,int> > ModelVotes;
00203 
00204     PointMatcher(cv::Size _size, cv::Point2f range_min, cv::Point2f range_max,
00205         PointMatcher::PointMatcherParams _params = PointMatcher::PointMatcherParams()) : hash(_size, range_min, range_max), params(_params) {};
00206 
00207     int addModel(const std::vector<KeyPointEx>& points);
00208     void addModelBasis(const std::vector<KeyPointEx>& points, const AffineBasis& basis);
00209     int match(const std::vector<KeyPointEx>& points, std::vector<float>& votes,
00210                             std::vector<std::pair<AffineBasis,AffineBasis> >& matched_bases) const;
00211     void matchBasis(const std::vector<KeyPointEx>& points, const AffineBasis& basis, std::vector<int>& votes) const;
00212     const AffineBasis& getBasis(int basis_id) const {return hash.getBases()[basis_id];};
00213     const GeometricHash& getHash() const {return hash;};
00214     const std::vector<KeyPointEx>& getTemplatePoints() const {return template_points;};
00215 };
00216 
00217 float validatePointMatch(const std::vector<KeyPointEx>& set1, const AffineBasis& basis1,
00218                          const std::vector<KeyPointEx>& set2, const AffineBasis& basis2);
00219 
00220 void getProximityPoints(const std::vector<KeyPointEx>& points, KeyPointEx point, float max_dist, std::vector<int>& indices);
00221 void findClosestPoint(const std::vector<KeyPointEx>& guess, const std::vector<KeyPointEx>& candidates, std::vector<KeyPointEx>& output, std::vector<bool>& is_detected, float max_dist);
00222 double affineDistortionRatio(const AffineBasis& basis1, const AffineBasis& basis2);
00223 
00224 
00225 #endif //_GEOMETRIC_HASH


outlet_pose_estimation
Author(s): Patrick Mihelich
autogenerated on Thu Nov 28 2013 11:46:23