110 ADEBUG <<
"Begin to Process2D.";
112 auto start = std::chrono::high_resolution_clock::now();
114 cv::Mat lane_map(lane_map_height_, lane_map_width_, CV_32FC1);
116 lane_map_width_ * lane_map_height_ *
sizeof(
float));
126 int y =
static_cast<int>(lane_map.rows * 0.9 - 1);
128 int step_y = (y - 40) * (y - 40) / 6400 + 1;
131 xy_points.resize(lane_type_num_);
133 uv_points.resize(lane_type_num_);
136 for (
int x = 1; x < lane_map.cols - 1; ++x) {
137 int value =
static_cast<int>(round(lane_map.at<
float>(y, x)));
140 if ((value > 0 && value < 5) || value == 11) {
142 if (value !=
static_cast<int>(round(lane_map.at<
float>(y, x + 1)))) {
143 Eigen::Matrix<float, 3, 1> img_point(
144 static_cast<float>(x * roi_width_ / lane_map.cols),
145 static_cast<float>(y * roi_height_ / lane_map.rows + roi_start_),
147 Eigen::Matrix<float, 3, 1> xy_p;
148 xy_p = trans_mat_ * img_point;
149 Eigen::Matrix<float, 2, 1> xy_point;
150 Eigen::Matrix<float, 2, 1> uv_point;
151 if (std::fabs(xy_p(2)) < 1e-6)
continue;
152 xy_point << xy_p(0) / xy_p(2), xy_p(1) / xy_p(2);
155 if (xy_point(0) < 0.0 ||
156 xy_point(0) > max_longitudinal_distance_ ||
157 std::abs(xy_point(1)) > 30.0) {
160 uv_point << static_cast<float>(x * roi_width_ / lane_map.cols),
161 static_cast<float>(y * roi_height_ / lane_map.rows + roi_start_);
162 if (xy_points[value].size() < minNumPoints_ || xy_point(0) < 50.0f ||
163 std::fabs(xy_point(1) - xy_points[value].back()(1)) < 1.0f) {
164 xy_points[value].push_back(xy_point);
165 uv_points[value].push_back(uv_point);
168 }
else if (value >= 5 && value < lane_type_num_) {
170 if (value !=
static_cast<int>(round(lane_map.at<
float>(y, x - 1)))) {
171 Eigen::Matrix<float, 3, 1> img_point(
172 static_cast<float>(x * roi_width_ / lane_map.cols),
173 static_cast<float>(y * roi_height_ / lane_map.rows + roi_start_),
175 Eigen::Matrix<float, 3, 1> xy_p;
176 xy_p = trans_mat_ * img_point;
177 Eigen::Matrix<float, 2, 1> xy_point;
178 Eigen::Matrix<float, 2, 1> uv_point;
179 if (std::fabs(xy_p(2)) < 1e-6)
continue;
180 xy_point << xy_p(0) / xy_p(2), xy_p(1) / xy_p(2);
182 if (xy_point(0) < 0.0 ||
183 xy_point(0) > max_longitudinal_distance_ ||
184 std::abs(xy_point(1)) > 30.0) {
187 uv_point << static_cast<float>(x * roi_width_ / lane_map.cols),
188 static_cast<float>(y * roi_height_ / lane_map.rows + roi_start_);
189 if (xy_points[value].size() < minNumPoints_ || xy_point(0) < 50.0f ||
190 std::fabs(xy_point(1) - xy_points[value].back()(1)) < 1.0f) {
191 xy_points[value].push_back(xy_point);
192 uv_points[value].push_back(uv_point);
194 }
else if (value >= lane_type_num_) {
195 AWARN <<
"Lane line value shouldn't be equal or more than: "
200 step_y = (y - 45) * (y - 45) / 6400 + 1;
204 auto elapsed_1 = std::chrono::high_resolution_clock::now() - start;
205 int64_t microseconds_1 =
206 std::chrono::duration_cast<std::chrono::microseconds>(elapsed_1).count();
207 time_1 += microseconds_1;
213 coeffs.resize(lane_type_num_);
214 img_coeffs.resize(lane_type_num_);
215 for (
int i = 1; i < lane_type_num_; ++i) {
216 coeffs[i] << 0, 0, 0, 0;
217 if (xy_points[i].size() < minNumPoints_)
continue;
218 Eigen::Matrix<float, 4, 1> coeff;
220 if (RansacFitting<float>(xy_points[i], &selected_xy_points, &coeff, 200,
221 static_cast<int>(minNumPoints_), 0.1f)) {
224 xy_points[i].clear();
225 xy_points[i] = selected_xy_points;
227 xy_points[i].clear();
231 auto elapsed_2 = std::chrono::high_resolution_clock::now() - start;
232 int64_t microseconds_2 =
233 std::chrono::duration_cast<std::chrono::microseconds>(elapsed_2).count();
234 time_2 += microseconds_2 - microseconds_1;
237 std::vector<float> c0s(lane_type_num_, 0);
238 for (
int i = 1; i < lane_type_num_; ++i) {
239 if (xy_points[i].size() < minNumPoints_)
continue;
241 static_cast<float>(coeffs[i](3)),
static_cast<float>(coeffs[i](2)),
242 static_cast<float>(coeffs[i](1)),
static_cast<float>(coeffs[i](0)),
243 static_cast<float>(3.0));
246 if (xy_points[4].size() < minNumPoints_ &&
247 xy_points[5].size() >= minNumPoints_) {
248 std::swap(xy_points[4], xy_points[5]);
249 std::swap(uv_points[4], uv_points[5]);
250 std::swap(coeffs[4], coeffs[5]);
251 std::swap(c0s[4], c0s[5]);
252 }
else if (xy_points[6].size() < minNumPoints_ &&
253 xy_points[5].size() >= minNumPoints_) {
254 std::swap(xy_points[6], xy_points[5]);
255 std::swap(uv_points[6], uv_points[5]);
256 std::swap(coeffs[6], coeffs[5]);
257 std::swap(c0s[6], c0s[5]);
260 if (xy_points[4].size() < minNumPoints_ &&
261 xy_points[11].size() >= minNumPoints_) {
263 bool use_boundary =
true;
264 for (
int k = 3; k >= 1; --k) {
265 if (xy_points[k].size() >= minNumPoints_) {
266 use_boundary =
false;
271 std::swap(xy_points[4], xy_points[11]);
272 std::swap(uv_points[4], uv_points[11]);
273 std::swap(coeffs[4], coeffs[11]);
274 std::swap(c0s[4], c0s[11]);
278 if (xy_points[6].size() < minNumPoints_ &&
279 xy_points[12].size() >= minNumPoints_) {
281 bool use_boundary =
true;
282 for (
int k = 7; k <= 9; ++k) {
283 if (xy_points[k].size() >= minNumPoints_) {
284 use_boundary =
false;
289 std::swap(xy_points[6], xy_points[12]);
290 std::swap(uv_points[6], uv_points[12]);
291 std::swap(coeffs[6], coeffs[12]);
292 std::swap(c0s[6], c0s[12]);
296 for (
int i = 1; i < lane_type_num_; ++i) {
298 if (xy_points[i].size() < minNumPoints_) {
306 if ((i < 5 && c0s[i] < c0s[i + 1]) ||
307 (i > 5 && i < 10 && c0s[i] > c0s[i - 1])) {
310 if (i == 11 || i == 12) {
311 std::sort(c0s.begin(), c0s.begin() + 10);
312 if ((c0s[i] > c0s[0] && i == 12) || (c0s[i] < c0s[9] && i == 11)) {
318 static_cast<float>(xy_points[i].front()(0));
320 static_cast<float>(xy_points[i].back()(0));
329 for (
size_t j = 0; j < xy_points[i].size(); ++j) {
331 p_j.
x =
static_cast<float>(xy_points[i][j](0));
332 p_j.
y =
static_cast<float>(xy_points[i][j](1));
337 for (
size_t j = 0; j < uv_points[i].size(); ++j) {
339 p_j.
x =
static_cast<float>(uv_points[i][j](0));
340 p_j.
y =
static_cast<float>(uv_points[i][j](1));
354 if (lane_.curve_car_coord.d >= 0) {
356 }
else if (lane_.curve_car_coord.d < 0) {
363 if (has_center_ == 1) {
366 if (spatial_id >= 1 && spatial_id <= 5) {
370 }
else if (has_center_ == 2) {
373 if (spatial_id >= 5 && spatial_id <= 9) {
379 auto elapsed = std::chrono::high_resolution_clock::now() - start;
380 int64_t microseconds =
381 std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
383 time_3 += microseconds - microseconds_2;
388 ADEBUG <<
"Avg sampling time: " << time_1 / time_num
389 <<
" Avg fitting time: " << time_2 / time_num
390 <<
" Avg writing time: " << time_3 / time_num;
391 ADEBUG <<
"darkSCNN lane_postprocess done!";