26 template <
typename Estimator,
27 typename LocalEstimator,
28 typename SupportMeasurer = InlierSupportMeasurer,
29 typename Sampler = RandomSampler>
42 Report
Estimate(
const std::vector<typename Estimator::X_t>&
X,
43 const std::vector<typename Estimator::Y_t>& Y);
59 template <
typename Estimator,
60 typename LocalEstimator,
61 typename SupportMeasurer,
67 template <
typename Estimator,
68 typename LocalEstimator,
69 typename SupportMeasurer,
73 const std::vector<typename Estimator::X_t>&
X,
74 const std::vector<typename Estimator::Y_t>& Y) {
75 CHECK_EQ(
X.size(), Y.size());
77 const size_t num_samples =
X.size();
87 typename SupportMeasurer::Support best_support;
88 typename Estimator::M_t best_model;
89 bool best_model_is_local =
false;
93 const double max_residual = options_.max_error * options_.max_error;
95 std::vector<double> residuals;
96 std::vector<double> best_local_residuals;
98 std::vector<typename LocalEstimator::X_t> X_inlier;
99 std::vector<typename LocalEstimator::Y_t> Y_inlier;
104 sampler.Initialize(num_samples);
106 size_t max_num_trials = options_.max_num_trials;
107 max_num_trials = std::min<size_t>(max_num_trials, sampler.MaxNumSamples());
108 size_t dyn_max_num_trials = max_num_trials;
117 sampler.SampleXY(
X, Y, &X_rand, &Y_rand);
120 const std::vector<typename Estimator::M_t> sample_models =
121 estimator.Estimate(X_rand, Y_rand);
124 for (
const auto& sample_model : sample_models) {
125 estimator.Residuals(
X, Y, sample_model, &residuals);
126 CHECK_EQ(residuals.size(), num_samples);
129 support_measurer.Evaluate(residuals, max_residual);
132 if (support_measurer.Compare(support, best_support)) {
133 best_support = support;
134 best_model = sample_model;
135 best_model_is_local =
false;
141 const size_t kMaxNumLocalTrials = 10;
142 for (
size_t local_num_trials = 0;
143 local_num_trials < kMaxNumLocalTrials;
144 ++local_num_trials) {
147 X_inlier.reserve(num_samples);
148 Y_inlier.reserve(num_samples);
149 for (
size_t i = 0; i < residuals.size(); ++i) {
150 if (residuals[i] <= max_residual) {
151 X_inlier.push_back(
X[i]);
152 Y_inlier.push_back(Y[i]);
156 const std::vector<typename LocalEstimator::M_t>
157 local_models = local_estimator.Estimate(
160 const size_t prev_best_num_inliers =
161 best_support.num_inliers;
163 for (
const auto& local_model : local_models) {
164 local_estimator.Residuals(
X, Y, local_model,
166 CHECK_EQ(residuals.size(), num_samples);
168 const auto local_support =
169 support_measurer.Evaluate(residuals,
173 if (support_measurer.Compare(local_support,
175 best_support = local_support;
176 best_model = local_model;
177 best_model_is_local =
true;
178 std::swap(residuals, best_local_residuals);
185 if (best_support.num_inliers <= prev_best_num_inliers) {
192 std::swap(residuals, best_local_residuals);
199 best_support.num_inliers, num_samples,
201 options_.dyn_num_trials_multiplier);
204 if (report.
num_trials >= dyn_max_num_trials &&
205 report.
num_trials >= options_.min_num_trials) {
213 report.
model = best_model;
216 if (report.
support.num_inliers < estimator.kMinNumSamples) {
226 if (best_model_is_local) {
227 local_estimator.Residuals(
X, Y, report.
model, &residuals);
229 estimator.Residuals(
X, Y, report.
model, &residuals);
232 CHECK_EQ(residuals.size(), num_samples);
235 for (
size_t i = 0; i < residuals.size(); ++i) {
236 report.
inlier_mask[i] = residuals[i] <= max_residual;
LORANSAC(const RANSACOptions &options)
Report Estimate(const std::vector< typename Estimator::X_t > &X, const std::vector< typename Estimator::Y_t > &Y)
LocalEstimator local_estimator
static size_t ComputeNumTrials(const size_t num_inliers, const size_t num_samples, const double confidence, const double num_trials_multiplier)
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
std::vector< char > inlier_mask
SupportMeasurer::Support support