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)