Apollo  6.0
Open source self driving car software
camera_ground_plane.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2018 The Apollo Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *****************************************************************************/
16 #pragma once
17 
18 #include <vector>
19 
20 #include "cyber/common/log.h"
23 
24 namespace apollo {
25 namespace perception {
26 namespace camera {
27 
28 // ground conversion utils
29 void ConvertGround3ToGround4(const float &baseline,
30  const std::vector<float> &k_mat,
31  const std::vector<float> &ground3,
32  std::vector<float> *ground4);
33 
34 bool ConvertGround4ToGround3(const float &baseline,
35  const std::vector<float> &k_mat,
36  const std::vector<float> &ground4,
37  std::vector<float> *ground3);
38 
39 void GetGroundPlanePitchHeight(const float &baseline,
40  const std::vector<float> &k_mat,
41  const std::vector<float> &ground3, float *pitch,
42  float *cam_height);
43 
44 void GetGround3FromPitchHeight(const std::vector<float> &k_mat,
45  const float &baseline, const float &pitch,
46  const float &cam_height,
47  std::vector<float> *ground3);
48 
49 // @brief: a ground plane tracker using pitch + camera height representation.
50 // @param [in]: per-frame p(pitch)h(height) and inlier ratio
51 // @param [in/out]: smoothed plane
53  public:
54  explicit GroundPlaneTracker(int track_length);
56 
57  void Push(const std::vector<float> &ph, const float &inlier_ratio);
58 
59  void GetGround(float *pitch, float *cam_height);
60 
61  void Restart();
62 
64  int length = static_cast<int>(pitch_height_inlier_tracks_.size());
65  CHECK_GE(length, 0);
66  return length;
67  }
68 
69  private:
70  int head_ = 0;
71  std::vector<float> pitch_height_inlier_tracks_; // pitch, height, inlier ...
72  std::vector<float> const_weight_temporal_;
73  std::vector<float> weight_;
74 };
75 
76 // params for ground detector
78  CameraGroundPlaneParams() { SetDefault(); }
79  void SetDefault();
80 
87 
88  void operator=(const CameraGroundPlaneParams &params) {
89  this->min_nr_samples = params.min_nr_samples;
90  this->nr_frames_track = params.nr_frames_track;
91  this->max_tilt_angle = params.max_tilt_angle;
92  this->min_inlier_ratio = params.min_inlier_ratio;
93  this->thres_inlier_plane_fitting = params.thres_inlier_plane_fitting;
94  }
95 };
96 
97 // @brief: a ground plane detector using disparity.
98 // @param [in]: disparity samples (row-disp pairs)
99 // @param [in/out]: ground plane (a * y + b * disp + c = 0)
101  public:
103  ground_plane_tracker_ = new GroundPlaneTracker(params_.nr_frames_track);
104  }
106  delete ground_plane_tracker_;
107  ground_plane_tracker_ = nullptr;
108  }
109 
110  void Init(const std::vector<float> &k_mat, int width, int height,
111  float baseline, int max_nr_samples = 1080) {
112  CHECK_EQ(k_mat.size(), 9U);
113  memcpy(k_mat_, k_mat.data(), sizeof(float) * 9);
114  width_ = width;
115  height_ = height;
116  baseline_ = baseline;
117  ss_flt_.resize(max_nr_samples * 2);
118  ss_int_.resize(max_nr_samples * 2);
119  }
120 
121  int get_min_nr_samples() { return params_.min_nr_samples; }
122 
123  // main interface: fit the plane from v-d samples
124  // input a backup (default) pitch + camera_height
125  // can be assigned by {a, b, c, d}: a * X + b * Y + c * Z + d = 0 (cam coor)
126  bool DetetGround(float pitch, float camera_height,
127  float *vd, /*samples: v0, d0 ... vj, dj*/
128  int count_vd, const std::vector<float> &plane = {});
129 
130  bool GetGroundModel(float *l) const {
131  l[0] = l_[0];
132  l[1] = l_[1];
133  l[2] = l_[2];
134  return ground_is_valid_;
135  }
136 
137  private:
138  void FillGroundModel(const std::vector<float> &ground3) {
139  CHECK_EQ(ground3.size(), 3U);
140  l_[0] = ground3[0];
141  l_[1] = ground3[1];
142  l_[2] = ground3[2];
143  }
144 
145  bool DetectGroundFromSamples(float *vd, int count_vd, float *inlier_ratio);
146 
147  private:
148  CameraGroundPlaneParams params_;
149  int width_ = 0;
150  int height_ = 0;
151  float k_mat_[9] = {0};
152  float baseline_ = 0.0f; // if disp is reversed-z, baseline = 1 / focal
153  float l_[3] = {0}; // a * y + b * disp + c = 0
154 
155  // scratch space
156  std::vector<int> ss_int_ = {};
157  std::vector<float> ss_flt_ = {};
158 
159  bool ground_is_valid_ = false; // status of ground estimation
160 
161  GroundPlaneTracker *ground_plane_tracker_ = nullptr;
162 };
163 
164 /*
165  fitting utils
166 */
167 template <typename T>
168 void GroundHypoGenFunc(const T *v, const T *d, T *p) {
169  // disp = p0 * y + p1 -> l = {p0, -1, p1}
170  T x[2] = {v[0], d[0]};
171  T xp[2] = {v[1], d[1]};
172  T l[3] = {0};
173  common::ILineFit2d(x, xp, l);
174  p[0] = -l[0] * common::IRec(l[1]);
175  p[1] = -l[2] * common::IRec(l[1]);
176 }
177 
178 template <typename T>
179 void GroundFittingCostFunc(const T *p, const T *v, const T *d, int n,
180  int *nr_inlier, // NOLINT compatible for i-lib
181  int *inliers,
182  T *cost, // NOLINT
183  T error_tol) {
184  *cost = static_cast<T>(0.0f);
185  *nr_inlier = 0;
186  const T *refx = v;
187  const T *refp = d;
188  for (int i = 0; i < n; ++i) {
189  T d_proj = refx[0] * p[0] + p[1];
190  T proj_err = static_cast<T>(fabs(d_proj - refp[0]));
191  if (proj_err < error_tol) {
192  inliers[(*nr_inlier)++] = i;
193  *cost += proj_err;
194  }
195  ++refx;
196  ++refp;
197  }
198 }
199 
200 } // namespace camera
201 } // namespace perception
202 } // namespace apollo
float thres_inlier_plane_fitting
Definition: camera_ground_plane.h:86
bool GetGroundModel(float *l) const
Definition: camera_ground_plane.h:130
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
float IRec(float a)
Definition: i_basic.h:69
void GroundHypoGenFunc(const T *v, const T *d, T *p)
Definition: camera_ground_plane.h:168
float max_camera_ground_height
Definition: camera_ground_plane.h:84
bool ConvertGround4ToGround3(const float &baseline, const std::vector< float > &k_mat, const std::vector< float > &ground4, std::vector< float > *ground3)
int nr_frames_track
Definition: camera_ground_plane.h:82
float min_inlier_ratio
Definition: camera_ground_plane.h:85
CameraGroundPlaneParams()
Definition: camera_ground_plane.h:78
void GetGround(float *pitch, float *cam_height)
int GetCurTrackLength()
Definition: camera_ground_plane.h:63
Definition: camera_ground_plane.h:100
void ILineFit2d(const T *x, const T *xp, T *l)
Definition: i_line.h:68
void operator=(const CameraGroundPlaneParams &params)
Definition: camera_ground_plane.h:88
float max_tilt_angle
Definition: camera_ground_plane.h:83
void ConvertGround3ToGround4(const float &baseline, const std::vector< float > &k_mat, const std::vector< float > &ground3, std::vector< float > *ground4)
void GetGround3FromPitchHeight(const std::vector< float > &k_mat, const float &baseline, const float &pitch, const float &cam_height, std::vector< float > *ground3)
~CameraGroundPlaneDetector()
Definition: camera_ground_plane.h:105
void Push(const std::vector< float > &ph, const float &inlier_ratio)
void Init(const std::vector< float > &k_mat, int width, int height, float baseline, int max_nr_samples=1080)
Definition: camera_ground_plane.h:110
void GroundFittingCostFunc(const T *p, const T *v, const T *d, int n, int *nr_inlier, int *inliers, T *cost, T error_tol)
Definition: camera_ground_plane.h:179
~GroundPlaneTracker()
Definition: camera_ground_plane.h:55
Definition: camera_ground_plane.h:77
int get_min_nr_samples()
Definition: camera_ground_plane.h:121
void GetGroundPlanePitchHeight(const float &baseline, const std::vector< float > &k_mat, const std::vector< float > &ground3, float *pitch, float *cam_height)
Definition: camera_ground_plane.h:52
int min_nr_samples
Definition: camera_ground_plane.h:81
CameraGroundPlaneDetector()
Definition: camera_ground_plane.h:102