22 #include "cyber/common/log.h" 27 namespace perception {
32 static const double lane_eps_value = 1e-6;
33 static const int max_poly_order = 3;
45 template <
typename Dtype>
46 bool PolyFit(
const std::vector<Eigen::Matrix<Dtype, 2, 1>>& pos_vec,
48 Eigen::Matrix<Dtype, max_poly_order + 1, 1>* coeff,
49 const bool& is_x_axis =
true) {
50 if (coeff ==
nullptr) {
51 AERROR <<
"The coefficient pointer is NULL.";
55 if (order > max_poly_order) {
56 AERROR <<
"The order of polynomial must be smaller than " << max_poly_order;
60 int n =
static_cast<int>(pos_vec.size());
62 AERROR <<
"The number of points should be larger than the order. #points = " 68 Eigen::Matrix<Dtype, Eigen::Dynamic, Eigen::Dynamic> A(n, order + 1);
69 Eigen::Matrix<Dtype, Eigen::Dynamic, 1>
y(n);
70 Eigen::Matrix<Dtype, Eigen::Dynamic, 1> result;
71 for (
int i = 0; i < n; ++i) {
72 for (
int j = 0; j <= order; ++j) {
73 A(i, j) =
static_cast<Dtype
>(
74 std::pow(is_x_axis ? pos_vec[i].
x() : pos_vec[i].
y(), j));
76 y(i) = is_x_axis ? pos_vec[i].y() : pos_vec[i].x();
80 result = A.householderQr().solve(y);
81 assert(result.size() == order + 1);
83 for (
int j = 0; j <= max_poly_order; ++j) {
84 (*coeff)(j) = (j <= order) ? result(j) :
static_cast<Dtype
>(0);
90 template <
typename Dtype>
92 const Eigen::Matrix<Dtype, max_poly_order + 1, 1>& coeff,
94 int poly_order = order;
95 if (order > max_poly_order) {
96 AERROR <<
"the order of polynomial function must be smaller than " 101 *y =
static_cast<Dtype
>(0);
102 for (
int j = 0; j <= poly_order; ++j) {
103 *y +=
static_cast<Dtype
>(coeff(j) * std::pow(x, j));
110 template <
typename Dtype>
112 std::vector<Eigen::Matrix<Dtype, 2, 1>>* selected_points,
113 Eigen::Matrix<Dtype, 4, 1>* coeff,
114 const int max_iters = 100,
116 const Dtype inlier_thres = static_cast<Dtype>(0.1)) {
117 if (coeff ==
nullptr) {
118 AERROR <<
"The coefficient pointer is NULL.";
122 selected_points->clear();
124 int n =
static_cast<int>(pos_vec.size());
125 int q1 =
static_cast<int>(n / 4);
126 int q2 =
static_cast<int>(n / 2);
127 int q3 =
static_cast<int>(n * 3 / 4);
129 AERROR <<
"The number of points should be larger than the order. #points = " 134 std::vector<int> index(3, 0);
136 Dtype min_residual = FLT_MAX;
137 Dtype early_stop_ratio = 0.95f;
138 Dtype good_lane_ratio = 0.666f;
139 for (
int j = 0; j < max_iters; ++j) {
140 index[0] = std::rand() % q2;
141 index[1] = q2 + std::rand() % q1;
142 index[2] = q3 + std::rand() % q1;
144 Eigen::Matrix<Dtype, 3, 3> matA;
145 matA << pos_vec[index[0]](0) * pos_vec[index[0]](0),
146 pos_vec[index[0]](0), 1,
147 pos_vec[index[1]](0) * pos_vec[index[1]](0),
148 pos_vec[index[1]](0), 1,
149 pos_vec[index[2]](0) * pos_vec[index[2]](0),
150 pos_vec[index[2]](0), 1;
152 Eigen::FullPivLU<Eigen::Matrix<Dtype, 3, 3>> mat(matA);
153 mat.setThreshold(1e-5f);
154 if (mat.rank() < 3) {
155 ADEBUG <<
"matA: "<< matA;
156 ADEBUG <<
"Matrix is not full rank (3). The rank is: " << mat.rank();
162 Eigen::Matrix<Dtype, 3, 1> matB;
163 matB << pos_vec[index[0]](1), pos_vec[index[1]](1), pos_vec[index[2]](1);
165 static_cast<Eigen::Matrix<Dtype, 3, 1>
> (matA.inverse() * matB);
166 if (!(matA * c).isApprox(matB)) {
167 ADEBUG <<
"No solution.";
174 for (
int i = 0; i < n; ++i) {
175 y = pos_vec[i](0) * pos_vec[i](0) * c(0) + pos_vec[i](0) * c(1) + c(2);
176 if (
std::abs(y - pos_vec[i](1)) <= inlier_thres) ++num_inliers;
177 residual +=
std::abs(y - pos_vec[i](1));
180 if (num_inliers > max_inliers ||
181 (num_inliers == max_inliers && residual < min_residual)) {
186 max_inliers = num_inliers;
187 min_residual = residual;
190 if (max_inliers > early_stop_ratio * n)
break;
193 if (static_cast<Dtype>(max_inliers) / n < good_lane_ratio)
return false;
197 for (
int i = 0; i < n; ++i) {
198 Dtype
y = pos_vec[i](0) * pos_vec[i](0) * (*coeff)(2) +
199 pos_vec[i](0) * (*coeff)(1) + (*coeff)(0);
200 if (
std::abs(y - pos_vec[i](1)) <= inlier_thres) {
201 selected_points->push_back(pos_vec[i]);
210 explicit DisjointSet(
size_t size) : disjoint_array_(), subset_num_(0) {
211 disjoint_array_.reserve(size);
216 disjoint_array_.clear();
217 disjoint_array_.reserve(size);
222 disjoint_array_.clear();
228 void Unite(
int x,
int y);
229 int Size()
const {
return subset_num_; }
230 size_t Num()
const {
return disjoint_array_.size(); }
233 std::vector<int> disjoint_array_;
245 pixels_.push_back(point);
255 void AddPixel(
int x,
int y);
258 std::vector<base::Point2DI>
GetPixels()
const {
return pixels_; }
262 std::vector<base::Point2DI> pixels_;
266 bool FindCC(
const std::vector<unsigned char>& src,
int width,
int height,
267 const base::RectI& roi, std::vector<ConnectedComponent>* cc);
270 float camera_ground_height,
271 const Eigen::Matrix3f& intrinsic_params_inverse,
272 Eigen::Vector3d* camera_point);
275 const Eigen::Matrix3f& intrinsic_params,
289 void QuickSort(
int* index,
const T* values,
int start,
int end) {
290 if (start >= end - 1) {
294 const T& pivot = values[index[(start + end - 1) / 2]];
301 while (lo < hi && values[index[lo]] < pivot) {
304 while (lo < hi && values[index[hi - 1]] >= pivot) {
307 if (lo == hi || lo == hi - 1) {
310 QSwap_(&(index[lo]), &(index[hi - 1]));
320 while (lo < hi && values[index[lo]] == pivot) {
323 while (lo < hi && values[index[hi - 1]] > pivot) {
326 if (lo == hi || lo == hi - 1) {
329 QSwap_(&(index[lo]), &(index[hi - 1]));
339 void QuickSort(
int* index,
const T* values,
int nsize) {
340 for (
int ii = 0; ii < nsize; ii++) {
345 bool FindKSmallValue(
const float* distance,
int dim,
int k,
int* index);
347 bool FindKLargeValue(
const float* distance,
int dim,
int k,
int* index);
float score
Definition: common_functions.h:38
int Size() const
Definition: common_functions.h:229
int GetPixelCount() const
Definition: common_functions.h:256
bool FindKLargeValue(const float *distance, int dim, int k, int *index)
Definition: common_functions.h:35
bool RansacFitting(const std::vector< Eigen::Matrix< Dtype, 2, 1 >> &pos_vec, std::vector< 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))
Definition: common_functions.h:111
base::BBox2DI GetBBox() const
Definition: common_functions.h:257
bool CameraPoint2Image(const Eigen::Vector3d &camera_point, const Eigen::Matrix3f &intrinsic_params, base::Point2DF *img_point)
ConnectedComponent(int x, int y)
Definition: common_functions.h:241
bool FindCC(const std::vector< unsigned char > &src, int width, int height, const base::RectI &roi, std::vector< ConnectedComponent > *cc)
Definition: common_functions.h:237
DisjointSet()
Definition: common_functions.h:209
float x
Definition: common_functions.h:40
void Init(size_t size)
Definition: common_functions.h:215
std::vector< base::Point2DI > GetPixels() const
Definition: common_functions.h:258
T abs(const T &x)
Definition: misc.h:48
bool PolyEval(const Dtype &x, int order, const Eigen::Matrix< Dtype, max_poly_order+1, 1 > &coeff, Dtype *y)
Definition: common_functions.h:91
bool FindKSmallValue(const float *distance, int dim, int k, int *index)
T x
Definition: point.h:84
void Reset()
Definition: common_functions.h:221
T y
Definition: point.h:85
Definition: common_functions.h:207
float y
Definition: common_functions.h:42
bool ComparePoint2DY(const base::Point2DF &point1, const base::Point2DF &point2)
DisjointSet(size_t size)
Definition: common_functions.h:210
int type
Definition: common_functions.h:36
ConnectedComponent()
Definition: common_functions.h:239
std::vector< base::Point2DF > Point2DSet
Definition: common_functions.h:30
bool ImagePoint2Camera(const base::Point2DF &img_point, float pitch_angle, float camera_ground_height, const Eigen::Matrix3f &intrinsic_params_inverse, Eigen::Vector3d *camera_point)
void QuickSort(int *index, const T *values, int start, int end)
Definition: common_functions.h:289
void QSwap_(T *a, T *b)
Definition: common_functions.h:282
~DisjointSet()
Definition: common_functions.h:213
std::vector< base::Point3DF > Point3DSet
Definition: common_functions.h:29
size_t Num() const
Definition: common_functions.h:230
bool PolyFit(const std::vector< 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)
Definition: common_functions.h:46
~ConnectedComponent()
Definition: common_functions.h:252