51bool PolyFit(
const EigenVector<Eigen::Matrix<Dtype, 2, 1>>& pos_vec,
53 Eigen::Matrix<Dtype, max_poly_order + 1, 1>* coeff,
54 const bool& is_x_axis =
true) {
55 if (coeff ==
nullptr) {
56 AERROR <<
"The coefficient pointer is NULL.";
60 if (order > max_poly_order) {
61 AERROR <<
"The order of polynomial must be smaller than " << max_poly_order;
65 int n =
static_cast<int>(pos_vec.size());
67 AERROR <<
"The number of points should be larger than the order. #points = "
73 Eigen::Matrix<Dtype, Eigen::Dynamic, Eigen::Dynamic> A(n, order + 1);
74 Eigen::Matrix<Dtype, Eigen::Dynamic, 1> y(n);
75 Eigen::Matrix<Dtype, Eigen::Dynamic, 1> result;
76 for (
int i = 0; i < n; ++i) {
77 for (
int j = 0; j <= order; ++j) {
78 A(i, j) =
static_cast<Dtype
>(
79 std::pow(is_x_axis ? pos_vec[i].x() : pos_vec[i].y(), j));
81 y(i) = is_x_axis ? pos_vec[i].y() : pos_vec[i].x();
85 result = A.householderQr().solve(y);
86 assert(result.size() == order + 1);
88 for (
int j = 0; j <= max_poly_order; ++j) {
89 (*coeff)(j) = (j <= order) ? result(j) :
static_cast<Dtype
>(0);
117 EigenVector<Eigen::Matrix<Dtype, 2, 1>>* selected_points,
118 Eigen::Matrix<Dtype, 4, 1>* coeff,
const int max_iters = 100,
120 const Dtype inlier_thres =
static_cast<Dtype
>(0.1)) {
121 if (coeff ==
nullptr) {
122 AERROR <<
"The coefficient pointer is NULL.";
126 selected_points->clear();
128 int n =
static_cast<int>(pos_vec.size());
129 int q1 =
static_cast<int>(n / 4);
130 int q2 =
static_cast<int>(n / 2);
131 int q3 =
static_cast<int>(n * 3 / 4);
133 AERROR <<
"The number of points should be larger than the order. #points = "
138 std::vector<int> index(3, 0);
140 Dtype min_residual = std::numeric_limits<float>::max();
141 Dtype early_stop_ratio = 0.95f;
142 Dtype good_lane_ratio = 0.666f;
143 for (
int j = 0; j < max_iters; ++j) {
144 index[0] = std::rand() % q2;
145 index[1] = q2 + std::rand() % q1;
146 index[2] = q3 + std::rand() % q1;
148 Eigen::Matrix<Dtype, 3, 3> matA;
149 matA << pos_vec[index[0]](0) * pos_vec[index[0]](0), pos_vec[index[0]](0),
150 1, pos_vec[index[1]](0) * pos_vec[index[1]](0), pos_vec[index[1]](0), 1,
151 pos_vec[index[2]](0) * pos_vec[index[2]](0), pos_vec[index[2]](0), 1;
153 Eigen::FullPivLU<Eigen::Matrix<Dtype, 3, 3>> mat(matA);
154 mat.setThreshold(1e-5f);
155 if (mat.rank() < 3) {
156 ADEBUG <<
"matA: " << matA;
157 ADEBUG <<
"Matrix is not full rank (3). The rank is: " << mat.rank();
163 Eigen::Matrix<Dtype, 3, 1> matB;
164 matB << pos_vec[index[0]](1), pos_vec[index[1]](1), pos_vec[index[2]](1);
166 static_cast<Eigen::Matrix<Dtype, 3, 1>
>(matA.inverse() * matB);
167 if (!(matA * c).isApprox(matB)) {
175 for (
int i = 0; i < n; ++i) {
176 y = pos_vec[i](0) * pos_vec[i](0) * c(0) + pos_vec[i](0) * c(1) + c(2);
177 if (std::abs(y - pos_vec[i](1)) <= inlier_thres) ++num_inliers;
178 residual += std::abs(y - pos_vec[i](1));
181 if (num_inliers > max_inliers ||
182 (num_inliers == max_inliers && residual < min_residual)) {
187 max_inliers = num_inliers;
188 min_residual = residual;
191 if (max_inliers > early_stop_ratio * n)
break;
194 if (
static_cast<Dtype
>(max_inliers) / n < good_lane_ratio)
return false;
198 for (
int i = 0; i < n; ++i) {
199 Dtype y = pos_vec[i](0) * pos_vec[i](0) * (*coeff)(2) +
200 pos_vec[i](0) * (*coeff)(1) + (*coeff)(0);
201 if (std::abs(y - pos_vec[i](1)) <= inlier_thres) {
202 selected_points->push_back(pos_vec[i]);
290void QuickSort(
int* index,
const T* values,
int start,
int end) {
291 if (start >= end - 1) {
295 const T& pivot = values[index[(start + end - 1) / 2]];
302 while (lo < hi && values[index[lo]] < pivot) {
305 while (lo < hi && values[index[hi - 1]] >= pivot) {
308 if (lo == hi || lo == hi - 1) {
311 QSwap_(&(index[lo]), &(index[hi - 1]));
321 while (lo < hi && values[index[lo]] == pivot) {
324 while (lo < hi && values[index[hi - 1]] > pivot) {
327 if (lo == hi || lo == hi - 1) {
330 QSwap_(&(index[lo]), &(index[hi - 1]));
bool PolyFit(const EigenVector< Eigen::Matrix< Dtype, 2, 1 > > &pos_vec, const int &order, Eigen::Matrix< Dtype, max_poly_order+1, 1 > *coeff, const bool &is_x_axis=true)
bool RansacFitting(const EigenVector< Eigen::Matrix< Dtype, 2, 1 > > &pos_vec, EigenVector< Eigen::Matrix< Dtype, 2, 1 > > *selected_points, Eigen::Matrix< Dtype, 4, 1 > *coeff, const int max_iters=100, const int N=5, const Dtype inlier_thres=static_cast< Dtype >(0.1))