Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "PointMatcher.h"
00037 #include "PointMatcherPrivate.h"
00038
00039 using namespace std;
00040
00042 template<typename T>
00043 PointMatcher<T>::Matches::Matches() {}
00044
00046 template<typename T>
00047 PointMatcher<T>::Matches::Matches(const Dists& dists, const Ids ids):
00048 dists(dists),
00049 ids(ids)
00050 {}
00051
00053 template<typename T>
00054 PointMatcher<T>::Matches::Matches(const int knn, const int pointsCount):
00055 dists(Dists(knn, pointsCount)),
00056 ids(Ids(knn, pointsCount))
00057 {}
00058
00060 template<typename T>
00061 T PointMatcher<T>::Matches::getDistsQuantile(const T quantile) const
00062 {
00063
00064 vector<T> values;
00065 values.reserve(dists.rows() * dists.cols());
00066 for (int x = 0; x < dists.cols(); ++x)
00067 {
00068 for (int y = 0; y < dists.rows(); ++y)
00069 {
00070 if (dists(y, x) != numeric_limits<T>::infinity())
00071 {
00072 values.push_back(dists(y, x));
00073 }
00074 }
00075 }
00076 if (values.size() == 0)
00077 throw ConvergenceError("no outlier to filter");
00078
00079 if (quantile < 0.0 || quantile > 1.0)
00080 throw ConvergenceError("quantile must be between 0 and 1");
00081
00082
00083 if (quantile == 1.0)
00084 return *max_element(values.begin(), values.end());
00085 nth_element(values.begin(), values.begin() + (values.size() * quantile), values.end());
00086 return values[values.size() * quantile];
00087 }
00088
00090 template<typename T>
00091 T PointMatcher<T>::Matches::getMedianAbsDeviation() const
00092 {
00093 vector<T> values;
00094 values.reserve(dists.rows() * dists.cols());
00095 const long cols = dists.cols();
00096 const long rows = dists.rows();
00097 for (int x = 0; x < cols; ++x)
00098 {
00099 for (int y = 0; y < rows; ++y)
00100 {
00101 if (dists(y, x) != numeric_limits<T>::infinity())
00102 {
00103 values.push_back(dists(y, x));
00104 }
00105 }
00106 }
00107 if (values.size() == 0)
00108 throw ConvergenceError("no outlier to filter");
00109
00110 nth_element(values.begin(), values.begin() + (values.size() / 2), values.end());
00111 const T median = values[values.size() / 2];
00112
00113
00114 const unsigned size = values.size();
00115 for (unsigned i = 0; i < size; ++i)
00116 {
00117 values[i] = fabs(values[i] - median);
00118 }
00119
00120 nth_element(values.begin(), values.begin() + (values.size() / 2), values.end());
00121 return values[values.size() / 2];
00122 }
00123
00124 template<typename T>
00125 T PointMatcher<T>::Matches::getStandardDeviation() const
00126 {
00127 auto d = dists.array();
00128 return std::sqrt((d - d.mean()).square().sum()/(d.size()-1));
00129 }
00130
00131
00132 template struct PointMatcher<float>::Matches;
00133 template struct PointMatcher<double>::Matches;