00001
00002
00003 #ifndef GFM_GROUPSMATCHER_HPP_
00004 #define GFM_GROUPSMATCHER_HPP_
00005
00006 #include <boost/noncopyable.hpp>
00007 #include <boost/serialization/nvp.hpp>
00008 #include <boost/serialization/utility.hpp>
00009 #include <boost/serialization/version.hpp>
00010
00011 #include "geom/Rectangle.hpp"
00012 #include "kernel/jafarMacro.hpp"
00013 #include "jmath/jblas.hpp"
00014 #include "fdetect/Descriptor.hpp"
00015 #include "gfm/Matcher.hpp"
00016 #include "gfm/MatchingResult.hpp"
00017 #include "gfm/MatchFocus.hpp"
00018
00019 namespace jafar {
00020 namespace gfm {
00025 class GroupsMatcher : public Matcher {
00026 class Group;
00027 struct InterestFeatureInfo {
00028 inline InterestFeatureInfo(fdetect::InterestFeature* iP) : group(0), interestPoint(iP), matchPoint(0) {}
00029 Group* group;
00030 fdetect::InterestFeature* interestPoint;
00031 InterestFeatureInfo* matchPoint;
00032
00033 };
00034 typedef std::vector<InterestFeatureInfo*> vInterestFeatureInfos;
00035 typedef vInterestFeatureInfos::iterator vInterestFeatureInfos_it;
00036 typedef vInterestFeatureInfos::const_iterator vInterestFeatureInfos_cit;
00037 typedef std::map<double, InterestFeatureInfo*> double2interestPointInfo;
00038 typedef std::pair<InterestFeatureInfo*, InterestFeatureInfo*> pIpInfoIpInfo;
00039 typedef std::vector<pIpInfoIpInfo> vpIpInfoIpInfos;
00040 class Group {
00041 public:
00042 struct GroupMember {
00043 double distance, angle;
00044 InterestFeatureInfo* interestPointInfo;
00045
00046 };
00047 typedef std::vector<GroupMember> vGroupMembers;
00048 public:
00049 Group(double2interestPointInfo::iterator itbegin, double2interestPointInfo::iterator itend )
00050 {
00051
00052 for(double2interestPointInfo::iterator it = itbegin; it != itend; ++it)
00053 {
00054 GroupMember gm;
00055 gm.interestPointInfo = it->second;
00056 m_members.push_back(gm);
00057 }
00058
00059 jblas::vec2 origin = at(0).interestPointInfo->interestPoint->point();
00060 at(0).angle = 0.;
00061 at(0).distance = 0.;
00062 for(vGroupMembers::iterator it = begin() + 1; it != end(); ++it)
00063 {
00064 jblas::vec2 v = it->interestPointInfo->interestPoint->point() - origin;
00065 it->distance = ublas::norm_2(v);
00066 it->angle = atan2( v(0), v(1));
00067 }
00068 }
00069 inline GroupMember pivot() { return m_members[0]; }
00070 inline GroupMember& at(int index) { return m_members[index]; }
00071 inline vGroupMembers::iterator begin() { return m_members.begin(); }
00072 inline vGroupMembers::iterator end() { return m_members.end(); }
00073 inline unsigned int size() { return m_members.size(); }
00074 friend std::ostream& operator <<(std::ostream& s, const Group& p_);
00075 private:
00076 vGroupMembers m_members;
00077 };
00078 typedef std::vector<Group*> vGroups;
00079 typedef vGroups::iterator vGroups_it;
00080 typedef std::pair<Group::GroupMember, Group::GroupMember> pGrpMembGrMemb;
00081 typedef std::vector< pGrpMembGrMemb > vpGrpMembGrMembs;
00082 typedef vpGrpMembGrMembs::iterator vpGrpMembGrMembs_it;
00083 struct GroupMatchHypothesis {
00084 inline GroupMatchHypothesis() {}
00085 double matchingStrength;
00086 double sumRotation;
00087 double sumScale;
00088 double sumTranslationU;
00089 double sumTranslationV;
00090 double angleErr;
00091 int count;
00092 geom::RectangleDouble rect;
00093 GroupsMatcher::Group* groupref;
00094 GroupsMatcher::Group* groupmatch;
00095 vpGrpMembGrMembs individualmatches;
00096 };
00097 class GroupsMatchSourceInfo : public MatchSourceInfo, public boost::noncopyable {
00098 public:
00099 GroupsMatchSourceInfo( jafar::fdetect::DetectionResult points, GroupsMatcher* gm);
00100 ~GroupsMatchSourceInfo();
00101 virtual void reinit();
00102 inline vGroups groups() { return m_groups; }
00103 inline const vInterestFeatureInfos& pointsInfo() { return m_pointsInfo; }
00104 friend std::ostream& operator <<(std::ostream& s, const GroupsMatchSourceInfo& p_);
00105 private:
00106 vGroups m_groups;
00107 vInterestFeatureInfos m_pointsInfo;
00108 };
00109 public:
00131 GroupsMatcher(MatchFocus* matchFocus = 0,
00132 unsigned int groupsize = 12,
00133 unsigned int groupsizeseedsearch = 12,
00134 unsigned int minimalgroupsize = 2,
00135 double distance = 20.0,
00136 double closeness = 0.6,
00137 double weakcloseness = 0.6,
00138 double distinguability = 0.1,
00139 double rotationTolerance = 0.2,
00140 double scaleTolerance = 10000.0,
00141 double distanceTolerance = 10.0,
00142 double rotationDifferenceWithMedian = 0.4,
00143 double thresholdofenoughtgroup = 0. ) :
00144 m_matchFocus(matchFocus),
00145 m_groupSize(groupsize),
00146 m_groupSizeSeedSearch(groupsizeseedsearch),
00147 m_minimalGroupSize(minimalgroupsize),
00148 m_distance(distance),
00149 m_closeness(closeness),
00150 m_weakCloseness(weakcloseness),
00151 m_distinguability(distinguability),
00152 m_rotationTolerance(rotationTolerance),
00153 m_scaleTolerance(scaleTolerance),
00154 m_distanceTolerance(distanceTolerance),
00155 m_rotationDifferenceWithMedian(rotationDifferenceWithMedian),
00156 m_thresholdOfEnoughtGroup(thresholdofenoughtgroup),
00157 m_rotationTolerancePropagation(rotationTolerance)
00158 { }
00159 GroupsMatcher(GroupsMatcher const& gm);
00160 GroupsMatcher& operator=(GroupsMatcher const& m) { if (&m != this) *this = *(new GroupsMatcher(m)); return *this; }
00161 virtual ~GroupsMatcher();
00162 public:
00163 virtual jafar::gfm::MatchingResult computeMatch( MatchSourceInfo* refsourceinfo, MatchSourceInfo* matchsourceinfo);
00164 virtual MatchSourceInfo* initMatchSourceInfo( const jafar::fdetect::DetectionResult& pointsource );
00165 public:
00166 void setMatchFocus(MatchFocus* matchFocus);
00167 private:
00168 GroupMatchHypothesis* searchBestMatchFor( Group* groupref, vGroups& groupsmatch );
00169 void propageMatching( vInterestFeatureInfos& matches, InterestFeatureInfo* startingpoint , GroupMatchHypothesis* hypothesis);
00170 void initiatePropagation(vInterestFeatureInfos& matches, GroupMatchHypothesis* match, vpGrpMembGrMembs individualmatches);
00171 #ifndef SWIG
00172 JFR_DEFINE_PARAM_RO(MatchFocus*, matchFocus)
00176 JFR_DEFINE_PARAM_RW(unsigned int, groupSize, setGroupSize)
00177 JFR_DEFINE_PARAM_RW(unsigned int, groupSizeSeedSearch, setGroupSizeSeedSearch)
00181 JFR_DEFINE_PARAM_RW(unsigned int, minimalGroupSize, setMinimalGroupSize)
00185 JFR_DEFINE_PARAM_RW(double, distance, setDistance)
00189 JFR_DEFINE_PARAM_RW(double, closeness, setCloseness)
00190 JFR_DEFINE_PARAM_RW(double, weakCloseness, setWeakCloseness)
00191 JFR_DEFINE_PARAM_RW(double, distinguability, setDistinguability)
00192 JFR_DEFINE_PARAM_RW(double, rotationTolerance, setRotationTolerance)
00193 JFR_DEFINE_PARAM_RW(double, scaleTolerance, setScaleTolerance)
00194 JFR_DEFINE_PARAM_RW(double, distanceTolerance, setDistanceTolerance)
00195 JFR_DEFINE_PARAM_RW(double, rotationDifferenceWithMedian, setRotationDifferenceWithMedian)
00196 JFR_DEFINE_PARAM_RW(double, thresholdOfEnoughtGroup, setThresholdOfEnoughtGroup)
00197 JFR_DEFINE_PARAM_RW(double, rotationTolerancePropagation, setRotationTolerancePropagation)
00198 #endif
00199 private:
00200
00201 int md_currentnumberofmatch;
00202
00203 friend std::ostream& operator <<(std::ostream& s, const GroupsMatcher::InterestFeatureInfo& p_);
00204 friend std::ostream& operator <<(std::ostream& s, const GroupsMatcher::Group::GroupMember& p_);
00205 friend std::ostream& operator <<(std::ostream& s, const GroupsMatcher::Group& p_);
00206 friend std::ostream& operator <<(std::ostream& s, const GroupsMatcher::GroupsMatchSourceInfo& p_);
00208 friend class boost::serialization::access;
00209 template<class Archive>
00210 void serialize(Archive &ar, const unsigned int version)
00211 {
00212 ar & BOOST_SERIALIZATION_NVP(m_matchFocus);
00213 ar & BOOST_SERIALIZATION_NVP(m_groupSize);
00214 ar & BOOST_SERIALIZATION_NVP(m_groupSizeSeedSearch);
00215 ar & BOOST_SERIALIZATION_NVP(m_minimalGroupSize);
00216 ar & BOOST_SERIALIZATION_NVP(m_distance);
00217 ar & BOOST_SERIALIZATION_NVP(m_closeness);
00218 ar & BOOST_SERIALIZATION_NVP(m_weakCloseness);
00219 ar & BOOST_SERIALIZATION_NVP(m_distinguability);
00220 ar & BOOST_SERIALIZATION_NVP(m_rotationTolerance);
00221 ar & BOOST_SERIALIZATION_NVP(m_scaleTolerance);
00222 ar & BOOST_SERIALIZATION_NVP(m_distanceTolerance);
00223 ar & BOOST_SERIALIZATION_NVP(m_rotationDifferenceWithMedian);
00224 ar & BOOST_SERIALIZATION_NVP(m_thresholdOfEnoughtGroup);
00225 ar & BOOST_SERIALIZATION_NVP(m_rotationTolerancePropagation);
00226 }
00227 };
00228 }
00229
00230 namespace gfm_v2 {
00235 template<typename InterestFeatureT>
00236 class GroupsMatcher : public Matcher<InterestFeatureT> {
00237 class Group;
00238
00239 struct InterestFeatureInfo {
00240 inline InterestFeatureInfo(InterestFeatureT* iP) : group(0), interestPoint(iP), matchPoint(0) {}
00241 Group* group;
00242 InterestFeatureT* interestPoint;
00243 InterestFeatureInfo* matchPoint;
00244
00245
00246 };
00247
00248 typedef std::vector< InterestFeatureInfo* > vInterestFeatureInfos;
00249 typedef typename vInterestFeatureInfos::iterator vInterestFeatureInfos_it;
00250 typedef typename vInterestFeatureInfos::const_iterator vInterestFeatureInfos_cit;
00251 typedef std::map<double, InterestFeatureInfo* > double2interestPointInfo;
00252 typedef typename double2interestPointInfo::iterator double2interestPointInfo_it;
00253 typedef std::pair<InterestFeatureInfo*, InterestFeatureInfo*> pIpInfoIpInfo;
00254 typedef std::vector<pIpInfoIpInfo> vpIpInfoIpInfos;
00255 typedef MatchSourceInfo<InterestFeatureT> MatchSourceInfoType;
00256 typedef jafar::fdetect_v2::DetectionResult< InterestFeatureT > DetectionResult;
00257 typedef jafar::gfm_v2::MatchingResult<InterestFeatureT> MatchingResult;
00258
00259 class Group {
00260 public:
00261 struct GroupMember {
00262 double distance, angle;
00263 InterestFeatureInfo* interestPointInfo;
00264
00265 };
00266 typedef std::vector< GroupMember > vGroupMembers;
00267 public:
00268 Group(double2interestPointInfo_it itbegin, double2interestPointInfo_it itend )
00269 {
00270
00271 for(double2interestPointInfo_it it = itbegin; it != itend; ++it)
00272 {
00273 GroupMember gm;
00274 gm.interestPointInfo = it->second;
00275 m_members.push_back(gm);
00276 }
00277
00278 jblas::vec2 origin = at(0).interestPointInfo->interestPoint->point();
00279 at(0).angle = 0.;
00280 at(0).distance = 0.;
00281 for(typename vGroupMembers::iterator it = begin() + 1; it != end(); ++it)
00282 {
00283 jblas::vec2 v = it->interestPointInfo->interestPoint->point() - origin;
00284 it->distance = ublas::norm_2(v);
00285 it->angle = atan2( v(0), v(1));
00286 }
00287 }
00288 inline GroupMember pivot() { return m_members[0]; }
00289 inline GroupMember& at(int index) { return m_members[index]; }
00290 inline typename vGroupMembers::iterator begin() { return m_members.begin(); }
00291 inline typename vGroupMembers::iterator end() { return m_members.end(); }
00292 inline unsigned int size() { return m_members.size(); }
00293
00294 private:
00295 vGroupMembers m_members;
00296 };
00297 typedef std::vector<Group*> vGroups;
00298 typedef typename vGroups::iterator vGroups_it;
00299 typedef std::pair<typename Group::GroupMember, typename Group::GroupMember> pGrpMembGrMemb;
00300 typedef std::vector< pGrpMembGrMemb > vpGrpMembGrMembs;
00301 typedef typename vpGrpMembGrMembs::iterator vpGrpMembGrMembs_it;
00302
00303 struct GroupMatchHypothesis {
00304 inline GroupMatchHypothesis() {}
00305 double matchingStrength;
00306 double sumRotation;
00307 double sumScale;
00308 double sumTranslationU;
00309 double sumTranslationV;
00310 double angleErr;
00311 int count;
00312 geom::RectangleDouble rect;
00313 Group* groupref;
00314 Group* groupmatch;
00315 vpGrpMembGrMembs individualmatches;
00316 };
00317
00318 class GroupsMatchSourceInfo : public MatchSourceInfoType, public boost::noncopyable {
00319 public:
00320 GroupsMatchSourceInfo( DetectionResult points, GroupsMatcher* gm);
00321 ~GroupsMatchSourceInfo();
00322 virtual void reinit();
00323 inline vGroups groups() { return m_groups; }
00324 inline const vInterestFeatureInfos& pointsInfo() { return m_pointsInfo; }
00325
00326 private:
00327 vGroups m_groups;
00328 vInterestFeatureInfos m_pointsInfo;
00329 };
00330 public:
00352 GroupsMatcher(gfm::MatchFocus* matchFocus = 0,
00353 unsigned int groupsize = 12,
00354 unsigned int groupsizeseedsearch = 12,
00355 unsigned int minimalgroupsize = 2,
00356 double distance = 20.0,
00357 double closeness = 0.6,
00358 double weakcloseness = 0.6,
00359 double distinguability = 0.1,
00360 double rotationTolerance = 0.2,
00361 double scaleTolerance = 10000.0,
00362 double distanceTolerance = 10.0,
00363 double rotationDifferenceWithMedian = 0.4,
00364 double thresholdofenoughtgroup = 0. ) :
00365 m_matchFocus(matchFocus),
00366 m_groupSize(groupsize),
00367 m_groupSizeSeedSearch(groupsizeseedsearch),
00368 m_minimalGroupSize(minimalgroupsize),
00369 m_distance(distance),
00370 m_closeness(closeness),
00371 m_weakCloseness(weakcloseness),
00372 m_distinguability(distinguability),
00373 m_rotationTolerance(rotationTolerance),
00374 m_scaleTolerance(scaleTolerance),
00375 m_distanceTolerance(distanceTolerance),
00376 m_rotationDifferenceWithMedian(rotationDifferenceWithMedian),
00377 m_thresholdOfEnoughtGroup(thresholdofenoughtgroup),
00378 m_rotationTolerancePropagation(rotationTolerance)
00379 { }
00380 GroupsMatcher(GroupsMatcher const& gm);
00381
00382 GroupsMatcher& operator=(GroupsMatcher const& m) { if (&m != this) *this = *(new GroupsMatcher(m)); return *this; }
00383 virtual ~GroupsMatcher();
00384 public:
00385 virtual MatchingResult computeMatch( MatchSourceInfoType* refsourceinfo, MatchSourceInfoType* matchsourceinfo);
00386 virtual MatchSourceInfoType* initMatchSourceInfo( const DetectionResult& pointsource );
00387 public:
00388 void setMatchFocus(gfm::MatchFocus* matchFocus);
00389 private:
00390 GroupMatchHypothesis* searchBestMatchFor( Group* groupref, vGroups& groupsmatch );
00391 void propageMatching( vInterestFeatureInfos& matches, InterestFeatureInfo* startingpoint , GroupMatchHypothesis* hypothesis);
00392 void initiatePropagation(vInterestFeatureInfos& matches, GroupMatchHypothesis* match, vpGrpMembGrMembs individualmatches);
00393 #ifndef SWIG
00394 JFR_DEFINE_PARAM_RO(gfm::MatchFocus*, matchFocus)
00398 JFR_DEFINE_PARAM_RW(unsigned int, groupSize, setGroupSize)
00399 JFR_DEFINE_PARAM_RW(unsigned int, groupSizeSeedSearch, setGroupSizeSeedSearch)
00403 JFR_DEFINE_PARAM_RW(unsigned int, minimalGroupSize, setMinimalGroupSize)
00407 JFR_DEFINE_PARAM_RW(double, distance, setDistance)
00411 JFR_DEFINE_PARAM_RW(double, closeness, setCloseness)
00412 JFR_DEFINE_PARAM_RW(double, weakCloseness, setWeakCloseness)
00413 JFR_DEFINE_PARAM_RW(double, distinguability, setDistinguability)
00414 JFR_DEFINE_PARAM_RW(double, rotationTolerance, setRotationTolerance)
00415 JFR_DEFINE_PARAM_RW(double, scaleTolerance, setScaleTolerance)
00416 JFR_DEFINE_PARAM_RW(double, distanceTolerance, setDistanceTolerance)
00417 JFR_DEFINE_PARAM_RW(double, rotationDifferenceWithMedian, setRotationDifferenceWithMedian)
00418 JFR_DEFINE_PARAM_RW(double, thresholdOfEnoughtGroup, setThresholdOfEnoughtGroup)
00419 JFR_DEFINE_PARAM_RW(double, rotationTolerancePropagation, setRotationTolerancePropagation)
00420 #endif
00421 private:
00422
00423 int md_currentnumberofmatch;
00424
00425
00426
00427
00428
00430 friend class boost::serialization::access;
00431 template<class Archive>
00432 void serialize(Archive &ar, const unsigned int version)
00433 {
00434 ar & BOOST_SERIALIZATION_NVP(m_matchFocus);
00435 ar & BOOST_SERIALIZATION_NVP(m_groupSize);
00436 ar & BOOST_SERIALIZATION_NVP(m_groupSizeSeedSearch);
00437 ar & BOOST_SERIALIZATION_NVP(m_minimalGroupSize);
00438 ar & BOOST_SERIALIZATION_NVP(m_distance);
00439 ar & BOOST_SERIALIZATION_NVP(m_closeness);
00440 ar & BOOST_SERIALIZATION_NVP(m_weakCloseness);
00441 ar & BOOST_SERIALIZATION_NVP(m_distinguability);
00442 ar & BOOST_SERIALIZATION_NVP(m_rotationTolerance);
00443 ar & BOOST_SERIALIZATION_NVP(m_scaleTolerance);
00444 ar & BOOST_SERIALIZATION_NVP(m_distanceTolerance);
00445 ar & BOOST_SERIALIZATION_NVP(m_rotationDifferenceWithMedian);
00446 ar & BOOST_SERIALIZATION_NVP(m_thresholdOfEnoughtGroup);
00447 ar & BOOST_SERIALIZATION_NVP(m_rotationTolerancePropagation);
00448 }
00449 };
00450 }
00451 }
00452
00453 #include "gfm/GroupsMatcher.hxx"
00454 #endif