39 #ifndef PCL_REGISTRATION_IMPL_CORRESPONDENCE_REJECTION_POLY_HPP_
40 #define PCL_REGISTRATION_IMPL_CORRESPONDENCE_REJECTION_POLY_HPP_
44 namespace registration {
46 template <
typename SourceT,
typename TargetT>
53 remaining_correspondences = original_correspondences;
57 PCL_ERROR(
"[pcl::registration::%s::getRemainingCorrespondences] No source was "
58 "input! Returning all input correspondences.\n",
59 getClassName().c_str());
64 PCL_ERROR(
"[pcl::registration::%s::getRemainingCorrespondences] No target was "
65 "input! Returning all input correspondences.\n",
66 getClassName().c_str());
71 if (cardinality_ < 2) {
72 PCL_ERROR(
"[pcl::registration::%s::getRemainingCorrespondences] Polygon "
73 "cardinality too low!. Returning all input correspondences.\n",
74 getClassName().c_str());
79 const int nr_correspondences =
static_cast<int>(original_correspondences.size());
82 if (cardinality_ >= nr_correspondences) {
83 PCL_ERROR(
"[pcl::registration::%s::getRemainingCorrespondences] Number of "
84 "correspondences smaller than polygon cardinality! Returning all input "
86 getClassName().c_str());
91 if (similarity_threshold_ < 0.0f || similarity_threshold_ > 1.0f) {
93 "[pcl::registration::%s::getRemainingCorrespondences] Invalid edge length "
94 "similarity - must be in [0,1]!. Returning all input correspondences.\n",
95 getClassName().c_str());
100 similarity_threshold_squared_ = similarity_threshold_ * similarity_threshold_;
103 remaining_correspondences.clear();
104 remaining_correspondences.reserve(nr_correspondences);
107 std::vector<int> num_samples(nr_correspondences, 0);
108 std::vector<int> num_accepted(nr_correspondences, 0);
111 for (
int i = 0; i < iterations_; ++i) {
113 const std::vector<int> idx =
114 getUniqueRandomIndices(nr_correspondences, cardinality_);
117 if (thresholdPolygon(original_correspondences, idx)) {
119 for (
int j = 0; j < cardinality_; ++j) {
120 ++num_samples[idx[j]];
121 ++num_accepted[idx[j]];
126 for (
int j = 0; j < cardinality_; ++j)
127 ++num_samples[idx[j]];
132 std::vector<float> accept_rate(nr_correspondences, 0.0f);
133 for (
int i = 0; i < nr_correspondences; ++i) {
134 const int numsi = num_samples[i];
136 accept_rate[i] = 0.0f;
138 accept_rate[i] =
static_cast<float>(num_accepted[i]) /
static_cast<float>(numsi);
142 const int hist_size = nr_correspondences / 2;
143 const std::vector<int> histogram =
144 computeHistogram(accept_rate, 0.0f, 1.0f, hist_size);
147 const int cut_idx = findThresholdOtsu(histogram);
148 const float cut =
static_cast<float>(cut_idx) /
static_cast<float>(hist_size);
151 for (
int i = 0; i < nr_correspondences; ++i)
152 if (accept_rate[i] > cut)
153 remaining_correspondences.push_back(original_correspondences[i]);
156 template <
typename SourceT,
typename TargetT>
159 const std::vector<float>& data,
float lower,
float upper,
int bins)
162 std::vector<int> result(bins, 0);
165 const int last_idx = bins - 1;
166 const float idx_per_val =
static_cast<float>(bins) / (upper - lower);
169 for (
const float& value : data)
170 ++result[std::min(last_idx,
static_cast<int>(value * idx_per_val))];
175 template <
typename SourceT,
typename TargetT>
178 const std::vector<int>& histogram)
181 constexpr
double eps = std::numeric_limits<double>::epsilon();
184 const int nbins =
static_cast<int>(histogram.size());
188 double sum_inv = 0.0;
189 for (
int i = 0; i < nbins; ++i) {
190 mean +=
static_cast<double>(i * histogram[i]);
191 sum_inv +=
static_cast<double>(histogram[i]);
193 sum_inv = 1.0 / sum_inv;
197 double class_mean1 = 0.0;
198 double class_prob1 = 0.0;
199 double class_prob2 = 1.0;
202 double between_class_variance_max = 0.0;
206 for (
int i = 0; i < nbins; ++i) {
207 class_mean1 *= class_prob1;
210 const double prob_i =
static_cast<double>(histogram[i]) * sum_inv;
213 class_prob1 += prob_i;
216 class_prob2 -= prob_i;
219 if (std::min(class_prob1, class_prob2) < eps ||
220 std::max(class_prob1, class_prob2) > 1.0 - eps)
224 class_mean1 = (class_mean1 +
static_cast<double>(i) * prob_i) / class_prob1;
227 const double class_mean2 = (mean - class_prob1 * class_mean1) / class_prob2;
230 const double between_class_variance = class_prob1 * class_prob2 *
231 (class_mean1 - class_mean2) *
232 (class_mean1 - class_mean2);
235 if (between_class_variance > between_class_variance_max) {
236 between_class_variance_max = between_class_variance;
void getRemainingCorrespondences(const pcl::Correspondences &original_correspondences, pcl::Correspondences &remaining_correspondences) override
Get a list of valid correspondences after rejection from the original set of correspondences.
std::vector< int > computeHistogram(const std::vector< float > &data, float lower, float upper, int bins)
Compute a linear histogram.
int findThresholdOtsu(const std::vector< int > &histogram)
Find the optimal value for binary histogram thresholding using Otsu's method.
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences