ICP.cpp
Go to the documentation of this file.
1 // kate: replace-tabs off; indent-width 4; indent-mode normal
2 // vim: ts=4:sw=4:noexpandtab
3 /*
4 
5 Copyright (c) 2010--2012,
6 François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland
7 You can contact the authors at <f dot pomerleau at gmail dot com> and
8 <stephane at magnenat dot net>
9 
10 All rights reserved.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright
15  notice, this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright
17  notice, this list of conditions and the following disclaimer in the
18  documentation and/or other materials provided with the distribution.
19  * Neither the name of the <organization> nor the
20  names of its contributors may be used to endorse or promote products
21  derived from this software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include "PointMatcher.h"
37 #include "PointMatcherPrivate.h"
38 #include "Timer.h"
39 
40 #include "LoggerImpl.h"
41 #include "TransformationsImpl.h"
42 #include "DataPointsFiltersImpl.h"
43 #include "MatchersImpl.h"
44 #include "OutlierFiltersImpl.h"
45 #include "ErrorMinimizersImpl.h"
47 #include "InspectorsImpl.h"
48 
49 #ifdef SYSTEM_YAML_CPP
50  #include "yaml-cpp/yaml.h"
51 #else
52  #include "yaml-cpp-pm/yaml.h"
53 #endif // HAVE_YAML_CPP
54 
55 using namespace std;
56 using namespace PointMatcherSupport;
57 
59 InvalidModuleType::InvalidModuleType(const std::string& reason):
60  runtime_error(reason)
61 {}
62 
64 template<typename T>
66  prefilteredReadingPtsCount(0),
67  prefilteredReferencePtsCount(0),
68  maxNumIterationsReached(false)
69 {}
70 
72 template<typename T>
74 {
75 }
76 
78 template<typename T>
80 {
81  transformations.clear();
85  matcher.reset();
86  outlierFilters.clear();
87  errorMinimizer.reset();
88  transformationCheckers.clear();
89  inspector.reset();
90 }
91 
93 template<typename T>
95 {
96 }
97 
99 template<typename T>
101 {
102  this->cleanup();
103 
104  this->transformations.push_back(std::make_shared<typename TransformationsImpl<T>::RigidTransformation>());
105  this->readingDataPointsFilters.push_back(std::make_shared<typename DataPointsFiltersImpl<T>::RandomSamplingDataPointsFilter>());
107  this->outlierFilters.push_back(std::make_shared<typename OutlierFiltersImpl<T>::TrimmedDistOutlierFilter>());
108  this->matcher = std::make_shared<typename MatchersImpl<T>::KDTreeMatcher>();
109  this->errorMinimizer = std::make_shared<PointToPlaneErrorMinimizer<T> >();
110  this->transformationCheckers.push_back(std::make_shared<typename TransformationCheckersImpl<T>::CounterTransformationChecker>());
112  this->inspector = std::make_shared<typename InspectorsImpl<T>::NullInspector>();
113 }
114 
116 template<typename T>
118 {
119  this->cleanup();
120 
121  YAML::Parser parser(in);
122  YAML::Node doc;
123  parser.GetNextDocument(doc);
124  typedef set<string> StringSet;
125  StringSet usedModuleTypes;
126 
127  // Fix for issue #6: compilation on gcc 4.4.4
128  //PointMatcher<T> pm;
129  const PointMatcher & pm = PointMatcher::get();
130 
131  {
132  // NOTE: The logger needs to be initialize first to allow ouput from other contructors
133  boost::mutex::scoped_lock lock(loggerMutex);
134  usedModuleTypes.insert(createModuleFromRegistrar("logger", doc, pm.REG(Logger), logger));
135  }
136  usedModuleTypes.insert(createModulesFromRegistrar("readingDataPointsFilters", doc, pm.REG(DataPointsFilter), readingDataPointsFilters));
137  usedModuleTypes.insert(createModulesFromRegistrar("readingStepDataPointsFilters", doc, pm.REG(DataPointsFilter), readingStepDataPointsFilters));
138  usedModuleTypes.insert(createModulesFromRegistrar("referenceDataPointsFilters", doc, pm.REG(DataPointsFilter), referenceDataPointsFilters));
139  //usedModuleTypes.insert(createModulesFromRegistrar("transformations", doc, pm.REG(Transformation), transformations));
140  usedModuleTypes.insert(createModuleFromRegistrar("matcher", doc, pm.REG(Matcher), matcher));
141  usedModuleTypes.insert(createModulesFromRegistrar("outlierFilters", doc, pm.REG(OutlierFilter), outlierFilters));
142  usedModuleTypes.insert(createModuleFromRegistrar("errorMinimizer", doc, pm.REG(ErrorMinimizer), errorMinimizer));
143 
144  // See if to use a rigid transformation
145  if (nodeVal("errorMinimizer", doc) != "PointToPointSimilarityErrorMinimizer")
146  this->transformations.push_back(std::make_shared<typename TransformationsImpl<T>::RigidTransformation>());
147  else
148  this->transformations.push_back(std::make_shared<typename TransformationsImpl<T>::SimilarityTransformation>());
149 
150  usedModuleTypes.insert(createModulesFromRegistrar("transformationCheckers", doc, pm.REG(TransformationChecker), transformationCheckers));
151  usedModuleTypes.insert(createModuleFromRegistrar("inspector", doc, pm.REG(Inspector),inspector));
152 
153 
154  // FIXME: this line cause segfault when there is an error in the yaml file...
155  //loadAdditionalYAMLContent(doc);
156 
157  // check YAML entries that do not correspend to any module
158  for(YAML::Iterator moduleTypeIt = doc.begin(); moduleTypeIt != doc.end(); ++moduleTypeIt)
159  {
160  string moduleType;
161  moduleTypeIt.first() >> moduleType;
162  if (usedModuleTypes.find(moduleType) == usedModuleTypes.end())
163  throw InvalidModuleType(
164  (boost::format("Module type %1% does not exist") % moduleType).str()
165  );
166  }
167 }
168 
170 template<typename T>
172 {
174 }
175 
177 template<typename T>
179 {
181 }
182 
184 template<typename T>
186 {
188 }
189 
191 template<typename T>
192 template<typename R>
193 const std::string& PointMatcher<T>::ICPChainBase::createModulesFromRegistrar(const std::string& regName, const YAML::Node& doc, const R& registrar, std::vector<std::shared_ptr<typename R::TargetType> >& modules)
194 {
195  const YAML::Node *reg = doc.FindValue(regName);
196  if (reg)
197  {
198  //cout << regName << endl;
199  for(YAML::Iterator moduleIt = reg->begin(); moduleIt != reg->end(); ++moduleIt)
200  {
201  const YAML::Node& module(*moduleIt);
202  modules.push_back(registrar.createFromYAML(module));
203  }
204  }
205  return regName;
206 }
207 
209 template<typename T>
210 template<typename R>
211 const std::string& PointMatcher<T>::ICPChainBase::createModuleFromRegistrar(const std::string& regName, const YAML::Node& doc, const R& registrar, std::shared_ptr<typename R::TargetType>& module)
212 {
213  const YAML::Node *reg = doc.FindValue(regName);
214  if (reg)
215  {
216  //cout << regName << endl;
217  module = registrar.createFromYAML(*reg);
218  }
219  else
220  module.reset();
221  return regName;
222 }
223 
224 template<typename T>
225 std::string PointMatcher<T>::ICPChainBase::nodeVal(const std::string& regName, const PointMatcherSupport::YAML::Node& doc)
226 {
227  const YAML::Node *reg = doc.FindValue(regName);
228  if (reg)
229  {
232  PointMatcherSupport::getNameParamsFromYAML(*reg, name, params);
233  return name;
234  }
235  return "";
236 }
237 
238 template struct PointMatcher<float>::ICPChainBase;
239 template struct PointMatcher<double>::ICPChainBase;
240 
241 
243 template<typename T>
245  const DataPoints& readingIn,
246  const DataPoints& referenceIn)
247 {
248  const int dim = readingIn.features.rows();
249  const TransformationParameters identity = TransformationParameters::Identity(dim, dim);
250  return this->compute(readingIn, referenceIn, identity);
251 }
252 
254 template<typename T>
256  const DataPoints& readingIn,
257  const DataPoints& referenceIn,
258  const TransformationParameters& initialTransformationParameters)
259 {
260  return this->compute(readingIn, referenceIn, initialTransformationParameters);
261 }
262 
264 template<typename T>
266  const DataPoints& readingIn,
267  const DataPoints& referenceIn,
268  const TransformationParameters& T_refIn_dataIn)
269 {
270  // Ensuring minimum definition of components
271  if (!this->matcher)
272  throw runtime_error("You must setup a matcher before running ICP");
273  if (!this->errorMinimizer)
274  throw runtime_error("You must setup an error minimizer before running ICP");
275  if (!this->inspector)
276  throw runtime_error("You must setup an inspector before running ICP");
277 
278  this->inspector->init();
279 
280  timer t; // Print how long take the algo
281  const int dim(referenceIn.features.rows());
282 
283  // Apply reference filters
284  // reference is express in frame <refIn>
285  DataPoints reference(referenceIn);
287  this->referenceDataPointsFilters.apply(reference);
288 
289  // Create intermediate frame at the center of mass of reference pts cloud
290  // this help to solve for rotations
291  const int nbPtsReference = reference.features.cols();
292  const Vector meanReference = reference.features.rowwise().sum() / nbPtsReference;
293  TransformationParameters T_refIn_refMean(Matrix::Identity(dim, dim));
294  T_refIn_refMean.block(0,dim-1, dim-1, 1) = meanReference.head(dim-1);
295 
296  // Reajust reference position:
297  // from here reference is express in frame <refMean>
298  // Shortcut to do T_refIn_refMean.inverse() * reference
299  reference.features.topRows(dim-1).colwise() -= meanReference.head(dim-1);
300 
301  // Init matcher with reference points center on its mean
302  this->matcher->init(reference);
303 
304  // statistics on last step
305  this->inspector->addStat("ReferencePreprocessingDuration", t.elapsed());
306  this->inspector->addStat("ReferenceInPointCount", referenceIn.features.cols());
307  this->inspector->addStat("ReferencePointCount", reference.features.cols());
308  LOG_INFO_STREAM("PointMatcher::icp - reference pre-processing took " << t.elapsed() << " [s]");
309  this->prefilteredReferencePtsCount = reference.features.cols();
310 
311  return computeWithTransformedReference(readingIn, reference, T_refIn_refMean, T_refIn_dataIn);
312 
313 }
314 
316 template<typename T>
318  const DataPoints& readingIn,
319  const DataPoints& reference,
320  const TransformationParameters& T_refIn_refMean,
321  const TransformationParameters& T_refIn_dataIn)
322 {
323  const int dim(reference.features.rows());
324 
325  if (T_refIn_dataIn.cols() != T_refIn_dataIn.rows()) {
326  throw runtime_error("The initial transformation matrix must be squared.");
327  }
328  if (dim != T_refIn_dataIn.cols()) {
329  throw runtime_error("The shape of initial transformation matrix must be NxN. "
330  "Where N is the number of rows in the read/reference scans.");
331  }
332 
333  timer t; // Print how long take the algo
334 
335  // Apply readings filters
336  // reading is express in frame <dataIn>
337  DataPoints reading(readingIn);
338  //const int nbPtsReading = reading.features.cols();
340  this->readingDataPointsFilters.apply(reading);
341  readingFiltered = reading;
342 
343  // Reajust reading position:
344  // from here reading is express in frame <refMean>
346  T_refMean_dataIn = T_refIn_refMean.inverse() * T_refIn_dataIn;
347  this->transformations.apply(reading, T_refMean_dataIn);
348 
349  // Prepare reading filters used in the loop
351 
352  // Since reading and reference are express in <refMean>
353  // the frame <refMean> is equivalent to the frame <iter(0)>
354  TransformationParameters T_iter = Matrix::Identity(dim, dim);
355 
356  bool iterate(true);
357  this->maxNumIterationsReached = false;
358  this->transformationCheckers.init(T_iter, iterate);
359 
360  size_t iterationCount(0);
361 
362  // statistics on last step
363  this->inspector->addStat("ReadingPreprocessingDuration", t.elapsed());
364  this->inspector->addStat("ReadingInPointCount", readingIn.features.cols());
365  this->inspector->addStat("ReadingPointCount", reading.features.cols());
366  LOG_INFO_STREAM("PointMatcher::icp - reading pre-processing took " << t.elapsed() << " [s]");
367  this->prefilteredReadingPtsCount = reading.features.cols();
368  t.restart();
369 
370  // iterations
371  while (iterate)
372  {
373  DataPoints stepReading(reading);
374 
375  //-----------------------------
376  // Apply step filter
377  this->readingStepDataPointsFilters.apply(stepReading);
378 
379  //-----------------------------
380  // Transform Readings
381  this->transformations.apply(stepReading, T_iter);
382 
383  //-----------------------------
384  // Match to closest point in Reference
385  const Matches matches(
386  this->matcher->findClosests(stepReading)
387  );
388 
389  //-----------------------------
390  // Detect outliers
391  const OutlierWeights outlierWeights(
392  this->outlierFilters.compute(stepReading, reference, matches)
393  );
394 
395  assert(outlierWeights.rows() == matches.ids.rows());
396  assert(outlierWeights.cols() == matches.ids.cols());
397 
398  //cout << "outlierWeights: " << outlierWeights << "\n";
399 
400 
401  //-----------------------------
402  // Dump
403  this->inspector->dumpIteration(
404  iterationCount, T_iter, reference, stepReading, matches, outlierWeights, this->transformationCheckers
405  );
406 
407  //-----------------------------
408  // Error minimization
409  // equivalent to:
410  // T_iter(i+1)_iter(0) = T_iter(i+1)_iter(i) * T_iter(i)_iter(0)
411  T_iter = this->errorMinimizer->compute(
412  stepReading, reference, outlierWeights, matches) * T_iter;
413 
414  // Old version
415  //T_iter = T_iter * this->errorMinimizer->compute(
416  // stepReading, reference, outlierWeights, matches);
417 
418  // in test
419  try
420  {
421  this->transformationCheckers.check(T_iter, iterate);
422  }
424  {
425  iterate = false;
426  this->maxNumIterationsReached = true;
427  }
428 
429  ++iterationCount;
430  }
431 
432  this->inspector->addStat("IterationsCount", iterationCount);
433  this->inspector->addStat("PointCountTouched", this->matcher->getVisitCount());
434  this->matcher->resetVisitCount();
435  this->inspector->addStat("OverlapRatio", this->errorMinimizer->getWeightedPointUsedRatio());
436  this->inspector->addStat("ConvergenceDuration", t.elapsed());
437  this->inspector->finish(iterationCount);
438 
439  LOG_INFO_STREAM("PointMatcher::icp - " << iterationCount << " iterations took " << t.elapsed() << " [s]");
440 
441  // Move transformation back to original coordinate (without center of mass)
442  // T_iter is equivalent to: T_iter(i+1)_iter(0)
443  // the frame <iter(0)> equals <refMean>
444  // so we have:
445  // T_iter(i+1)_dataIn = T_iter(i+1)_iter(0) * T_refMean_dataIn
446  // T_iter(i+1)_dataIn = T_iter(i+1)_iter(0) * T_iter(0)_dataIn
447  // T_refIn_refMean remove the temperary frame added during initialization
448  return (T_refIn_refMean * T_iter * T_refMean_dataIn);
449 }
450 
451 template struct PointMatcher<float>::ICP;
452 template struct PointMatcher<double>::ICP;
453 
454 
456 template<typename T>
458 {
459  return (mapPointCloud.features.cols() != 0);
460 }
461 
463 template<typename T>
465 {
466  // Ensuring minimum definition of components
467  if (!this->matcher)
468  throw runtime_error("You must setup a matcher before running ICP");
469  if (!this->inspector)
470  throw runtime_error("You must setup an inspector before running ICP");
471 
472  timer t; // Print how long take the algo
473  const int dim(inputCloud.features.rows());
474  const int ptCount(inputCloud.features.cols());
475 
476  // update keyframe
477  if (ptCount == 0)
478  {
479  LOG_WARNING_STREAM("Ignoring attempt to create a map from an empty cloud");
480  return false;
481  }
482 
483  this->inspector->addStat("MapPointCount", inputCloud.features.cols());
484 
485  // Set map
486  mapPointCloud = inputCloud;
487 
488  // Create intermediate frame at the center of mass of reference pts cloud
489  // this help to solve for rotations
490  const Vector meanMap = mapPointCloud.features.rowwise().sum() / ptCount;
491  T_refIn_refMean = Matrix::Identity(dim, dim);
492  T_refIn_refMean.block(0,dim-1, dim-1, 1) = meanMap.head(dim-1);
493 
494  // Reajust reference position (only translations):
495  // from here reference is express in frame <refMean>
496  // Shortcut to do T_refIn_refMean.inverse() * reference
497  mapPointCloud.features.topRows(dim-1).colwise() -= meanMap.head(dim-1);
498 
499  // Apply reference filters
501  this->referenceDataPointsFilters.apply(mapPointCloud);
502 
503  this->matcher->init(mapPointCloud);
504 
505  this->inspector->addStat("SetMapDuration", t.elapsed());
506 
507  return true;
508 }
509 
511 template<typename T>
513 {
514  const int dim(mapPointCloud.features.rows());
515  T_refIn_refMean = Matrix::Identity(dim, dim);
516  mapPointCloud = DataPoints();
517 }
518 
519 template<typename T>
521 {
523 
524  if(mapPointCloud.getNbPoints() > 0)
525  {
526  this->matcher->init(mapPointCloud);
527  }
528 }
529 
530 template<typename T>
532 {
534 
535  if(mapPointCloud.getNbPoints() > 0)
536  {
537  this->matcher->init(mapPointCloud);
538  }
539 }
540 
542 template<typename T>
544 {
545  DataPoints globalMap(mapPointCloud);
546  if(this->hasMap())
547  {
548  const int dim(mapPointCloud.features.rows());
549  const Vector meanMapNonHomo(T_refIn_refMean.block(0,dim-1, dim-1, 1));
550  globalMap.features.topRows(dim-1).colwise() += meanMapNonHomo;
551  }
552 
553  return globalMap;
554 }
555 
557 template<typename T>
560 }
561 
563 template<typename T>
565 {
566  return mapPointCloud;
567 }
568 
570 template<typename T>
573 }
574 
576 template<typename T>
578  const DataPoints& cloudIn)
579 {
580  const int dim = cloudIn.features.rows();
581  const TransformationParameters identity = TransformationParameters::Identity(dim, dim);
582  return this->compute(cloudIn, identity);
583 }
584 
586 template<typename T>
588  const DataPoints& cloudIn, const TransformationParameters& T_dataInOld_dataInNew)
589 {
590  return this->compute(cloudIn, T_dataInOld_dataInNew);
591 }
592 
594 template<typename T>
596  const DataPoints& cloudIn, const TransformationParameters& T_refIn_dataIn)
597 {
598  // initial keyframe
599  if (!hasMap())
600  {
601  const int dim(cloudIn.features.rows());
602  LOG_WARNING_STREAM("Ignoring attempt to perform ICP with an empty map");
603  return Matrix::Identity(dim, dim);
604  }
605 
606  this->inspector->init();
607 
608  return this->computeWithTransformedReference(cloudIn, mapPointCloud, T_refIn_refMean, T_refIn_dataIn);
609 }
610 
611 template struct PointMatcher<float>::ICPSequence;
612 template struct PointMatcher<double>::ICPSequence;
Matrix OutlierWeights
Weights of the associations between the points in Matches and the points in the reference.
Definition: PointMatcher.h:397
const DataPoints getPrefilteredMap() const
Return the map, in global coordinates (slow)
Definition: ICP.cpp:543
A matcher links points in the reading to points in the reference.
Definition: PointMatcher.h:473
#define LOG_INFO_STREAM(args)
public interface
The logger interface, used to output warnings and informations.
Definition: PointMatcher.h:104
bool hasMap() const
Return whether the object currently holds a valid map.
Definition: ICP.cpp:457
void restart()
void apply(DataPoints &cloud, const TransformationParameters &parameters) const
Apply this chain to cloud, using parameters, mutates cloud.
virtual void setDefault()
Construct an ICP algorithm that works in most of the cases.
Definition: ICP.cpp:520
PM::DataPoints DataPoints
boost::mutex loggerMutex
mutex to protect access to logging
Definition: Logger.cpp:41
bool setMap(const DataPoints &map)
Set the map using inputCloud.
Definition: ICP.cpp:464
::std::string string
Definition: gtest.h:1979
virtual void setDefault()
Construct an ICP algorithm that works in most of the cases.
Definition: ICP.cpp:100
DataPointsFilters referenceDataPointsFilters
filters for reference
Definition: PointMatcher.h:660
TransformationParameters operator()(const DataPoints &cloudIn)
Apply ICP to cloud cloudIn, with identity as initial guess.
Definition: ICP.cpp:577
bool maxNumIterationsReached
store if we reached the maximum number of iterations last time compute was called ...
Definition: PointMatcher.h:681
TransformationParameters compute(const DataPoints &cloudIn, const TransformationParameters &initialTransformationParameters)
Apply ICP to cloud cloudIn, with initial guess.
Definition: ICP.cpp:595
TransformationCheckers transformationCheckers
transformation checkers
Definition: PointMatcher.h:665
virtual void loadAdditionalYAMLContent(PointMatcherSupport::YAML::Node &doc)
Hook to load addition subclass-specific content from the YAML file.
Definition: ICP.cpp:94
Struct used to inform through an exeption that ICP reached max number of iterations.
OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Apply outlier-detection chain.
An error minimizer will compute a transformation matrix such as to minimize the error between the rea...
Definition: PointMatcher.h:530
Iterator begin() const
Definition: node.cpp:141
const DataPoints & getPrefilteredInternalMap() const
Return the map, in internal coordinates (fast)
Definition: ICP.cpp:564
DataPointsFilters readingDataPointsFilters
filters for reading, applied once
Definition: PointMatcher.h:658
std::map< std::string, Parameter > Parameters
Parameters stored as a map of string->string.
Functions and classes that are not dependant on scalar type are defined in this namespace.
An inspector allows to log data at the different steps, for analysis.
Definition: PointMatcher.h:624
An exception thrown when one tries to use a module type that does not exist.
Definition: PointMatcher.h:83
void getNameParamsFromYAML(const YAML::Node &module, std::string &name, Parametrizable::Parameters &params)
Retrieve name and parameters from a yaml node.
Definition: Registrar.cpp:12
TransformationParameters operator()(const DataPoints &readingIn, const DataPoints &referenceIn)
Perform ICP and return optimised transformation matrix.
Definition: ICP.cpp:244
Functions and classes that are dependant on scalar type are defined in this templatized class...
Definition: PointMatcher.h:130
OutlierFilters outlierFilters
outlier filters
Definition: PointMatcher.h:663
static const PointMatcher & get()
Return instances.
Definition: Registry.cpp:145
Iterator end() const
Definition: node.cpp:159
bool GetNextDocument(Node &document)
Definition: parser.cpp:61
Result of the data-association step (Matcher::findClosests), before outlier rejection.
Definition: PointMatcher.h:371
std::string nodeVal(const std::string &regName, const PointMatcherSupport::YAML::Node &doc)
Get the value of a field in a node.
Definition: ICP.cpp:225
A data filter takes a point cloud as input, transforms it, and produces another point cloud as output...
Definition: PointMatcher.h:440
std::shared_ptr< ErrorMinimizer > errorMinimizer
error minimizer
Definition: PointMatcher.h:664
An outlier filter removes or weights links between points in reading and their matched points in refe...
Definition: PointMatcher.h:499
::RandomSamplingDataPointsFilter< T > RandomSamplingDataPointsFilter
TransformationParameters compute(const DataPoints &readingIn, const DataPoints &referenceIn, const TransformationParameters &initialTransformationParameters)
Perform ICP from initial guess and return optimised transformation matrix.
Definition: ICP.cpp:265
void check(const TransformationParameters &parameters, bool &iterate)
Check using all transformation checkers, set iterate to false if iteration should stop...
#define LOG_WARNING_STREAM(args)
virtual void loadFromYaml(std::istream &in)
Construct an ICP algorithm from a YAML file.
Definition: ICP.cpp:531
ICPChainBase()
Protected contstructor, to prevent the creation of this object.
Definition: ICP.cpp:65
std::shared_ptr< Matcher > matcher
matcher
Definition: PointMatcher.h:662
const std::string & createModulesFromRegistrar(const std::string &regName, const PointMatcherSupport::YAML::Node &doc, const R &registrar, std::vector< std::shared_ptr< typename R::TargetType > > &modules)
Instantiate modules if their names are in the YAML file.
TransformationParameters computeWithTransformedReference(const DataPoints &readingIn, const DataPoints &reference, const TransformationParameters &T_refIn_refMean, const TransformationParameters &initialTransformationParameters)
Perferm ICP using an already-transformed reference and with an already-initialized matcher...
Definition: ICP.cpp:317
std::shared_ptr< Inspector > inspector
inspector
Definition: PointMatcher.h:666
double elapsed() const
A transformation checker can stop the iteration depending on some conditions.
Definition: PointMatcher.h:583
Transformations transformations
transformations
Definition: PointMatcher.h:661
unsigned prefilteredReadingPtsCount
remaining number of points after prefiltering but before the iterative process
Definition: PointMatcher.h:679
const Node * FindValue(const T &key) const
Definition: nodeimpl.h:29
bool getMaxNumIterationsReached() const
Return the flag that informs if we reached the maximum number of iterations during the last iterative...
Definition: ICP.cpp:185
void apply(DataPoints &cloud)
Apply this chain to cloud, mutates cloud.
Eigen::Matrix< T, Eigen::Dynamic, 1 > Vector
A vector over ScalarType.
Definition: PointMatcher.h:161
void init(const TransformationParameters &parameters, bool &iterate)
Init all transformation checkers, set iterate to false if iteration should stop.
::SamplingSurfaceNormalDataPointsFilter< T > SamplingSurfaceNormalDataPointsFilter
Matrix features
features of points in the cloud
Definition: PointMatcher.h:331
virtual ~ICPChainBase()
virtual desctructor
Definition: ICP.cpp:73
DataPointsFilters readingStepDataPointsFilters
filters for reading, applied at each step
Definition: PointMatcher.h:659
std::shared_ptr< Logger > logger
the current logger
Definition: Logger.cpp:42
Stuff common to all ICP algorithms.
Definition: PointMatcher.h:655
unsigned getPrefilteredReadingPtsCount() const
Return the remaining number of points in reading after prefiltering but before the iterative process...
Definition: ICP.cpp:171
ICP algorithm.
Definition: PointMatcher.h:702
unsigned getPrefilteredReferencePtsCount() const
Return the remaining number of points in the reference after prefiltering but before the iterative pr...
Definition: ICP.cpp:178
Matrix TransformationParameters
A matrix holding the parameters a transformation.
Definition: PointMatcher.h:182
void clearMap()
Clear the map (reset to same state as after the object is created)
Definition: ICP.cpp:512
virtual void loadFromYaml(std::istream &in)
Construct an ICP algorithm from a YAML file.
Definition: ICP.cpp:117
unsigned prefilteredReferencePtsCount
remaining number of points after prefiltering but before the iterative process
Definition: PointMatcher.h:680
void cleanup()
Clean chain up, empty all filters and delete associated objects.
Definition: ICP.cpp:79
const std::string & createModuleFromRegistrar(const std::string &regName, const PointMatcherSupport::YAML::Node &doc, const R &registrar, std::shared_ptr< typename R::TargetType > &module)
Instantiate a module if its name is in the YAML file.


libpointmatcher
Author(s):
autogenerated on Sat May 27 2023 02:38:02