31 assert(hist1.size() == hist2.size());
33 double BhattachDist_aux = 0.0;
34 for (
unsigned i = 0; i < hist1.size(); i++)
35 BhattachDist_aux += sqrt(hist1[i] * hist2[i]);
37 BhattachDist = sqrt(1 - BhattachDist_aux);
42 SubgraphMatcher::SubgraphMatcher()
50 bool SubgraphMatcher::evalUnaryConstraints(
58 cout <<
"unary between " << plane1.
id <<
" " << plane2.
id <<
"\n";
103 configLocaliser.hue_threshold)
106 cout <<
"Hist_H false " 108 << configLocaliser.hue_threshold <<
"\n";
137 if (rel_areas < configLocaliser.area_full_threshold_inv ||
138 rel_areas > configLocaliser.area_full_threshold)
141 cout <<
"False: rel_areas full " << rel_areas << endl;
148 if (rel_elong < configLocaliser.elongation_threshold_inv ||
149 rel_elong > configLocaliser.elongation_threshold)
152 cout <<
"False: rel_elong full " << rel_elong << endl;
162 if (rel_areas < configLocaliser.area_full_threshold_inv ||
163 rel_areas > configLocaliser.area_threshold)
166 cout <<
"rel_areas RefFull " << rel_areas << endl;
173 if (rel_areas < configLocaliser.area_threshold_inv ||
174 rel_areas > configLocaliser.area_full_threshold)
177 cout <<
"rel_areas CheckFull " << rel_areas << endl;
183 rel_areas < configLocaliser.area_threshold_inv ||
184 rel_areas > configLocaliser.area_threshold)
187 cout <<
"rel_areas simple " << rel_areas << endl;
193 if (rel_elong < configLocaliser.elongation_threshold_inv ||
194 rel_elong > configLocaliser.elongation_threshold)
197 cout <<
"rel_elong simple " << rel_elong << endl;
206 cout <<
"UNARY TRUE" << endl;
212 bool SubgraphMatcher::evalUnaryConstraintsOdometry(
220 cout <<
"unaryOdometry between " << plane1.
id <<
" " << plane2.
id <<
"\n";
226 if (fabs(plane1.
d - plane2.
d) > configLocaliser.dist_d)
229 cout <<
"depthUnaryConstraint false " << fabs(plane1.
d - plane2.
d)
230 <<
" > " << configLocaliser.dist_d <<
"\n";
238 cout <<
"angleUnaryConstraint false " 240 << configLocaliser.angle <<
"\n";
286 configLocaliser.hue_threshold)
289 cout <<
"Hist_H false_ " 291 << configLocaliser.hue_threshold <<
"\n";
323 if (rel_areas < configLocaliser.area_full_threshold_inv ||
324 rel_areas > configLocaliser.area_full_threshold)
327 cout <<
"False: rel_areas full " << rel_areas << endl;
334 if (rel_elong < configLocaliser.elongation_threshold_inv ||
335 rel_elong > configLocaliser.elongation_threshold)
338 cout <<
"False: rel_elong full " << rel_elong << endl;
348 if (rel_areas < configLocaliser.area_full_threshold_inv ||
349 rel_areas > configLocaliser.area_threshold)
352 cout <<
"rel_areas RefFull " << rel_areas << endl;
359 if (rel_areas < configLocaliser.area_threshold_inv ||
360 rel_areas > configLocaliser.area_full_threshold)
363 cout <<
"rel_areas CheckFull " << rel_areas << endl;
369 rel_areas < configLocaliser.area_threshold_inv ||
370 rel_areas > configLocaliser.area_threshold)
373 cout <<
"rel_areas simple " << rel_areas << endl;
379 if (rel_elong < configLocaliser.elongation_threshold_inv ||
380 rel_elong > configLocaliser.elongation_threshold)
383 cout <<
"rel_elong simple " << rel_elong << endl;
392 cout <<
"UNARY TRUE" << endl;
398 bool SubgraphMatcher::evalUnaryConstraints2D(
406 cout <<
"unary2D between " << plane1.
id <<
" " << plane2.
id <<
"\n";
416 if (fabs(plane1.
d - plane2.
d) < 0.15)
465 configLocaliser.hue_threshold)
468 cout <<
"Hist_H false " 470 << configLocaliser.hue_threshold <<
"\n";
499 if (rel_areas < configLocaliser.area_full_threshold_inv ||
500 rel_areas > configLocaliser.area_full_threshold)
503 cout <<
"False: rel_areas full " << rel_areas << endl;
510 if (rel_elong < configLocaliser.elongation_threshold_inv ||
511 rel_elong > configLocaliser.elongation_threshold)
514 cout <<
"False: rel_elong full " << rel_elong << endl;
524 if (rel_areas < configLocaliser.area_full_threshold_inv ||
525 rel_areas > configLocaliser.area_threshold)
528 cout <<
"rel_areas RefFull " << rel_areas << endl;
535 if (rel_areas < configLocaliser.area_threshold_inv ||
536 rel_areas > configLocaliser.area_full_threshold)
539 cout <<
"rel_areas CheckFull " << rel_areas << endl;
545 rel_areas < configLocaliser.area_threshold_inv ||
546 rel_areas > configLocaliser.area_threshold)
549 cout <<
"rel_areas simple " << rel_areas << endl;
555 if (rel_elong < configLocaliser.elongation_threshold_inv ||
556 rel_elong > configLocaliser.elongation_threshold)
559 cout <<
"rel_elong simple " << rel_elong << endl;
568 cout <<
"UNARY TRUE" << endl;
574 bool SubgraphMatcher::evalUnaryConstraintsOdometry2D(
582 cout <<
"unaryOdometry2D between " << plane1.
id <<
" " << plane2.
id <<
"\n";
593 if (fabs(plane1.
d - plane2.
d) < 0.12)
600 cout <<
"pass 2D \n";
604 if (fabs(plane1.
d - plane2.
d) > configLocaliser.dist_d)
607 cout <<
"depthUnaryConstraint false " << fabs(plane1.
d - plane2.
d)
608 <<
" > " << configLocaliser.dist_d <<
"\n";
616 cout <<
"angleUnaryConstraint false " 618 << configLocaliser.angle <<
"\n";
664 configLocaliser.hue_threshold)
667 cout <<
"Hist_H false_ " 669 << configLocaliser.hue_threshold <<
"\n";
701 if (rel_areas < configLocaliser.area_full_threshold_inv ||
702 rel_areas > configLocaliser.area_full_threshold)
705 cout <<
"False: rel_areas full " << rel_areas << endl;
712 if (rel_elong < configLocaliser.elongation_threshold_inv ||
713 rel_elong > configLocaliser.elongation_threshold)
716 cout <<
"False: rel_elong full " << rel_elong << endl;
726 if (rel_areas < configLocaliser.area_full_threshold_inv ||
727 rel_areas > configLocaliser.area_threshold)
730 cout <<
"rel_areas RefFull " << rel_areas << endl;
737 if (rel_areas < configLocaliser.area_threshold_inv ||
738 rel_areas > configLocaliser.area_full_threshold)
741 cout <<
"rel_areas CheckFull " << rel_areas << endl;
747 rel_areas < configLocaliser.area_threshold_inv ||
748 rel_areas > configLocaliser.area_threshold)
751 cout <<
"rel_areas simple " << rel_areas << endl;
757 if (rel_elong < configLocaliser.elongation_threshold_inv ||
758 rel_elong > configLocaliser.elongation_threshold)
761 cout <<
"rel_elong simple " << rel_elong << endl;
770 cout <<
"UNARY TRUE" << endl;
780 bool SubgraphMatcher::evalBinaryConstraints(
795 double dif_height = fabs(
800 float threshold_dist_dependent =
801 configLocaliser.height_threshold *
803 float height_threshold = std::max(
804 configLocaliser.height_threshold, threshold_dist_dependent);
805 if (dif_height > height_threshold)
809 cout <<
"Binary false: Ref dif_height " << dif_height << endl;
817 double dif_height = fabs(
825 configLocaliser.height_threshold;
826 if (dif_height > height_threshold)
830 cout <<
"Binary false BIG Area: Ref dif_height " << dif_height
840 double dif_height2 = fabs(
845 float threshold_dist_dependent =
846 configLocaliser.height_threshold *
848 float height_threshold = std::max(
849 configLocaliser.height_threshold, threshold_dist_dependent);
850 if (dif_height2 > height_threshold)
854 cout <<
"Binary false: neigRef dif_height2 " << dif_height2 << endl;
862 double dif_height2 = fabs(
869 float height_threshold =
871 if (dif_height2 > height_threshold)
875 cout <<
"Binary false: neigRef dif_height2 " << dif_height2 << endl;
883 double dif_normal = fabs(
888 if (dif_normal > std::max(
889 configLocaliser.angle_threshold,
893 cout <<
"Binary false: angle " << dif_normal <<
" with " << neigRef.
id 901 double rel_dist_centers = sqrt(
913 if (configLocaliser.use_completeness)
915 if (RefBothFull && CheckBothFull)
917 if (rel_dist_centers < configLocaliser.dist_threshold_inv ||
918 rel_dist_centers > configLocaliser.dist_threshold)
921 cout <<
"Binary false: dist_centers1 with " << neigRef.
id 928 else if (RefBothFull || CheckBothFull)
930 if (rel_dist_centers < configLocaliser.dist_threshold_inv ||
931 rel_dist_centers > configLocaliser.dist_threshold)
934 cout <<
"Binary false: dist_centers2 with " << neigRef.
id 944 if (rel_dist_centers < configLocaliser.dist_threshold_inv ||
945 rel_dist_centers > configLocaliser.dist_threshold)
948 cout <<
"Binary false: dist_centers3 with " << neigRef.
id 961 if (rel_dist_centers < configLocaliser.dist_threshold_inv ||
962 rel_dist_centers > configLocaliser.dist_threshold)
965 cout <<
"Binary false: dist_centers4 with " << neigRef.
id 977 cout <<
"BINARY TRUE\n" << endl;
984 map<unsigned, unsigned>& contained, map<unsigned, unsigned>& container)
986 if (contained.size() > container.size())
return false;
990 it != contained.end(); it++)
991 if (container.count(it->first) == 0)
993 else if (container[it->first] != it->second)
997 cout <<
"Repeated sequence. Comparing:\n";
999 it != contained.end(); it++)
1000 cout << it->first <<
" " << it->second << endl;
1003 it != container.end(); it++)
1004 cout << it->first <<
" " << it->second << endl;
1017 void SubgraphMatcher::exploreSubgraphTreeR(
1018 set<unsigned>& sourcePlanes, set<unsigned>& targetPlanes,
1019 map<unsigned, unsigned>& matched)
1022 cout <<
"matched: " << matched.size() <<
"\n";
1024 it != matched.end(); it++)
1025 cout << it->first <<
" - " << it->second <<
" =" 1026 << subgraphTrg->pPBM->vPlanes[it->second].label << endl;
1027 cout <<
"sourcePlanes: " << sourcePlanes.size() <<
": ";
1029 it1 != sourcePlanes.end(); it1++)
1030 cout << *it1 <<
" ";
1031 cout <<
"\ntargetPlanes " << targetPlanes.size() <<
": ";
1033 it2 != targetPlanes.end(); it2++)
1034 cout << *it2 <<
" ";
1044 unsigned requiredMatches =
1045 max(configLocaliser.min_planes_recognition,
1046 static_cast<unsigned>(winnerMatch.size()));
1067 while (!sourcePlanes.empty())
1071 cout <<
"Compare " << *it1
1072 <<
" Compare Compare Compare Compare Compare " << endl;
1075 if ((matched.size() +
min(sourcePlanes.size(), targetPlanes.size())) <=
1079 cout <<
"End branch recursive search. Too short " << matched.size()
1080 <<
" prev winner " << winnerMatch.size() << endl;
1097 it2 != targetPlanes.end(); it2++)
1100 cout <<
" " << *it1 <<
" with " << *it2 << endl;
1134 if (hashUnaryConstraints[*it1][*it2] != 1)
1139 bool binaryFail =
false;
1141 it_matched != matched.end(); it_matched++)
1142 if (!evalBinaryConstraints(
1143 subgraphSrc->pPBM->vPlanes[*it1],
1144 subgraphSrc->pPBM->vPlanes[it_matched->first],
1145 subgraphTrg->pPBM->vPlanes[*it2],
1146 subgraphTrg->pPBM->vPlanes[it_matched->second]))
1151 if (binaryFail)
continue;
1156 set<unsigned> nextSrcPlanes = sourcePlanes;
1157 nextSrcPlanes.erase(*it1);
1158 set<unsigned> nextTrgPlanes = targetPlanes;
1159 nextTrgPlanes.erase(*it2);
1160 map<unsigned, unsigned> nextMatched = matched;
1161 nextMatched[*it1] = *it2;
1163 alreadyExplored.push_back(nextMatched);
1165 exploreSubgraphTreeR(nextSrcPlanes, nextTrgPlanes, nextMatched);
1171 sourcePlanes.erase(it1);
1174 if (matched.size() > winnerMatch.size())
1176 float areaMatched = calcAreaMatched(matched);
1179 cout <<
"End branch recursive search. matched " << matched.size()
1180 <<
" A " << areaMatched <<
" prev winner " << winnerMatch.size()
1181 <<
" A " << areaWinnerMatch << endl;
1183 areaWinnerMatch = areaMatched;
1184 winnerMatch = matched;
1188 void SubgraphMatcher::exploreSubgraphTreeR_Area(
1189 set<unsigned>& sourcePlanes, set<unsigned>& targetPlanes,
1190 map<unsigned, unsigned>& matched)
1193 cout <<
"matched: " << matched.size() <<
"\n";
1195 it != matched.end(); it++)
1196 cout << it->first <<
" - " << it->second <<
" =" 1197 << subgraphTrg->pPBM->vPlanes[it->second].label << endl;
1198 cout <<
"sourcePlanes: " << sourcePlanes.size() <<
": ";
1200 it1 != sourcePlanes.end(); it1++)
1201 cout << *it1 <<
" ";
1202 cout <<
"\ntargetPlanes " << targetPlanes.size() <<
": ";
1204 it2 != targetPlanes.end(); it2++)
1205 cout << *it2 <<
" ";
1215 float matchedArea = calcAreaMatched(matched);
1217 float unmatchedArea = 0;
1219 it1 != sourcePlanes.end(); it1++)
1220 unmatchedArea += subgraphSrc->pPBM->vPlanes[*it1].areaHull;
1225 while (!sourcePlanes.empty())
1229 cout <<
"Compare " << *it1
1230 <<
" Compare Compare Compare Compare Compare " << endl;
1233 if ((matched.size() +
min(sourcePlanes.size(), targetPlanes.size())) <=
1234 configLocaliser.min_planes_recognition)
1235 if ((matchedArea + unmatchedArea) < areaWinnerMatch)
1238 cout <<
"End branch recursive search. Too short " 1239 << matched.size() <<
" prev winner " << winnerMatch.size()
1257 it2 != targetPlanes.end(); it2++)
1260 cout <<
" " << *it1 <<
" with " << *it2 << endl;
1294 if (hashUnaryConstraints[*it1][*it2] != 1)
1299 bool binaryFail =
false;
1301 it_matched != matched.end(); it_matched++)
1302 if (!evalBinaryConstraints(
1303 subgraphSrc->pPBM->vPlanes[*it1],
1304 subgraphSrc->pPBM->vPlanes[it_matched->first],
1305 subgraphTrg->pPBM->vPlanes[*it2],
1306 subgraphTrg->pPBM->vPlanes[it_matched->second]))
1311 if (binaryFail)
continue;
1316 set<unsigned> nextSrcPlanes = sourcePlanes;
1317 nextSrcPlanes.erase(*it1);
1318 set<unsigned> nextTrgPlanes = targetPlanes;
1319 nextTrgPlanes.erase(*it2);
1320 map<unsigned, unsigned> nextMatched = matched;
1321 nextMatched[*it1] = *it2;
1323 alreadyExplored.push_back(nextMatched);
1325 exploreSubgraphTreeR_Area(
1326 nextSrcPlanes, nextTrgPlanes, nextMatched);
1332 sourcePlanes.erase(it1);
1336 float areaMatched = calcAreaMatched(matched);
1337 if (areaMatched > areaWinnerMatch)
1340 cout <<
"End branch recursive search. matched " << matched.size()
1341 <<
" A " << areaMatched <<
" prev winner " << winnerMatch.size()
1342 <<
" A " << areaWinnerMatch << endl;
1344 areaWinnerMatch = areaMatched;
1345 winnerMatch = matched;
1349 float SubgraphMatcher::calcAreaMatched(
1350 std::map<unsigned, unsigned>& matched_planes)
1352 float areaMatched = 0;
1354 it != matched_planes.end(); it++)
1355 areaMatched += subgraphSrc->pPBM->vPlanes[it->first].areaHull;
1360 float SubgraphMatcher::calcAreaUnmatched(std::set<unsigned>& unmatched_planes)
1362 float areaUnatched = 0;
1364 it != unmatched_planes.end(); it++)
1365 areaUnatched += subgraphSrc->pPBM->vPlanes[*it].areaHull;
1367 return areaUnatched;
1405 std::map<unsigned, unsigned> SubgraphMatcher::compareSubgraphs(
1409 subgraphSrc = &subgraphSource;
1410 subgraphTrg = &subgraphTarget;
1411 map<unsigned, unsigned> matched;
1413 areaWinnerMatch = 0;
1414 winnerMatch.clear();
1415 alreadyExplored.clear();
1418 std::set<unsigned> targetPlanes = subgraphTrg->subgraphPlanesIdx;
1421 cout <<
"Source planes: ";
1423 it2 != sourcePlanes.end(); it2++)
1424 cout <<
" " << *it2;
1426 cout <<
"Target planes: ";
1428 it2 != targetPlanes.end(); it2++)
1429 cout <<
" " << *it2;
1434 hashUnaryConstraints = std::vector<std::vector<int8_t>>(
1435 subgraphSrc->pPBM->vPlanes.size(),
1436 std::vector<int8_t>(subgraphTrg->pPBM->vPlanes.size()));
1439 it1 != sourcePlanes.end(); it1++)
1441 it2 != targetPlanes.end(); it2++)
1442 hashUnaryConstraints[*it1][*it2] =
1443 (evalUnaryConstraints(
1444 subgraphSrc->pPBM->vPlanes[*it1],
1445 subgraphTrg->pPBM->vPlanes[*it2], *subgraphTrg->pPBM,
1449 else if (option == 1)
1451 it1 != sourcePlanes.end(); it1++)
1453 it2 != targetPlanes.end(); it2++)
1454 hashUnaryConstraints[*it1][*it2] =
1455 (evalUnaryConstraintsOdometry(
1456 subgraphSrc->pPBM->vPlanes[*it1],
1457 subgraphTrg->pPBM->vPlanes[*it2], *subgraphTrg->pPBM,
1461 else if (option == 2)
1464 it1 != sourcePlanes.end(); it1++)
1466 it2 != targetPlanes.end(); it2++)
1467 hashUnaryConstraints[*it1][*it2] =
1468 (evalUnaryConstraints2D(
1469 subgraphSrc->pPBM->vPlanes[*it1],
1470 subgraphTrg->pPBM->vPlanes[*it2], *subgraphTrg->pPBM,
1474 else if (option == 3)
1477 it1 != sourcePlanes.end(); it1++)
1479 it2 != targetPlanes.end(); it2++)
1480 hashUnaryConstraints[*it1][*it2] =
1481 (evalUnaryConstraintsOdometry2D(
1482 subgraphSrc->pPBM->vPlanes[*it1],
1483 subgraphTrg->pPBM->vPlanes[*it2], *subgraphTrg->pPBM,
1488 exploreSubgraphTreeR(sourcePlanes, targetPlanes, matched);
1491 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).
for(ctr=DCTSIZE;ctr > 0;ctr--)
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)