58 return OutlierWeights::Constant(input.
ids.rows(), input.
ids.cols(), 1);
123 const T limit =
factor * median;
183 typedef typename Eigen::Array<T, Eigen::Dynamic, 1> LineArray;
185 const int points_nbr = matches.
dists.rows() * matches.
dists.cols();
188 std::vector<T> tmpSortedDist;
189 tmpSortedDist.reserve(points_nbr);
190 for (
int x = 0;
x < matches.
dists.cols(); ++
x)
191 for (
int y = 0; y < matches.
dists.rows(); ++y)
192 if ((matches.
dists(y,
x) != numeric_limits<T>::infinity()) && (matches.
dists(y,
x) > 0))
193 tmpSortedDist.push_back(matches.
dists(y,
x));
194 if (tmpSortedDist.empty())
195 throw ConvergenceError(
"Inlier ratio optimization failed due to absence of matches");
197 std::sort(tmpSortedDist.begin(), tmpSortedDist.end());
198 std::vector<T> tmpCumSumSortedDist;
199 tmpCumSumSortedDist.reserve(points_nbr);
200 std::partial_sum(tmpSortedDist.begin(), tmpSortedDist.end(), tmpCumSumSortedDist.begin());
202 const int minEl = floor(this->
minRatio*points_nbr);
203 const int maxEl = floor(this->
maxRatio*points_nbr);
206 Eigen::Map<LineArray> sortedDist(&tmpCumSumSortedDist[0], points_nbr);
208 const LineArray trunkSortedDist = sortedDist.segment(minEl, maxEl-minEl);
210 const LineArray ids = LineArray::LinSpaced(trunkSortedDist.rows(), minEl+1, maxEl);
211 const LineArray ratio = ids / points_nbr;
212 const LineArray deno = ratio.pow(this->
lambda);
214 const LineArray FRMS = trunkSortedDist * ids.inverse() * deno.inverse().square() ;
216 FRMS.minCoeff(&minIndex);
217 const T optRatio = (float)(minIndex + minEl)/ (float)points_nbr;
230 warningPrinted(false)
247 if(normalsReading.cols() != 0 && normalsReference.cols() != 0)
249 for (
int x = 0;
x < w.cols(); ++
x)
251 const Vector normalRead = normalsReading.col(
x).normalized();
253 for (
int y = 0; y < w.rows(); ++y)
255 const int idRef = input.
ids(y,
x);
262 const Vector normalRef = normalsReference.col(idRef).normalized();
264 const T value = normalRead.dot(normalRef);
277 LOG_INFO_STREAM(
"SurfaceNormalOutlierFilter: surface normals not available. Skipping filtering");
281 w = Matrix::Ones(input.
dists.rows(), input.
dists.cols());
303 (boost::format(
"GenericDescriptorOutlierFilter: Error, the parameter named 'source' can only be set to 'reference' or 'reading' but was set to %1%") %
source).str());
316 const int readPtsCount = input.
dists.cols();
323 cloud = &filteredReference;
325 cloud = &filteredReading;
332 (boost::format(
"GenericDescriptorOutlierFilter: Error, the parameter named 'descName' must be a 1D descriptor but the field %1% is %2%D") %
descName % desc.rows()).str());
335 for(
int k=0; k <
knn; k++)
337 for(
int i=0; i < readPtsCount; i++)
340 if (
source ==
"reference") {
341 point_id = input.
ids(k, i);
343 LOG_INFO_STREAM(
"Invalid Index in GenericOutlierFilter, setting weight to 0.");
372 w(k,i) = desc(0, point_id);
391 {
"cauchy", RobustFctId::Cauchy},
392 {
"welsch", RobustFctId::Welsch},
393 {
"sc", RobustFctId::SwitchableConstraint},
394 {
"gm", RobustFctId::GM},
395 {
"tukey", RobustFctId::Tukey},
396 {
"huber", RobustFctId::Huber},
397 {
"L1", RobustFctId::L1},
398 {
"student", RobustFctId::Student}
417 const set<string> validScaleEstimator = {
"none",
"mad",
"berg",
"std"};
418 if (validScaleEstimator.find(
scaleEstimator) == validScaleEstimator.end()) {
421 const set<string> validDistanceType = {
"point2point",
"point2plane"};
422 if (validDistanceType.find(
distanceType) == validDistanceType.end()) {
467 return this->
robustFiltering(filteredReading, filteredReference, input);
479 int nbr_read_point = input.
dists.cols();
480 int nbr_match = input.
dists.rows();
484 Vector reading_point(Vector::Zero(3));
485 Vector reference_point(Vector::Zero(3));
488 Matrix dists(Matrix::Zero(nbr_match, nbr_read_point));
490 for(
int i = 0; i < nbr_read_point; ++i)
492 reading_point = reading.
features.block(0, i, 3, 1);
493 for(
int j = 0; j < nbr_match; ++j)
495 const int reference_idx = input.
ids(j, i);
497 reference_point = reference.
features.block(0, reference_idx, 3, 1);
499 normal = normals.col(reference_idx).normalized();
501 dists(j, i) =
pow(normal.dot(reading_point-reference_point), 2);
539 const T CONVERGENCE_RATE = 0.85;
557 Array w, aboveThres, belowThres;
559 case RobustFctId::Cauchy:
560 w = (1 + e2 / k2).inverse();
562 case RobustFctId::Welsch:
563 w = (-e2 / k2).exp();
565 case RobustFctId::SwitchableConstraint:
566 aboveThres = 4.0 * k2 * ((k + e2).square()).inverse();
567 w = (e2 >= k).select(aboveThres, 1.0);
569 case RobustFctId::GM:
570 w = k2*((k + e2).square()).inverse();
572 case RobustFctId::Tukey:
573 belowThres = (1 - e2 / k2).square();
574 w = (e2 >= k2).select(0.0, belowThres);
576 case RobustFctId::Huber:
577 aboveThres = k * (e2.sqrt().inverse());
578 w = (e2 >= k2).select(aboveThres, 1.0);
580 case RobustFctId::L1:
581 w = e2.sqrt().inverse();
583 case RobustFctId::Student: {
585 auto p = (1 + e2 / k).
pow(-(k + d) / 2);
586 w = p * (k + d) * (k + e2).inverse();
595 const double ARBITRARY_SMALL_VALUE = 1e-50;
596 w = (w.array() <= ARBITRARY_SMALL_VALUE).select(ARBITRARY_SMALL_VALUE, w);
Matrix OutlierWeights
Weights of the associations between the points in Matches and the points in the reference.
const std::string distanceType
virtual OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Detect outliers using features.
#define LOG_INFO_STREAM(args)
MaxDistOutlierFilter(const Parameters ¶ms=Parameters())
const std::string robustFctName
PointMatcher< T >::Vector Vector
constexpr T pow(const T base, const std::size_t exponent)
virtual OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Detect outliers using features.
Parametrizable::InvalidParameter InvalidParameter
Matrix computePointToPlaneDistance(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
GenericDescriptorOutlierFilter(const Parameters ¶ms=Parameters())
static const ParametersDoc availableParameters()
Point matcher did not converge.
ConstView getDescriptorViewByName(const std::string &name) const
Get a const view on a descriptor by name, throw an exception if it does not exist.
const std::string scaleEstimator
virtual OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Detect outliers using features.
T optimizeInlierRatio(const Matches &matches)
VarTrimmedDistOutlierFilter(const Parameters ¶ms=Parameters())
virtual OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Detect outliers using features.
virtual OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Detect outliers using features.
std::map< std::string, RobustFctId > RobustFctMap
RobustOutlierFilter(const std::string &className, const ParametersDoc paramsDoc, const Parameters ¶ms)
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > Matrix
A dense matrix over ScalarType.
PointMatcher< T >::Matrix Matrix
PointMatcher< T >::OutlierWeights OutlierWeights
const std::string descName
virtual OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Detect outliers using features.
T getDistsQuantile(const T quantile) const
Get the distance at the T-ratio closest point.
SurfaceNormalOutlierFilter(const Parameters ¶ms=Parameters())
static const ParametersDoc availableParameters()
std::map< std::string, Parameter > Parameters
Parameters stored as a map of string->string.
static RobustFctMap robustFcts
Functions and classes that are not dependant on scalar type are defined in this namespace.
const Eigen::Block< const Matrix > ConstView
A view on a const feature or const descriptor.
virtual void resolveEstimatorName()
Result of the data-association step (Matcher::findClosests), before outlier rejection.
An outlier filter removes or weights links between points in reading and their matched points in refe...
const M::mapped_type & get(const M &m, const typename M::key_type &k)
PointMatcher< T >::Array Array
MinDistOutlierFilter(const Parameters ¶ms=Parameters())
const T squaredApproximation
The superclass of classes that are constructed using generic parameters. This class provides the para...
std::string getParamValueString(const std::string ¶mName)
Get the value of a parameter, as a string.
std::vector< ParameterDoc > ParametersDoc
The documentation of all parameters.
static const ParametersDoc availableParameters()
S get(const std::string ¶mName)
Return the value of paramName, lexically-casted to S.
const std::string className
name of the class
const int nbIterationForScale
TrimmedDistOutlierFilter(const Parameters ¶ms=Parameters())
const bool useSoftThreshold
static const ParametersDoc availableParameters()
virtual OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Detect outliers using features.
Dists dists
squared distances to closest points
static const ParametersDoc availableParameters()
static const ParametersDoc availableParameters()
T getStandardDeviation() const
Matrix features
features of points in the cloud
Ids ids
identifiers of closest points
static constexpr int InvalidId
virtual OutlierWeights robustFiltering(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
T getMedianAbsDeviation() const
Calculate the Median of Absolute Deviation(MAD), which is median(|x-median(x)|), a kind of robust sta...
virtual OutlierWeights compute(const DataPoints &filteredReading, const DataPoints &filteredReference, const Matches &input)
Detect outliers using features.