30 #ifndef MATH_UTIL_RANSAC_H_
31 #define MATH_UTIL_RANSAC_H_
37 #include <boost/make_shared.hpp>
42 template <
class Model>
55 int32_t min_iterations,
56 int32_t max_iterations,
57 std::vector<uint32_t>& inliers,
60 int32_t breakout = std::numeric_limits<int32_t>::max();
63 int32_t max_inliers = 0;
65 if (!model.ValidData())
72 rng_ = boost::make_shared<RandomGenerator>();
75 std::vector<int32_t> indices;
78 for (iterations = 0; (iterations < max_iterations && iterations < breakout) || iterations < min_iterations; iterations++)
81 rng_->GetUniformRandomSample(0, model.Size() - 1, Model::MIN_SIZE, indices);
85 if (model.GetModel(indices, hypothesis, max_error))
87 int32_t inlier_count = model.GetInlierCount(hypothesis, max_error);
91 if (inlier_count > max_inliers)
93 max_inliers = inlier_count;
94 Model::CopyTo(hypothesis, best_fit);
97 double ratio = inlier_count /
static_cast<double>(model.Size());
98 double p_no_outliers = 1.0 - std::pow(ratio, Model::MIN_SIZE);
99 if (p_no_outliers == 0)
103 else if (p_no_outliers < .9999)
105 breakout = std::log(1 - confidence) / std::log(p_no_outliers);
113 model.GetInliers(best_fit, max_error, inliers);
122 template <
class Model>
135 int32_t max_iterations,
137 std::vector<uint32_t>& inliers,
140 Model model(data, batch_size);
142 int32_t breakout = std::numeric_limits<int32_t>::max();
145 int32_t max_inliers = 0;
147 if (!model.ValidData())
154 rng_ = boost::make_shared<RandomGenerator>();
157 std::vector<int32_t> indices;
160 while (iterations < max_iterations && iterations < breakout)
163 model.ClearSamples();
164 while (iterations < max_iterations && iterations < breakout && model.Samples() < batch_size)
168 rng_->GetUniformRandomSample(0, model.Size() - 1, Model::MIN_SIZE, indices);
169 model.AddSample(indices, max_error);
172 if (model.Samples() > 0)
174 int32_t inlier_count = model.ProcessSamples(hypothesis, max_error);
175 if (inlier_count > 0 && inlier_count > max_inliers)
177 max_inliers = inlier_count;
178 Model::CopyTo(hypothesis, best_fit);
181 double ratio = inlier_count /
static_cast<double>(model.Size());
182 double p_no_outliers = 1.0 - std::pow(ratio, Model::MIN_SIZE);
183 if (p_no_outliers == 0)
187 else if (p_no_outliers < .9999)
189 breakout = std::log(1 - confidence) / std::log(p_no_outliers);
197 model.GetInliers(best_fit, max_error, inliers);
207 #endif // MATH_UTIL_RANSAC_H_