64 switch (options.methodSelection)
66 case CGridMapAligner::amCorrelation:
67 return AlignPDF_correlation(
68 mm1, mm2, initialEstimationPDF, runningTime, info);
70 case CGridMapAligner::amModifiedRANSAC:
71 case CGridMapAligner::amRobustMatch:
73 return AlignPDF_robustMatch(
74 mm1, mm2, initialEstimationPDF, runningTime, info);
83 bool myVectorOrder(
const pair<size_t, float>& o1,
const pair<size_t, float>& o2)
85 return o1.second < o2.second;
99 options.methodSelection == CGridMapAligner::amRobustMatch ||
100 options.methodSelection == CGridMapAligner::amModifiedRANSAC)
104 outInfo.correspondences;
115 std::vector<size_t> idxs1, idxs2;
145 "Metric maps must be of classes COccupancyGridMap2D or "
151 "Different resolutions for m1, m2:\n"
152 "\tres(m1) = %f\n\tres(m2) = %f\n",
157 outInfo.goodness = 1.0f;
159 outInfo.landmarks_map1 = lm1;
160 outInfo.landmarks_map2 = lm2;
168 const size_t N1 = std::max(
170 const size_t N2 = std::max(
173 m_grid_feat_extr.extractFeatures(
174 *m1, *lm1, N1, options.feature_descriptor,
175 options.feature_detector_options);
176 m_grid_feat_extr.extractFeatures(
177 *m2, *lm2, N2, options.feature_descriptor,
178 options.feature_detector_options);
186 const size_t nLM1 = lm1->size();
187 const size_t nLM2 = lm2->size();
191 if (nLM1 < 2 || nLM2 < 2)
193 outInfo.goodness = 0;
203 CImage im1(1, 1, 1), im2(1, 1, 1);
205 unsigned int corrsCount = 0;
206 std::vector<bool> hasCorr(nLM1,
false);
208 const double thres_max = options.threshold_max;
209 const double thres_delta = options.threshold_delta;
212 if (options.debug_show_corrs)
216 std::cerr <<
"Warning: options.debug_show_corrs has no effect "
217 "since MRPT 0.9.1\n";
220 for (
size_t idx1 = 0; idx1 < nLM1; idx1++)
223 vector<pair<size_t, float>> corrs_indiv;
227 vector<float> corrs_indiv_only;
228 corrs_indiv.reserve(nLM2);
229 corrs_indiv_only.reserve(nLM2);
231 for (
size_t idx2 = 0; idx2 < nLM2; idx2++)
235 lm1->landmarks.get(idx1)->features[0]->descriptorDistanceTo(
236 *lm2->landmarks.get(idx2)->features[0]);
238 corrs_indiv.push_back(std::make_pair(idx2, minDist));
239 corrs_indiv_only.push_back(minDist);
249 std::sort(corrs_indiv.begin(), corrs_indiv.end(),
myVectorOrder);
253 const size_t nBestToKeep = corrs_indiv.size();
255 for (
size_t w = 0;
w < nBestToKeep;
w++)
257 if (corrs_indiv[
w].second <= thres_max &&
258 corrs_indiv[
w].second <= (corr_best + thres_delta))
260 idxs1.push_back(idx1);
261 idxs2.push_back(corrs_indiv[
w].
first);
262 outInfo.correspondences_dists_maha.push_back(
264 idx1, corrs_indiv[
w].
first, corrs_indiv[
w].second));
269 if (options.debug_show_corrs)
271 auxWin->setWindowTitle(
format(
"Corr: %i - rest",
int(idx1)));
273 auxWin->plot(corrs_indiv_only,
".3",
"the_corr");
276 xs[0]=0; xs[1]=corrs_indiv_only.size()+1;
278 ys[0]=ys[1] = corr_best+thres_delta;
279 auxWin->plot(xs,ys,
"g",
"the_thres");
281 if (idx1==0) auxWin->axis_fit();
282 auxWin->waitForKey();
289 if (options.save_feat_coors)
294 std::map<size_t, std::set<size_t>> corrs_by_idx;
295 for (
size_t l = 0; l < idxs1.size(); l++)
296 corrs_by_idx[idxs1[l]].insert(idxs2[l]);
298 for (std::map<
size_t, std::set<size_t>>::
iterator it =
299 corrs_by_idx.begin();
300 it != corrs_by_idx.end(); ++it)
303 lm1->landmarks.get(it->first)
305 ->getFirstDescriptorAsMatrix(descriptor1);
307 im1 =
CImage(descriptor1,
true);
309 const size_t FEAT_W = im1.getWidth();
310 const size_t FEAT_H = im1.getHeight();
311 const size_t nF = it->second.size();
313 CImage img_compose(FEAT_W * 2 + 15, 10 + (5 + FEAT_H) * nF);
323 format(
"grid_feats/_FEAT_MATCH_%03i", (
int)it->first);
325 for (j = 0, it_j = it->second.begin(); j < nF; ++j, ++it_j)
327 fil +=
format(
"_%u",
static_cast<unsigned int>(*it_j));
330 lm2->landmarks.get(*it_j)
332 ->getFirstDescriptorAsMatrix(descriptor2);
333 im2 =
CImage(descriptor2,
true);
335 10 + FEAT_W, 5 + j * (FEAT_H + 5), im2);
345 correspondences.clear();
346 for (it1 = idxs1.begin(), it2 = idxs2.begin(); it1 != idxs1.end();
351 mp.
this_x = lm1->landmarks.get(*it1)->pose_mean.x;
352 mp.
this_y = lm1->landmarks.get(*it1)->pose_mean.y;
353 mp.
this_z = lm1->landmarks.get(*it1)->pose_mean.z;
356 mp.
other_x = lm2->landmarks.get(*it2)->pose_mean.x;
357 mp.
other_y = lm2->landmarks.get(*it2)->pose_mean.y;
358 mp.
other_z = lm2->landmarks.get(*it2)->pose_mean.z;
359 correspondences.push_back(mp);
363 hasCorr[*it1] =
true;
368 outInfo.goodness = (2.0f * corrsCount) / (nLM1 + nLM2);
376 outInfo.goodness = 0;
378 outInfo.sog1 = pdf_SOG;
379 outInfo.sog2 = pdf_SOG;
380 outInfo.sog3 = pdf_SOG;
387 "[CGridMapAligner] Overall estimation(%u corrs, total: "
388 "%u): (%.03f,%.03f,%.03fdeg)\n",
389 corrsCount, (
unsigned)correspondences.size(),
390 outInfo.noRobustEstimation.x(),
391 outInfo.noRobustEstimation.y(),
392 RAD2DEG(outInfo.noRobustEstimation.phi())));
398 TMapMatchingsToPoseMode;
399 TMapMatchingsToPoseMode sog_modes;
406 if (options.methodSelection == CGridMapAligner::amRobustMatch)
414 const unsigned int min_inliers =
415 options.ransac_minSetSizeRatio * (nLM1 + nLM2) / 2;
421 options.ransac_mahalanobisDistanceThreshold;
428 options.ransac_prob_good_inliers;
433 correspondences, options.ransac_SOG_sigma_m, tfest_params,
442 size_t nB = pdf_SOG->size();
443 outInfo.sog1 = pdf_SOG;
447 best_mode.
log_w = -std::numeric_limits<double>::max();
449 for (
size_t n = 0;
n < pdf_SOG->size();
n++)
457 pdf_SOG->push_back(best_mode);
458 outInfo.sog2 = pdf_SOG;
461 "[CGridMapAligner] amRobustMatch: "
462 << nB <<
" SOG modes reduced to " << pdf_SOG->size()
463 <<
" (most-likely) (min.inliers=" << min_inliers <<
")\n");
473 const size_t nCorrs = all_corrs.size();
482 for (
size_t i = 0; i < nLM1; i++)
483 lm1_pnts.
insertPoint(lm1->landmarks.get(i)->pose_mean);
485 for (
size_t i = 0; i < nLM2; i++)
486 lm2_pnts.
insertPoint(lm2->landmarks.get(i)->pose_mean);
490 const size_t minInliersTOaccept =
491 round(options.ransac_minSetSizeRatio * 0.5 * (nLM1 + nLM2));
493 const unsigned int ransac_min_nSimulations =
495 unsigned int ransac_nSimulations =
498 const double probability_find_good_model = 0.9999;
500 const double chi2_thres_dim1 =
502 const double chi2_thres_dim2 =
508 COV_pnt.get_unsafe(0, 0) = COV_pnt.get_unsafe(1, 1) =
509 square(options.ransac_SOG_sigma_m);
519 const unsigned int max_trials =
520 (nCorrs * (nCorrs - 1) / 2) *
523 unsigned int iter = 0;
525 unsigned int trials = 0;
527 while (iter < ransac_nSimulations &&
541 }
while (idx1 == idx2);
544 if (all_corrs[idx1].this_idx == all_corrs[idx2].this_idx ||
545 all_corrs[idx1].this_idx == all_corrs[idx2].other_idx)
547 if (all_corrs[idx1].other_idx == all_corrs[idx2].this_idx ||
548 all_corrs[idx1].other_idx == all_corrs[idx2].other_idx)
555 const double corrs_dist1 =
557 all_corrs[idx1].this_x, all_corrs[idx1].this_y,
558 all_corrs[idx1].this_z, all_corrs[idx2].this_x,
559 all_corrs[idx2].this_y, all_corrs[idx2].this_z);
561 const double corrs_dist2 =
563 all_corrs[idx1].other_x, all_corrs[idx1].other_y,
564 all_corrs[idx1].other_z, all_corrs[idx2].other_x,
565 all_corrs[idx2].other_y, all_corrs[idx2].other_z);
569 const double corrs_dist_chi2 =
571 (8.0 *
square(options.ransac_SOG_sigma_m) *
574 if (corrs_dist_chi2 > chi2_thres_dim1)
continue;
580 bool is_new_hyp =
true;
583 itOldHyps != sog_modes.end(); ++itOldHyps)
585 if (itOldHyps->first.contains(all_corrs[idx1]) &&
586 itOldHyps->first.contains(all_corrs[idx2]))
589 itOldHyps->second.log_w = std::log(
590 std::exp(itOldHyps->second.log_w) + 1.0);
595 if (!is_new_hyp)
continue;
598 tentativeSubSet.push_back(all_corrs[idx1]);
599 tentativeSubSet.push_back(all_corrs[idx2]);
606 used_landmarks1[all_corrs[idx1].this_idx] =
true;
607 used_landmarks1[all_corrs[idx2].this_idx] =
true;
608 used_landmarks2[all_corrs[idx1].other_idx] =
true;
609 used_landmarks2[all_corrs[idx2].other_idx] =
true;
613 bool keep_incorporating =
true;
622 temptPose.
cov *=
square(options.ransac_SOG_sigma_m);
630 const double ccos = cos(temptPose.
mean.
phi());
631 const double ssin = sin(temptPose.
mean.
phi());
634 Hc.get_unsafe(1, 1) = ccos;
635 Hc.get_unsafe(0, 0) = ccos;
636 Hc.get_unsafe(1, 0) = ssin;
637 Hc.get_unsafe(0, 1) = -ssin;
645 vector<float> matches_dist;
646 std::vector<size_t> matches_idx;
652 #define GRIDMAP_USE_PROD_INTEGRAL
654 #ifdef GRIDMAP_USE_PROD_INTEGRAL
655 double best_pair_value = 0;
657 double best_pair_value =
658 std::numeric_limits<double>::max();
660 double best_pair_d2 =
661 std::numeric_limits<double>::max();
662 pair<size_t, size_t> best_pair_ij;
667 CDisplayWindowPlots win(
"Matches");
669 for (
size_t j = 0; j < nLM2; j++)
671 if (used_landmarks2[j])
continue;
678 pdf_M2_j.
cov.get_unsafe(0, 0) =
679 pdf_M2_j.
cov.get_unsafe(1, 1) =
680 square(options.ransac_SOG_sigma_m);
685 pdf_M2_j.
cov, 2,
"b-",
686 format(
"M2_%u", (
unsigned)j),
true);
689 static const unsigned int N_KDTREE_SEARCHED = 3;
695 N_KDTREE_SEARCHED, matches_idx, matches_dist);
698 for (
size_t u = 0; u < matches_idx.size(); u++)
700 if (used_landmarks1[matches_idx[u]])
continue;
703 Hq.get_unsafe(0, 2) =
704 -p2_j_local.
x * ssin - p2_j_local.
y * ccos;
705 Hq.get_unsafe(1, 2) =
706 p2_j_local.
x * ccos - p2_j_local.
y * ssin;
709 Hc.multiply_HCHt(COV_pnt, pdf_M1_i.
cov);
711 temptPose.
cov, pdf_M1_i.
cov,
true);
714 lm1_pnts.
getPoint(matches_idx[u], px, py);
721 pdf_M1_i.
cov, 2,
"r-",
722 format(
"M1_%u", (
unsigned)matches_idx[u]),
727 #ifdef GRIDMAP_USE_PROD_INTEGRAL
728 const double prod_ij =
733 if (prod_ij > best_pair_value)
735 const double prod_ij =
737 if (prod_ij < best_pair_value)
743 best_pair_value = prod_ij;
744 best_pair_ij.first = matches_idx[u];
745 best_pair_ij.second = j;
770 keep_incorporating =
false;
773 if (best_pair_d2 < chi2_thres_dim2)
782 float p1_i_localx, p1_i_localy;
783 float p2_j_localx, p2_j_localy;
785 best_pair_ij.first, p1_i_localx,
788 best_pair_ij.second, p2_j_localx,
791 used_landmarks1[best_pair_ij.first] =
true;
792 used_landmarks2[best_pair_ij.second] =
true;
794 tentativeSubSet.push_back(
796 best_pair_ij.first, best_pair_ij.second,
797 p1_i_localx, p1_i_localy, 0,
798 p2_j_localx, p2_j_localy, 0
801 keep_incorporating =
true;
805 }
while (keep_incorporating);
808 const size_t ninliers = tentativeSubSet.size();
809 if (ninliers > minInliersTOaccept)
815 newGauss.
cov = temptPose.
cov;
817 sog_modes[tentativeSubSet] = newGauss;
824 if (largestConsensusCorrs.size() < ninliers)
826 largestConsensusCorrs = tentativeSubSet;
831 const double fracinliers =
833 static_cast<double>(
std::min(nLM1, nLM2));
839 pNoOutliers = std::max(
840 std::numeric_limits<double>::epsilon(),
843 1.0 - std::numeric_limits<double>::epsilon(),
846 ransac_nSimulations =
847 log(1 - probability_find_good_model) /
850 if (ransac_nSimulations < ransac_min_nSimulations)
851 ransac_nSimulations = ransac_min_nSimulations;
865 s != sog_modes.end(); ++
s)
867 cout <<
"SOG mode: " <<
s->second.mean
868 <<
" inliers: " <<
s->first.size() << endl;
869 pdf_SOG->push_back(
s->second);
873 if (pdf_SOG->size() > 0) pdf_SOG->normalizeWeights();
877 size_t nB = pdf_SOG->size();
878 outInfo.sog1 = pdf_SOG;
881 pdf_SOG->mergeModes(options.maxKLd_for_merge,
false);
882 const double merge_clock_tim = merge_clock.
Tac();
884 outInfo.sog2 = pdf_SOG;
885 size_t nA = pdf_SOG->size();
888 "[CGridMapAligner] amModifiedRANSAC: %u SOG modes "
889 "merged to %u in %.03fsec\n",
890 (
unsigned int)nB, (
unsigned int)nA, merge_clock_tim));
895 if (options.debug_save_map_pairs)
897 static unsigned int NN = 0;
905 " Largest consensus: %u\n",
906 static_cast<unsigned>(largestConsensusCorrs.size()));
914 s != sog_modes.end(); ++
s)
916 COccupancyGridMap2D::saveAsEMFTwoMapsWithCorrespondences(
917 format(
"__debug_corrsGrid_%05u.emf", NN), m1, m2,
919 COccupancyGridMap2D::saveAsBitmapTwoMapsWithCorrespondences(
920 format(
"__debug_corrsGrid_%05u.png", NN), m1, m2,
954 outInfo.icp_goodness_all_sog_modes.clear();
956 i != pdf_SOG->end(); ++cnt)
959 pnts1.get(), pnts2.get(), (i)->mean,
nullptr, &icpInfo);
968 const double icp_maha_dist =
971 cout <<
"ICP " << cnt <<
" log-w: " << i->log_w
972 <<
" Goodness: " << 100 * icpInfo.
goodness
973 <<
" D_M= " << icp_maha_dist << endl;
974 cout <<
" final pos: " << icp_est->getMeanVal() << endl;
975 cout <<
" org pos: " << i->mean << endl;
977 outInfo.icp_goodness_all_sog_modes.push_back(
981 if (icpInfo.
goodness > options.min_ICP_goodness &&
982 icp_maha_dist < options.max_ICP_mahadist)
984 icp_est->getMean((i)->
mean);
990 i = pdf_SOG->erase(i);
996 outInfo.sog3 = pdf_SOG;
998 pdf_SOG->mergeModes(options.maxKLd_for_merge,
false);
1000 "[CGridMapAligner] " << pdf_SOG->size()
1001 <<
" SOG modes merged after ICP.");
1012 "Refactor `info` so it is polymorphic and can use dynamic_cast<> here");
1021 *runningTime = tictac->
Tac();
1070 float phiResolution =
DEG2RAD(0.2f);
1071 float phiMin = -
M_PIf + 0.5f * phiResolution;
1072 float phiMax =
M_PIf;
1080 CImage map1_img, map2_img;
1081 float currentMaxCorr = -1e6f;
1088 size_t map2_lx = map2_mod.
getSizeX();
1089 size_t map2_ly = map2_mod.
getSizeY();
1090 CMatrix outCrossCorr, bestCrossCorr;
1091 float map2width_2 = 0.5f * (map2_mod.
getXMax() - map2_mod.
getXMin());
1093 #ifdef CORRELATION_SHOW_DEBUG
1094 CDisplayWindow* win =
new CDisplayWindow(
"corr");
1095 CDisplayWindow* win2 =
new CDisplayWindow(
"map2_mod");
1101 for (phi = phiMin; phi < phiMax; phi += phiResolution)
1106 pivotPt_x - cos(phi) * map2width_2,
1107 pivotPt_y - sin(phi) * map2width_2,
1112 for (
unsigned int cy2 = 0; cy2 < map2_ly; cy2++)
1115 for (
unsigned int cx2 = 0; cx2 < map2_lx; cx2++)
1127 map2_img, outCrossCorr, -1, -1, -1, -1,
1132 float corrPeak = outCrossCorr.maxCoeff();
1133 printf(
"phi = %fdeg \tmax corr=%f\n",
RAD2DEG(phi), corrPeak);
1136 if (corrPeak > currentMaxCorr)
1138 currentMaxCorr = corrPeak;
1139 bestCrossCorr = outCrossCorr;
1143 #ifdef CORRELATION_SHOW_DEBUG
1144 outCrossCorr.adjustRange(0, 1);
1145 CImage aux(outCrossCorr,
true);
1146 win->showImage(aux);
1147 win2->showImage(map2_img);
1148 std::this_thread::sleep_for(5ms);
1155 *runningTime = tictac->Tac();
1159 bestCrossCorr.normalize(0, 1);
1160 CImage aux(bestCrossCorr,
true);
1163 #ifdef CORRELATION_SHOW_DEBUG
1169 CMatrix::Index uMax, vMax;
1170 currentMaxCorr = bestCrossCorr.maxCoeff(&uMax, &vMax);
1172 PDF->mean.x(m1->
idx2x(uMax));
1173 PDF->mean.y(m1->
idx2y(vMax));
1184 CGridMapAligner::TConfigParams::TConfigParams()
1188 feature_detector_options(),
1190 ransac_minSetSizeRatio(0.20f),
1191 ransac_SOG_sigma_m(0.10f),
1193 ransac_chi2_quantile(0.99),
1194 ransac_prob_good_inliers(0.9999),
1195 featsPerSquareMeter(0.015f),
1196 threshold_max(0.15f),
1197 threshold_delta(0.10f),
1198 min_ICP_goodness(0.30f),
1199 max_ICP_mahadist(10.0),
1200 maxKLd_for_merge(0.9),
1202 save_feat_coors(false),
1203 debug_show_corrs(false),
1204 debug_save_map_pairs(false)
1215 "\n----------- [CGridMapAligner::TConfigParams] ------------ \n\n");
1235 feature_detector_options.dumpToTextStream(out);
1247 iniFile.
read_enum(section,
"methodSelection", methodSelection);
1250 featsPerSquareMeter,
float, iniFile, section)
1261 ransac_minSetSizeRatio,
float, iniFile, section)
1265 ransac_chi2_quantile,
double, iniFile, section)
1267 ransac_prob_good_inliers,
double, iniFile, section)
1274 section,
"feature_descriptor", feature_descriptor,
true);
1275 feature_detector_options.loadFromConfigFile(iniFile, section);
#define MRPT_LOAD_CONFIG_VAR_NO_DEFAULT( variableName, variableType, configFileObject, sectionNameStr)
#define MRPT_LOAD_CONFIG_VAR( variableName, variableType, configFileObject, sectionNameStr)
An useful macro for loading variables stored in a INI-like file under a key with the same name that t...
bool myVectorOrder(const pair< size_t, float > &o1, const pair< size_t, float > &o2)
#define LOADABLEOPTS_DUMP_VAR(variableName, variableType)
Macro for dumping a variable to a stream, within the method "dumpToTextStream(out)" (Variable types a...
#define IS_CLASS(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of t...
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
#define MRPT_LOG_DEBUG_STREAM(__CONTENTS)
#define MRPT_LOG_INFO_STREAM(__CONTENTS)
#define MRPT_LOG_INFO(_STRING)
A class for storing a map of 3D probabilistic landmarks.
std::shared_ptr< CLandmarksMap > Ptr
Declares a virtual base class for all metric maps storage classes.
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const override
Returns information about the class of an object in runtime.
This class stores any customizable set of metric maps.
ProxyFilterContainerByClass< mrpt::maps::CSimplePointsMap::Ptr, TListMaps > m_pointsMaps
STL-like proxy to access this kind of maps in maps.
ProxyFilterContainerByClass< mrpt::maps::COccupancyGridMap2D::Ptr, TListMaps > m_gridMaps
STL-like proxy to access this kind of maps in maps.
A class for storing an occupancy grid map.
float getResolution() const
Returns the resolution of the grid map.
float getYMin() const
Returns the "y" coordinate of top side of grid map.
float idx2y(const size_t cy) const
unsigned int getSizeX() const
Returns the horizontal size of grid map in cells count.
cellType * getRow(int cy)
Access to a "row": mainly used for drawing grid as a bitmap efficiently, do not use it normally.
float getXMax() const
Returns the "x" coordinate of right side of grid map.
float getYMax() const
Returns the "y" coordinate of bottom side of grid map.
float getPos(float x, float y) const
Read the real valued [0,1] contents of a cell, given its coordinates.
void getAsImage(utils::CImage &img, bool verticalFlip=false, bool forceRGB=false, bool tricolor=false) const
Returns the grid as a 8-bit graylevel image, where each pixel is a cell (output image is RGB only if ...
unsigned int getSizeY() const
Returns the vertical size of grid map in cells count.
float getXMin() const
Returns the "x" coordinate of left side of grid map.
void setSize(float x_min, float x_max, float y_min, float y_max, float resolution, float default_value=0.5f)
Change the size of gridmap, erasing all its previous contents.
float idx2x(const size_t cx) const
Transform a cell index into a coordinate value.
double getArea() const
Returns the area of the gridmap, in square meters.
static cellType p2l(const float p)
Scales a real valued probability in [0,1] to an integer representation of: log(p)-log(1-p) in the val...
int16_t cellType
The type of the map cells:
unsigned long getPoint(size_t index, float &x, float &y, float &z) const
Access to a given point from map, as a 2D point.
void insertPoint(float x, float y, float z=0)
Provides a way to insert (append) individual points into the map: the missing fields of child classes...
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans.
virtual void reserve(size_t newLength) override
Reserves memory for a given number of points: the size of the map does not change,...
std::shared_ptr< CSimplePointsMap > Ptr
A numeric matrix of compile-time fixed size.
This class is a "CSerializable" wrapper for "CMatrixFloat".
A matrix of dynamic size.
void kdTreeNClosestPoint2DIdx(float x0, float y0, size_t knn, std::vector< size_t > &out_idx, std::vector< float > &out_dist_sqr) const
KD Tree-based search for the N closest point to some given 2D coordinates and returns their indexes.
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction.
A class used to store a 2D point.
A gaussian distribution for 2D points.
double productIntegralWith(const CPoint2DPDFGaussian &p) const
Computes the "correspondence likelihood" of this PDF with another one: This is implemented as the int...
CPoint2D mean
The mean value.
double mahalanobisDistanceTo(const CPoint2DPDFGaussian &other) const
Returns the Mahalanobis distance from this PDF to another PDF, that is, it's evaluation at (0,...
mrpt::math::CMatrixDouble22 cov
The 2x2 covariance matrix.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle.
const double & phi() const
Get the phi angle of the 2D pose (in radians)
Declares a class that represents a Probability Density function (PDF) of a 3D pose .
std::shared_ptr< CPose3DPDF > Ptr
double x() const
Common members of all points & poses classes.
double distanceTo(const CPoseOrPoint< OTHERCLASS > &b) const
Returns the Euclidean distance to another pose/point:
Declares a class that represents a Probability Density function (PDF) of a 2D pose .
CPose2D mean
The mean value.
std::shared_ptr< CPosePDFGaussian > Ptr
mrpt::math::CMatrixDouble33 cov
The 3x3 covariance matrix.
double mahalanobisDistanceTo(const CPosePDFGaussian &theOther)
Computes the Mahalanobis distance between the centers of two Gaussians.
std::shared_ptr< CPosePDF > Ptr
std::shared_ptr< CPosePDFSOG > Ptr
CListGaussianModes::iterator iterator
uint32_t drawUniform32bit()
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm,...
void dumpToTextStream(mrpt::utils::CStream &out) const override
This method should clearly display all the contents of the structure in textual form,...
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) override
This method load the options from a ".ini"-like file or memory-stored string list.
A class for aligning two multi-metric maps (with an occupancy grid maps and a points map,...
mrpt::poses::CPose3DPDF::Ptr Align3DPDF(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPose3DPDFGaussian &initialEstimationPDF, float *runningTime=nullptr, void *info=nullptr)
Not applicable in this class, will launch an exception.
unsigned int maxIterations
Maximum number of iterations to run.
float smallestThresholdDist
The size for threshold such that iterations will stop, since it is considered precise enough.
float thresholdDist
Initial threshold distance for two points to become a correspondence.
Several implementations of ICP (Iterative closest point) algorithms for aligning two point maps or a ...
TConfigParams options
The options employed by the ICP align.
mrpt::poses::CPosePDF::Ptr Align(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPose2D &grossEst, float *runningTime=nullptr, void *info=nullptr)
The method for aligning a pair of metric maps, aligning only 2D + orientation.
virtual void drawImage(int x, int y, const utils::CImage &img)
Draws an image as a bitmap at a given position.
virtual void filledRectangle(int x0, int y0, int x1, int y1, const mrpt::utils::TColor color)
Draws a filled rectangle.
This class allows loading and storing values and vectors of different types from a configuration text...
ENUMTYPE read_enum(const std::string §ion, const std::string &name, const ENUMTYPE &defaultValue, bool failIfNotFound=false) const
Reads an "enum" value, where the value in the config file can be either a numerical value or the symb...
A class for storing images as grayscale or RGB bitmaps.
void cross_correlation_FFT(const CImage &in_img, math::CMatrixFloat &out_corr, int u_search_ini=-1, int v_search_ini=-1, int u_search_size=-1, int v_search_size=-1, float biasThisImg=0, float biasInImg=0) const
Computes the correlation matrix between this image and another one.
size_t getHeight() const override
Returns the height of the image in pixels.
size_t getWidth() const override
Returns the width of the image in pixels.
bool saveToFile(const std::string &fileName, int jpeg_quality=95) const
Save the image to a file, whose format is determined from the extension (internally uses OpenCV).
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
This class implements a high-performance stopwatch.
double Tac()
Stops the stopwatch.
void Tic()
Starts the stopwatch.
const Scalar * const_iterator
GLenum GLenum GLvoid * row
GLubyte GLubyte GLubyte GLubyte w
GLfloat GLfloat GLfloat v2
GLfloat GLfloat GLfloat GLfloat v3
GLenum GLsizei GLenum format
GLsizei const GLchar ** string
bool deleteFilesInDirectory(const std::string &s, bool deleteDirectoryAsWell=false)
Delete all the files in a given directory (nothing done if directory does not exists,...
bool createDirectory(const std::string &dirName)
Creates a directory.
T distanceBetweenPoints(const T x1, const T y1, const T x2, const T y2)
Returns the distance between 2 points in 2D.
int round(const T value)
Returns the closer integer (int) to x.
std::vector< bool > vector_bool
A type for passing a vector of bools.
bool se2_l2(const mrpt::utils::TMatchingPairList &in_correspondences, mrpt::math::TPose2D &out_transformation, mrpt::math::CMatrixDouble33 *out_estimateCovariance=nullptr)
Least-squares (L2 norm) solution to finding the optimal SE(2) (x,y,yaw) between two reference frames.
bool se2_l2_robust(const mrpt::utils::TMatchingPairList &in_correspondences, const double in_normalizationStd, const TSE2RobustParams &in_ransac_params, TSE2RobustResult &out_results)
Robust least-squares (L2 norm) solution to finding the optimal SE(2) (x,y,yaw) between two reference ...
@ descPolarImages
Polar image descriptor.
double chi2inv(double P, unsigned int dim=1)
The "quantile" of the Chi-Square distribution, for dimension "dim" and probability 0<P<1 (the inverse...
#define THROW_EXCEPTION(msg)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define ASSERTMSG_(f, __ERROR_MSG)
This base provides a set of functions for maths stuff.
CONTAINER::Scalar minimum(const CONTAINER &v)
double mean(const CONTAINER &v)
Computes the mean value of a vector.
T square(const T x)
Inline function for the square of a number.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
A namespace of pseudo-random numbers genrators of diferent distributions.
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
Classes for computer vision, detectors, features, etc.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
This file implements several operations that operate element-wise on individual or pairs of container...
unsigned __int32 uint32_t
const float ransac_mahalanobisDistanceThreshold
Helper types for STL containers with Eigen memory allocators.
The struct for each mode:
mrpt::math::CMatrixDouble33 cov
double log_w
The log-weight.
The ICP algorithm return information.
The ICP algorithm return information.
float goodness
A goodness measure for the alignment, it is a [0,1] range indicator of percentage of correspondences.
Parameters for se2_l2_robust().
unsigned int ransac_nSimulations
(Default = 0) If set to 0, an adaptive algorithm is used to determine the number of iterations,...
bool verbose
(Default=false)
double ransac_fuseMaxDiffXY
(Default = 0.01)
unsigned int ransac_maxSetSize
(Default = 20)
bool ransac_algorithmForLandmarks
(Default = true) Use Mahalanobis distance (true) or Euclidean dist (false)
double ransac_fuseMaxDiffPhi
(Default=0.1degree) (In radians)
double ransac_mahalanobisDistanceThreshold
(Default = 3.0)
bool ransac_fuseByCorrsMatch
(Default = true) If true, the weight of Gaussian modes will be increased when an exact match in the s...
unsigned int ransac_minSetSize
(Default=3)
double probability_find_good_model
(Default = 0.999) See parameter ransac_nSimulations.
Output placeholder for se2_l2_robust()
mrpt::utils::TMatchingPairList largestSubSet
the largest consensus sub-set
mrpt::poses::CPosePDFSOG transformation
The output as a set of transformations (sum of Gaussians)
static constexpr TColor black()
A structure for holding correspondences between two sets of points or points-like entities in 2D or 3...