30   assert(hist1.size() == hist2.size());
    32   double BhattachDist_aux = 0.0;
    33   for(
unsigned i=0; i < hist1.size(); i++)
    34     BhattachDist_aux += sqrt(hist1[i]*hist2[i]);
    36   BhattachDist = sqrt(1 - BhattachDist_aux);
    41 SubgraphMatcher::SubgraphMatcher()
    49 bool SubgraphMatcher::evalUnaryConstraints(
Plane &plane1, 
Plane &plane2, 
PbMap &trgPbMap, 
bool useStructure)
    56   cout << 
"unary between " << plane1.
id << 
" " << plane2.
id << 
"\n";
   122     if( rel_areas < configLocaliser.area_full_threshold_inv || rel_areas > configLocaliser.area_full_threshold ){
   124     cout << 
"False: rel_areas full " << rel_areas << endl;
   130     if( rel_elong < configLocaliser.elongation_threshold_inv || rel_elong > configLocaliser.elongation_threshold ){
   132     cout << 
"False: rel_elong full " << rel_elong << endl;
   141       if( rel_areas < configLocaliser.area_full_threshold_inv || rel_areas > configLocaliser.area_threshold ){
   143       cout << 
"rel_areas RefFull " << rel_areas << endl;
   149       if( rel_areas < configLocaliser.area_threshold_inv || rel_areas > configLocaliser.area_full_threshold ){
   151       cout << 
"rel_areas CheckFull " << rel_areas << endl;
   155     else if( rel_areas < configLocaliser.area_threshold_inv || rel_areas > configLocaliser.area_threshold ){
   157     cout << 
"rel_areas simple " << rel_areas << endl;
   162     if( rel_elong < configLocaliser.elongation_threshold_inv || rel_elong > configLocaliser.elongation_threshold ){
   164     cout << 
"rel_elong simple " << rel_elong << endl;
   172   cout << 
"UNARY TRUE" << endl;
   178 bool SubgraphMatcher::evalUnaryConstraintsOdometry(
Plane &plane1, 
Plane &plane2, 
PbMap &trgPbMap, 
bool useStructure)
   185   cout << 
"unaryOdometry between " << plane1.
id << 
" " << plane2.
id << 
"\n";
   191   if( fabs(plane1.
d - plane2.
d) > configLocaliser.dist_d){
   193     cout << 
"depthUnaryConstraint false " << fabs(plane1.
d - plane2.
d) << 
" > " << configLocaliser.dist_d << 
"\n";
   200     cout << 
"angleUnaryConstraint false " << plane1.
v3normal .dot (plane2.
v3normal) << 
" < " << configLocaliser.angle << 
"\n";
   271     if( rel_areas < configLocaliser.area_full_threshold_inv || rel_areas > configLocaliser.area_full_threshold ){
   273     cout << 
"False: rel_areas full " << rel_areas << endl;
   279     if( rel_elong < configLocaliser.elongation_threshold_inv || rel_elong > configLocaliser.elongation_threshold ){
   281     cout << 
"False: rel_elong full " << rel_elong << endl;
   290       if( rel_areas < configLocaliser.area_full_threshold_inv || rel_areas > configLocaliser.area_threshold ){
   292       cout << 
"rel_areas RefFull " << rel_areas << endl;
   298       if( rel_areas < configLocaliser.area_threshold_inv || rel_areas > configLocaliser.area_full_threshold ){
   300       cout << 
"rel_areas CheckFull " << rel_areas << endl;
   304     else if( rel_areas < configLocaliser.area_threshold_inv || rel_areas > configLocaliser.area_threshold ){
   306     cout << 
"rel_areas simple " << rel_areas << endl;
   311     if( rel_elong < configLocaliser.elongation_threshold_inv || rel_elong > configLocaliser.elongation_threshold ){
   313     cout << 
"rel_elong simple " << rel_elong << endl;
   321   cout << 
"UNARY TRUE" << endl;
   327 bool SubgraphMatcher::evalUnaryConstraints2D(
Plane &plane1, 
Plane &plane2, 
PbMap &trgPbMap, 
bool useStructure)
   334   cout << 
"unary2D between " << plane1.
id << 
" " << plane2.
id << 
"\n";
   342     if( fabs(plane1.
d - plane2.
d) < 0.15 ){
   411     if( rel_areas < configLocaliser.area_full_threshold_inv || rel_areas > configLocaliser.area_full_threshold ){
   413     cout << 
"False: rel_areas full " << rel_areas << endl;
   419     if( rel_elong < configLocaliser.elongation_threshold_inv || rel_elong > configLocaliser.elongation_threshold ){
   421     cout << 
"False: rel_elong full " << rel_elong << endl;
   430       if( rel_areas < configLocaliser.area_full_threshold_inv || rel_areas > configLocaliser.area_threshold ){
   432       cout << 
"rel_areas RefFull " << rel_areas << endl;
   438       if( rel_areas < configLocaliser.area_threshold_inv || rel_areas > configLocaliser.area_full_threshold ){
   440       cout << 
"rel_areas CheckFull " << rel_areas << endl;
   444     else if( rel_areas < configLocaliser.area_threshold_inv || rel_areas > configLocaliser.area_threshold ){
   446     cout << 
"rel_areas simple " << rel_areas << endl;
   451     if( rel_elong < configLocaliser.elongation_threshold_inv || rel_elong > configLocaliser.elongation_threshold ){
   453     cout << 
"rel_elong simple " << rel_elong << endl;
   461   cout << 
"UNARY TRUE" << endl;
   467 bool SubgraphMatcher::evalUnaryConstraintsOdometry2D(
Plane &plane1, 
Plane &plane2, 
PbMap &trgPbMap, 
bool useStructure)
   474   cout << 
"unaryOdometry2D between " << plane1.
id << 
" " << plane2.
id << 
"\n";
   483     if( fabs(plane1.
d - plane2.
d) < 0.12 ){
   489   cout << 
"pass 2D \n";
   493   if( fabs(plane1.
d - plane2.
d) > configLocaliser.dist_d){
   495     cout << 
"depthUnaryConstraint false " << fabs(plane1.
d - plane2.
d) << 
" > " << configLocaliser.dist_d << 
"\n";
   502     cout << 
"angleUnaryConstraint false " << plane1.
v3normal .dot (plane2.
v3normal) << 
" < " << configLocaliser.angle << 
"\n";
   573     if( rel_areas < configLocaliser.area_full_threshold_inv || rel_areas > configLocaliser.area_full_threshold ){
   575     cout << 
"False: rel_areas full " << rel_areas << endl;
   581     if( rel_elong < configLocaliser.elongation_threshold_inv || rel_elong > configLocaliser.elongation_threshold ){
   583     cout << 
"False: rel_elong full " << rel_elong << endl;
   592       if( rel_areas < configLocaliser.area_full_threshold_inv || rel_areas > configLocaliser.area_threshold ){
   594       cout << 
"rel_areas RefFull " << rel_areas << endl;
   600       if( rel_areas < configLocaliser.area_threshold_inv || rel_areas > configLocaliser.area_full_threshold ){
   602       cout << 
"rel_areas CheckFull " << rel_areas << endl;
   606     else if( rel_areas < configLocaliser.area_threshold_inv || rel_areas > configLocaliser.area_threshold ){
   608     cout << 
"rel_areas simple " << rel_areas << endl;
   613     if( rel_elong < configLocaliser.elongation_threshold_inv || rel_elong > configLocaliser.elongation_threshold ){
   615     cout << 
"rel_elong simple " << rel_elong << endl;
   623   cout << 
"UNARY TRUE" << endl;
   648     float threshold_dist_dependent = configLocaliser.height_threshold * (Ref.
v3center - neigRef.
v3center).
norm() * 0.4;
   649     float height_threshold = std::max(configLocaliser.height_threshold, threshold_dist_dependent);
   650     if(dif_height > height_threshold){
   653     cout << 
"Binary false: Ref dif_height " << dif_height << endl;
   664     float height_threshold = (neigRef.
areaHull + neigCheck.
areaHull)*configLocaliser.height_threshold;
   665     if(dif_height > height_threshold){
   668     cout << 
"Binary false BIG Area: Ref dif_height " << dif_height << endl;
   679     float threshold_dist_dependent = configLocaliser.height_threshold * (Ref.
v3center - neigRef.
v3center).
norm() * 0.4;
   680     float height_threshold = std::max(configLocaliser.height_threshold, threshold_dist_dependent);
   681     if(dif_height2 > height_threshold){
   684     cout << 
"Binary false: neigRef dif_height2 " << dif_height2 << endl;
   695     float height_threshold = (Ref.
areaHull + Check.
areaHull)*configLocaliser.height_threshold;
   696     if(dif_height2 > height_threshold){
   699     cout << 
"Binary false: neigRef dif_height2 " << dif_height2 << endl;
   708   if( dif_normal > std::max(configLocaliser.angle_threshold,2*(Ref.
v3center - neigRef.
v3center).norm()) ){
   710       cout << 
"Binary false:  angle " << dif_normal << 
" with " << neigRef.
id << endl;
   722   if(configLocaliser.use_completeness)
   724     if(RefBothFull && CheckBothFull)
   726       if( rel_dist_centers < configLocaliser.dist_threshold_inv || rel_dist_centers > configLocaliser.dist_threshold ){
   728         cout << 
"Binary false:  dist_centers1 with " << neigRef.
id << endl;
   733     else if(RefBothFull || CheckBothFull)
   735       if( rel_dist_centers < configLocaliser.dist_threshold_inv || rel_dist_centers > configLocaliser.dist_threshold ){
   737         cout << 
"Binary false:  dist_centers2 with " << neigRef.
id << endl;
   743       if( rel_dist_centers < configLocaliser.dist_threshold_inv || rel_dist_centers > configLocaliser.dist_threshold ){
   745       cout << 
"Binary false:  dist_centers3 with " << neigRef.
id << endl;
   753       if( rel_dist_centers < configLocaliser.dist_threshold_inv || rel_dist_centers > configLocaliser.dist_threshold){
   755       cout << 
"Binary false:  dist_centers4 with " << neigRef.
id << endl;
   764   cout << 
"BINARY TRUE\n" << endl;
   772   if( contained.size() > container.size() )
   777     if(container.count(it->first) == 0)
   779     else if(container[it->first] != it->second)
   783     cout << 
"Repeated sequence. Comparing:\n";
   785       cout << it->first << 
" " << it->second << endl;
   788       cout << it->first << 
" " << it->second << endl;
   800 void SubgraphMatcher::exploreSubgraphTreeR(set<unsigned> &sourcePlanes, set<unsigned> &targetPlanes, map<unsigned, unsigned> &matched)
   803     cout << 
"matched: " << matched.size() << 
"\n";
   805       cout << it->first << 
" - " << it->second << 
" =" << subgraphTrg->pPBM->vPlanes[it->second].label << endl;
   806     cout << 
"sourcePlanes: " << sourcePlanes.size() << 
": ";
   809     cout << 
"\ntargetPlanes " << targetPlanes.size() << 
": ";
   820   unsigned requiredMatches = max(configLocaliser.min_planes_recognition, static_cast<unsigned>(winnerMatch.size()));
   836   while(!sourcePlanes.empty())
   840       cout << 
"Compare " << *it1 << 
" Compare Compare Compare Compare Compare " << endl;
   843     if( (matched.size() + 
min(sourcePlanes.size(),targetPlanes.size())) <= requiredMatches )
   846         cout << 
"End branch recursive search. Too short " << matched.size() << 
" prev winner " << winnerMatch.size() << endl;
   862         cout << 
" " << *it1 << 
" with " << *it2 << endl;
   887       if( hashUnaryConstraints[*it1][*it2] != 1 )
   890       bool binaryFail = 
false;
   892         if( !evalBinaryConstraints(subgraphSrc->pPBM->vPlanes[*it1], subgraphSrc->pPBM->vPlanes[it_matched->first], subgraphTrg->pPBM->vPlanes[*it2], subgraphTrg->pPBM->vPlanes[it_matched->second]) )
   902       set<unsigned> nextSrcPlanes = sourcePlanes;
   903       nextSrcPlanes.erase(*it1);
   904       set<unsigned> nextTrgPlanes = targetPlanes;
   905       nextTrgPlanes.erase(*it2);
   906       map<unsigned, unsigned> nextMatched = matched;
   907       nextMatched[*it1] = *it2;
   909       alreadyExplored.push_back(nextMatched);
   911       exploreSubgraphTreeR(nextSrcPlanes, nextTrgPlanes, nextMatched);
   918     sourcePlanes.erase(it1);
   921   if(matched.size() > winnerMatch.size()){
   922   float areaMatched = calcAreaMatched(matched);
   925       cout << 
"End branch recursive search. matched " << matched.size() << 
" A " << areaMatched << 
" prev winner " << winnerMatch.size() << 
" A " << areaWinnerMatch << endl;
   927     areaWinnerMatch = areaMatched;
   928     winnerMatch = matched;}
   931 void SubgraphMatcher::exploreSubgraphTreeR_Area(set<unsigned> &sourcePlanes, set<unsigned> &targetPlanes, map<unsigned, unsigned> &matched)
   934     cout << 
"matched: " << matched.size() << 
"\n";
   936       cout << it->first << 
" - " << it->second << 
" =" << subgraphTrg->pPBM->vPlanes[it->second].label << endl;
   937     cout << 
"sourcePlanes: " << sourcePlanes.size() << 
": ";
   940     cout << 
"\ntargetPlanes " << targetPlanes.size() << 
": ";
   951   float matchedArea = calcAreaMatched(matched);
   953   float unmatchedArea = 0; 
   955     unmatchedArea += subgraphSrc->pPBM->vPlanes[*it1].areaHull;
   959   while(!sourcePlanes.empty())
   963       cout << 
"Compare " << *it1 << 
" Compare Compare Compare Compare Compare " << endl;
   966     if( (matched.size() + 
min(sourcePlanes.size(),targetPlanes.size())) <= configLocaliser.min_planes_recognition )
   967       if( (matchedArea + unmatchedArea) < areaWinnerMatch )
   970           cout << 
"End branch recursive search. Too short " << matched.size() << 
" prev winner " << winnerMatch.size() << endl;
   986         cout << 
" " << *it1 << 
" with " << *it2 << endl;
  1011       if( hashUnaryConstraints[*it1][*it2] != 1 )
  1014       bool binaryFail = 
false;
  1016         if( !evalBinaryConstraints(subgraphSrc->pPBM->vPlanes[*it1], subgraphSrc->pPBM->vPlanes[it_matched->first], subgraphTrg->pPBM->vPlanes[*it2], subgraphTrg->pPBM->vPlanes[it_matched->second]) )
  1026       set<unsigned> nextSrcPlanes = sourcePlanes;
  1027       nextSrcPlanes.erase(*it1);
  1028       set<unsigned> nextTrgPlanes = targetPlanes;
  1029       nextTrgPlanes.erase(*it2);
  1030       map<unsigned, unsigned> nextMatched = matched;
  1031       nextMatched[*it1] = *it2;
  1033       alreadyExplored.push_back(nextMatched);
  1035       exploreSubgraphTreeR_Area(nextSrcPlanes, nextTrgPlanes, nextMatched);
  1042     sourcePlanes.erase(it1);
  1046   float areaMatched = calcAreaMatched(matched);
  1047   if(areaMatched > areaWinnerMatch){
  1049       cout << 
"End branch recursive search. matched " << matched.size() << 
" A " << areaMatched << 
" prev winner " << winnerMatch.size() << 
" A " << areaWinnerMatch << endl;
  1051     areaWinnerMatch = areaMatched;
  1052     winnerMatch = matched;}
  1055 float SubgraphMatcher::calcAreaMatched(std::map<unsigned,unsigned> &matched_planes)
  1057   float areaMatched = 0;
  1059     areaMatched += subgraphSrc->pPBM->vPlanes[it->first].areaHull;
  1064 float SubgraphMatcher::calcAreaUnmatched(std::set<unsigned> &unmatched_planes)
  1066   float areaUnatched = 0;
  1068     areaUnatched += subgraphSrc->pPBM->vPlanes[*it].areaHull;
  1070   return areaUnatched;
  1100 std::map<unsigned,unsigned> SubgraphMatcher::compareSubgraphs(
Subgraph &subgraphSource, 
Subgraph &subgraphTarget, 
const int option)
  1103   subgraphSrc = &subgraphSource;
  1104   subgraphTrg = &subgraphTarget;
  1105   map<unsigned, unsigned> matched;
  1107   areaWinnerMatch = 0;
  1108   winnerMatch.clear();
  1109   alreadyExplored.clear(); 
  1111   std::set<unsigned> targetPlanes = subgraphTrg->subgraphPlanesIdx;
  1114   cout << 
"Source planes: ";
  1116     cout << 
" " << *it2;
  1118   cout << 
"Target planes: ";
  1120     cout << 
" " << *it2;
  1125   hashUnaryConstraints = std::vector<std::vector<int8_t> >(subgraphSrc->pPBM->vPlanes.size(), std::vector<int8_t>(subgraphTrg->pPBM->vPlanes.size()) );
  1129         hashUnaryConstraints[*it1][*it2] = (evalUnaryConstraints(subgraphSrc->pPBM->vPlanes[*it1], subgraphTrg->pPBM->vPlanes[*it2], *subgraphTrg->pPBM, 
false ) ? 1 : 0);
  1133         hashUnaryConstraints[*it1][*it2] = (evalUnaryConstraintsOdometry(subgraphSrc->pPBM->vPlanes[*it1], subgraphTrg->pPBM->vPlanes[*it2], *subgraphTrg->pPBM, 
false ) ? 1 : 0);
  1137         hashUnaryConstraints[*it1][*it2] = (evalUnaryConstraints2D(subgraphSrc->pPBM->vPlanes[*it1], subgraphTrg->pPBM->vPlanes[*it2], *subgraphTrg->pPBM, 
false ) ? 1 : 0);
  1141         hashUnaryConstraints[*it1][*it2] = (evalUnaryConstraintsOdometry2D(subgraphSrc->pPBM->vPlanes[*it1], subgraphTrg->pPBM->vPlanes[*it2], *subgraphTrg->pPBM, 
false ) ? 1 : 0);
  1143   exploreSubgraphTreeR(sourcePlanes, targetPlanes, matched);
  1146   cout << 
"Area winnerMatch " << areaWinnerMatch << endl;
 
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL. 
 
A class used to store a planar feature (Plane for short). 
 
double BhattacharyyaDist_(std::vector< float > &hist1, std::vector< float > &hist2)
 
bool isSubgraphContained(map< unsigned, unsigned > &contained, map< unsigned, unsigned > &container)
 
unsigned id
! Parameters to allow the plane-based representation of the map by a graph 
 
std::vector< float > hist_H
 
Eigen::Vector3f v3center
! Geometric description 
 
std::set< unsigned > subgraphPlanesIdx
 
A class used to store a Plane-based Map (PbMap). 
 
CONTAINER::Scalar norm(const CONTAINER &v)