Apollo 11.0
自动驾驶开放平台
center_point_detection.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2022 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
18
19#include <algorithm>
20#include <functional>
21#include <numeric>
22#include <random>
23#include <utility>
24
25#if GPU_PLATFORM == NVIDIA
26#include <cuda_runtime_api.h>
27#elif GPU_PLATFORM == AMD
28#include <hip/hip_runtime.h>
29#include <hip/hip_runtime_api.h>
30#endif
31
32#include "cyber/common/file.h"
33#include "cyber/common/log.h"
44
46
47namespace apollo {
48namespace perception {
49namespace lidar {
50
51using base::Object;
52using base::PointD;
53using base::PointF;
54
55// point cloud range
57 : x_min_range_(Params::kMinXRange),
58 x_max_range_(Params::kMaxXRange),
59 y_min_range_(Params::kMinYRange),
60 y_max_range_(Params::kMaxYRange),
61 z_min_range_(Params::kMinZRange),
62 z_max_range_(Params::kMaxZRange) {}
63
65 std::string config_file =
66 GetConfigFile(options.config_path, options.config_file);
67 ACHECK(apollo::cyber::common::GetProtoFromFile(config_file, &model_param_));
68
69 const auto &model_info = model_param_.info();
70 std::string model_path = GetModelPath(model_info.name());
71 // Network files
72 std::string proto_file =
73 GetModelFile(model_path, model_info.proto_file().file());
74 std::string weight_file =
75 GetModelFile(model_path, model_info.weight_file().file());
76 // Network input and output names
77 input_blob_names_ = inference::GetBlobNames(model_info.inputs());
78 output_blob_names_ = inference::GetBlobNames(model_info.outputs());
79
80 inference_.reset(inference::CreateInferenceByName(
81 model_info.framework(), proto_file, weight_file, output_blob_names_,
82 input_blob_names_));
83
84 std::map<std::string, std::vector<int>> shape_map;
85 inference::AddShape(&shape_map, model_info.inputs());
86 inference::AddShape(&shape_map, model_info.outputs());
87
88 if (!inference_->Init(shape_map)) {
89 return false;
90 }
91
92 if (model_param_.preprocess().enable_ground_removal()) {
93 z_min_range_ = std::max(
94 z_min_range_,
95 static_cast<float>(model_param_.preprocess().ground_removal_height()));
96 }
97 nms_strategy_ = model_param_.nms_strategy();
98 diff_class_iou_ = model_param_.diff_class_iou();
99 diff_class_nms_ = model_param_.diff_class_nms();
100
101 cone_score_threshold_ = model_param_.postprocess().cone_score_threshold();
102 ped_score_threshold_ = model_param_.postprocess().ped_score_threshold();
103 cyc_score_threshold_ = model_param_.postprocess().cyc_score_threshold();
104 small_mot_score_threshold_ =
105 model_param_.postprocess().small_mot_score_threshold();
106 big_mot_score_threshold_ =
107 model_param_.postprocess().big_mot_score_threshold();
108
109 if (model_param_.has_plugins()) {
110 const auto &plugin = model_param_.plugins();
111 const auto &name = plugin.name();
115 if (!down_sample_) {
116 AINFO << "Failed to find down_sample plugin: " << name << ", skipped";
117 return false;
118 }
120 option.config_path = plugin.config_path();
121 option.config_file = plugin.config_file();
122 if (!down_sample_->Init(option)) {
123 AINFO << "Failed to init down_sample plugin: " << name << ", skipped";
124 return false;
125 }
126 }
127 // if (diff_class_nms_) {
128 // nms_strategy_table_ = {
129 // {base::ObjectType::BICYCLE, {base::ObjectType::PEDESTRIAN,
130 // base::ObjectType::UNKNOWN}},
131 // {base::ObjectType::PEDESTRIAN, {base::ObjectType::UNKNOWN}},
132 // {base::ObjectType::VEHICLE, {base::ObjectType::BICYCLE,
133 // base::ObjectType::PEDESTRIAN, base::ObjectType::UNKNOWN}}
134 // };
135 // }
136 return true;
137}
138
139float get_3Dbox_iou_len(float center1, float len1, float center2, float len2) {
140 float x11 = center1 - len1 / 2;
141 float x12 = center2 - len2 / 2;
142 float x21 = center1 + len1 / 2;
143 float x22 = center2 + len2 / 2;
144 if (std::min(x22, x21) - std::max(x12, x11) < 0) {
145 return 0;
146 }
147 return std::min(x22, x21) - std::max(x12, x11);
148}
149
151 auto center1 = obj1->center;
152 auto center2 = obj2->center;
153 auto size1 = obj1->size;
154 auto size2 = obj2->size;
155 float x_len = get_3Dbox_iou_len(center1(0), size1(0), center2(0), size2(0));
156 float y_len = get_3Dbox_iou_len(center1(1), size1(1), center2(1), size2(1));
157 float z_len = get_3Dbox_iou_len(center1(2), size1(2), center2(2), size2(2));
158 float v1 = size1(0) * size1(1) * size1(2);
159 float v2 = size2(0) * size2(1) * size2(2);
160 float vo = x_len * y_len * z_len;
161 return vo / (v1 + v2 - vo);
162}
163
164// bool nms_by_strategy(std::shared_ptr<base::Object> obj1,
165// std::shared_ptr<base::Object> obj2,
166// std::map<base::ObjectType, std::vector<base::ObjectType>> table) {
167// if (obj1.get()->type == obj2.get()->type) {
168// return obj1.get()->confidence > obj2.get()->confidence;
169// }
170// std::vector<base::ObjectType> obj_type_array = table[obj1.get()->type];
171// if (std::find(obj_type_array.begin(), obj_type_array.end(),
172// obj2->type) != obj_type_array.end()) {
173// return true;
174// } else {
175// return false;
176// }
177// return true;
178// }
179
181 LidarFrame *frame) {
182 // check input
183 if (frame == nullptr) {
184 AERROR << "Input null frame ptr.";
185 return false;
186 }
187 if (frame->cloud == nullptr) {
188 AERROR << "Input null frame cloud.";
189 return false;
190 }
191 if (frame->cloud->size() == 0) {
192 AERROR << "Input none points.";
193 return false;
194 }
195
196 // record input cloud and lidar frame
197 original_cloud_ = frame->cloud;
198 original_world_cloud_ = frame->world_cloud;
199 lidar_frame_ref_ = frame;
200
201 // check output
202 frame->segmented_objects.clear();
203
204 if (cudaSetDevice(model_param_.preprocess().gpu_id()) != cudaSuccess) {
205 AERROR << "Failed to set device to gpu "
206 << model_param_.preprocess().gpu_id();
207 return false;
208 }
209
210 Timer timer;
211
212 int num_points;
213 cur_cloud_ptr_ = std::shared_ptr<base::PointFCloud>(
214 new base::PointFCloud(*original_cloud_));
215
216 if (model_param_.preprocess().enable_roi_outside_removal()) {
217 cur_cloud_ptr_->CopyPointCloud(*original_cloud_, frame->roi_indices);
218 }
219
220 // down sample the point cloud through filtering beams
221 if (model_param_.preprocess().enable_downsample_beams()) {
222 base::PointFCloudPtr downsample_beams_cloud_ptr(new base::PointFCloud());
223 if (DownSamplePointCloudBeams(
224 cur_cloud_ptr_, downsample_beams_cloud_ptr,
225 model_param_.preprocess().downsample_beams_factor())) {
226 cur_cloud_ptr_ = downsample_beams_cloud_ptr;
227 } else {
228 AWARN << "Down-sample beams factor must be >= 1. Cancel down-sampling."
229 " Current factor: "
230 << model_param_.preprocess().downsample_beams_factor();
231 }
232 }
233
234 // down sample the point cloud through filtering voxel grid
235 if (model_param_.preprocess().enable_downsample_pointcloud()) {
236 DownSampleOptions down_sample_options;
237 ACHECK(down_sample_ != nullptr);
238 down_sample_->Process(down_sample_options, cur_cloud_ptr_);
239 }
240
241 downsample_time_ = timer.toc(true);
242 num_points = cur_cloud_ptr_->size();
243 AINFO << "num points before fusing: " << num_points;
244
245 // fuse clouds of preceding frames with current cloud
246 cur_cloud_ptr_->mutable_points_timestamp()->assign(cur_cloud_ptr_->size(),
247 0.0);
248 if (model_param_.preprocess().enable_fuse_frames() &&
249 model_param_.preprocess().num_fuse_frames() > 1) {
250 // before fusing
251 while (!prev_world_clouds_.empty() &&
252 frame->timestamp - prev_world_clouds_.front()->get_timestamp() >
253 model_param_.preprocess().fuse_time_interval()) {
254 prev_world_clouds_.pop_front();
255 }
256 // transform current cloud to world coordinate and save to a new ptr
257 base::PointDCloudPtr cur_world_cloud_ptr =
258 std::make_shared<base::PointDCloud>();
259 for (size_t i = 0; i < cur_cloud_ptr_->size(); ++i) {
260 auto &pt = cur_cloud_ptr_->at(i);
261 Eigen::Vector3d trans_point(pt.x, pt.y, pt.z);
262 trans_point = lidar_frame_ref_->lidar2world_pose * trans_point;
263 PointD world_point;
264 world_point.x = trans_point(0);
265 world_point.y = trans_point(1);
266 world_point.z = trans_point(2);
267 world_point.intensity = pt.intensity;
268 cur_world_cloud_ptr->push_back(world_point);
269 }
270 cur_world_cloud_ptr->set_timestamp(frame->timestamp);
271
272 // fusing clouds
273 for (auto &prev_world_cloud_ptr : prev_world_clouds_) {
274 num_points += prev_world_cloud_ptr->size();
275 }
276 FuseCloud(cur_cloud_ptr_, prev_world_clouds_);
277
278 // after fusing
279 while (static_cast<int>(prev_world_clouds_.size()) >=
280 model_param_.preprocess().num_fuse_frames() - 1) {
281 prev_world_clouds_.pop_front();
282 }
283 prev_world_clouds_.emplace_back(cur_world_cloud_ptr);
284 }
285 fuse_time_ = timer.toc(true);
286
287 // shuffle points and cut off
288 if (model_param_.preprocess().enable_shuffle_points()) {
289 num_points =
290 std::min(num_points, model_param_.preprocess().max_num_points());
291 std::vector<int> point_indices = GenerateIndices(0, num_points, true);
292 base::PointFCloudPtr shuffle_cloud_ptr(
293 new base::PointFCloud(*cur_cloud_ptr_, point_indices));
294 cur_cloud_ptr_ = shuffle_cloud_ptr;
295 }
296 shuffle_time_ = timer.toc(true);
297
298 // points_array[x, y, z, i,timestampe, ......]
299 std::vector<float> points_data(num_points *
300 model_param_.preprocess().num_point_feature());
301
302 CloudToArray(cur_cloud_ptr_, points_data.data(),
303 model_param_.preprocess().normalizing_factor());
304 cloud_to_array_time_ = timer.toc(true);
305
306 auto input_data_blob = inference_->get_blob(input_blob_names_.at(0));
307 auto output_bbox_blob = inference_->get_blob(output_blob_names_.at(0));
308 auto output_score_blob = inference_->get_blob(output_blob_names_.at(1));
309 auto output_label_blob = inference_->get_blob(output_blob_names_.at(2));
310
311 std::vector<int> points_shape{num_points,
312 model_param_.preprocess().num_point_feature()};
313 input_data_blob->Reshape(points_shape);
314 float *data_ptr = input_data_blob->mutable_cpu_data();
315 memcpy(data_ptr, points_data.data(), points_data.size() * sizeof(float));
316
317 inference_->Infer();
318
319 inference_time_ = timer.toc(true);
320
321 // paddle inference
322 std::vector<float> out_detections;
323 std::vector<int64_t> out_labels;
324 std::vector<float> out_scores;
325
326 // FilterScore(output_bbox_blob, output_label_blob, output_score_blob,
327 // model_param_.postprocess().score_threshold(), &out_detections,
328 // &out_labels, &out_scores);
329
330 FilterDiffScore(output_bbox_blob, output_label_blob, output_score_blob,
331 &out_detections, &out_labels, &out_scores);
332
333 GetObjects(frame->lidar2world_pose, out_detections,
334 out_labels, out_scores, &frame->segmented_objects);
335
336 std::stringstream sstr;
337 sstr << "[CenterPointDetection BeforeNMS] "
338 << std::to_string(frame->timestamp)
339 << " objs: " << frame->segmented_objects.size() << std::endl;
340 for (auto obj : frame->segmented_objects) {
341 sstr << "id = " << obj->id << ": " << obj->center(0) << ", "
342 << obj->center(1) << ", " << obj->center(2) << ", "
343 << obj->size(0) << ", " << obj->size(1) << ", "
344 << obj->size(2) << ", " << obj->theta << ", "
345 << static_cast<int>(obj->type) << ", "
346 << obj->confidence << std::endl;
347 }
348 ADEBUG << sstr.str();
349
350 if (model_param_.filter_by_points()) {
351 FilterObjectsbyPoints(&frame->segmented_objects);
352 }
353
354 PERF_BLOCK("class_nms")
355 if (diff_class_nms_) {
356 FilterObjectsbyClassNMS(&frame->segmented_objects);
357 }
359 nms_time_ = timer.toc(true);
360
361 // filter semantic if it's not unknown
362 if (model_param_.filter_by_semantic_type()) {
363 FilterObjectsbySemanticType(&frame->segmented_objects);
364 }
365
366 FilterForegroundPoints(&frame->segmented_objects);
367
368 SetPointsInROI(&frame->segmented_objects);
369
370 postprocess_time_ = timer.toc(true);
371
372 AINFO << "CenterPoint: "
373 << "\n"
374 << "down sample: " << downsample_time_ << "\t"
375 << "fuse: " << fuse_time_ << "\t"
376 << "shuffle: " << shuffle_time_ << "\t"
377 << "cloud_to_array: " << cloud_to_array_time_ << "\t"
378 << "inference: " << inference_time_ << "\t"
379 << "postprocess: " << postprocess_time_ << "\t"
380 << "nms: " << nms_time_ << "\t";
381
382 std::stringstream ssstr;
383 ssstr << "[CenterPointDetection AfterNMS] "
384 << std::to_string(frame->timestamp)
385 << " objs: " << frame->segmented_objects.size() << std::endl;
386 for (auto obj : frame->segmented_objects) {
387 ssstr << "id = " << obj->id << ": " << obj->center(0) << ", "
388 << obj->center(1) << ", " << obj->center(2) << ", "
389 << obj->size(0) << ", " << obj->size(1) << ", "
390 << obj->size(2) << ", " << obj->theta << ", "
391 << static_cast<int>(obj->type) << std::endl;
392 }
393 ADEBUG << ssstr.str();
394
395 return true;
396}
397
398// normalizing_factor: Normalize intensity range to [0, 1] by this factor
399void CenterPointDetection::CloudToArray(const base::PointFCloudPtr &pc_ptr,
400 float *out_points_array,
401 const float normalizing_factor) {
402 for (size_t i = 0; i < pc_ptr->size(); ++i) {
403 const auto &point = pc_ptr->at(i);
404 float x = point.x;
405 float y = point.y;
406 float z = point.z;
407 float intensity = point.intensity;
408 if (z < z_min_range_ || z > z_max_range_ || y < y_min_range_ ||
409 y > y_max_range_ || x < x_min_range_ || x > x_max_range_) {
410 continue;
411 }
412 out_points_array[i * model_param_.preprocess().num_point_feature() + 0] = x;
413 out_points_array[i * model_param_.preprocess().num_point_feature() + 1] = y;
414 out_points_array[i * model_param_.preprocess().num_point_feature() + 2] = z;
415 out_points_array[i * model_param_.preprocess().num_point_feature() + 3] =
416 intensity / normalizing_factor;
417 // delta of timestamp between prev and cur frames
418 if (5 == model_param_.preprocess().num_point_feature()) {
419 out_points_array[i * model_param_.preprocess().num_point_feature() + 4] =
420 static_cast<float>(pc_ptr->points_timestamp(i));
421 }
422 }
423}
424
425void CenterPointDetection::FuseCloud(
426 const base::PointFCloudPtr &out_cloud_ptr,
427 const std::deque<base::PointDCloudPtr> &fuse_clouds) {
428 for (auto iter = fuse_clouds.rbegin(); iter != fuse_clouds.rend(); ++iter) {
429 double delta_t = lidar_frame_ref_->timestamp - (*iter)->get_timestamp();
430 // transform prev world point cloud to current sensor's coordinates
431 for (size_t i = 0; i < (*iter)->size(); ++i) {
432 auto &point = (*iter)->at(i);
433 Eigen::Vector3d trans_point(point.x, point.y, point.z);
434 trans_point = lidar_frame_ref_->lidar2world_pose.inverse() * trans_point;
435 base::PointF pt;
436 pt.x = static_cast<float>(trans_point(0));
437 pt.y = static_cast<float>(trans_point(1));
438 pt.z = static_cast<float>(trans_point(2));
439 pt.intensity = static_cast<float>(point.intensity);
440 // delta of time between current and prev frame
441 out_cloud_ptr->push_back(pt, delta_t);
442 }
443 }
444}
445
446std::vector<int> CenterPointDetection::GenerateIndices(int start_index,
447 int size, bool shuffle) {
448 // create a range number array
449 std::vector<int> indices(size);
450 std::iota(indices.begin(), indices.end(), start_index);
451
452 // shuffle the index array
453 if (shuffle) {
454 unsigned seed = 0;
455 std::shuffle(indices.begin(), indices.end(),
456 std::default_random_engine(seed));
457 }
458 return indices;
459}
460
461void CenterPointDetection::GetBoxCorner(int num_objects,
462 const std::vector<float> &detections,
463 std::vector<float> &box_corner,
464 std::vector<float> &box_rectangular) {
465 for (int i = 0; i < num_objects; ++i) {
466 float x =
467 detections[i * model_param_.postprocess().num_output_box_feature()];
468 float y =
469 detections[i * model_param_.postprocess().num_output_box_feature() + 1];
470 float w =
471 detections[i * model_param_.postprocess().num_output_box_feature() + 3];
472 float l =
473 detections[i * model_param_.postprocess().num_output_box_feature() + 4];
474 float a =
475 detections[i * model_param_.postprocess().num_output_box_feature() + 6];
476 if (model_param_.quantize() > 0) {
477 w = ceil(w / model_param_.quantize()) * model_param_.quantize();
478 l = ceil(l / model_param_.quantize()) * model_param_.quantize();
479 }
480 if (model_param_.postprocess().width_enlarge_value() > 0) {
481 w = w + model_param_.postprocess().width_enlarge_value();
482 }
483 if (model_param_.postprocess().length_enlarge_value() > 0) {
484 l = l + model_param_.postprocess().length_enlarge_value();
485 }
486
487 float cos_a = cos(a);
488 float sin_a = sin(a);
489 float hw = w * 0.5;
490 float hl = l * 0.5;
491
492 float left_up_x = (-hw) * cos_a + (-hl) * sin_a + x;
493 float left_up_y = (-hw) * (-sin_a) + (-hl) * cos_a + y;
494 float right_up_x = (-hw) * cos_a + (hl)*sin_a + x;
495 float right_up_y = (-hw) * (-sin_a) + (hl)*cos_a + y;
496 float right_down_x = (hw)*cos_a + (hl)*sin_a + x;
497 float right_down_y = (hw) * (-sin_a) + (hl)*cos_a + y;
498 float left_down_x = (hw)*cos_a + (-hl) * sin_a + x;
499 float left_down_y = (hw) * (-sin_a) + (-hl) * cos_a + y;
500
501 box_corner[i * 8 + 0] = left_up_x;
502 box_corner[i * 8 + 1] = left_up_y;
503 box_corner[i * 8 + 2] = right_up_x;
504 box_corner[i * 8 + 3] = right_up_y;
505 box_corner[i * 8 + 4] = right_down_x;
506 box_corner[i * 8 + 5] = right_down_y;
507 box_corner[i * 8 + 6] = left_down_x;
508 box_corner[i * 8 + 7] = left_down_y;
509
510 box_rectangular[i * 4] = std::min(
511 std::min(std::min(left_up_x, right_up_x), right_down_x), left_down_x);
512 box_rectangular[i * 4 + 1] = std::min(
513 std::min(std::min(left_up_y, right_up_y), right_down_y), left_down_y);
514 box_rectangular[i * 4 + 2] = std::max(
515 std::max(std::max(left_up_x, right_up_x), right_down_x), left_down_x);
516 box_rectangular[i * 4 + 3] = std::max(
517 std::max(std::max(left_up_y, right_up_y), right_down_y), left_down_y);
518 }
519}
520
521void CenterPointDetection::GetBoxIndices(
522 int num_objects,
523 const std::vector<float> &detections,
524 const std::vector<float> &box_corner,
525 const std::vector<float> &box_rectangular,
526 std::vector<std::shared_ptr<Object>> *objects) {
527 for (size_t point_idx = 0; point_idx < original_cloud_->size(); ++point_idx) {
528 const auto &point = original_cloud_->at(point_idx);
529 if (model_param_.filter_ground_points() &&
530 original_cloud_->points_label(point_idx) == static_cast<uint8_t>(
532 continue;
533 }
534 float px = point.x;
535 float py = point.y;
536 float pz = point.z;
537
538 int box_count = 0;
539
540 for (int box_idx = 0; box_idx < num_objects; box_idx++) {
541 if (box_count >= model_param_.point2box_max_num()) {
542 break;
543 }
544 if (px < box_rectangular[box_idx * 4 + 0] ||
545 px > box_rectangular[box_idx * 4 + 2]) {
546 continue;
547 }
548 if (py < box_rectangular[box_idx * 4 + 1] ||
549 py > box_rectangular[box_idx * 4 + 3]) {
550 continue;
551 }
552
553 float z =
554 detections[box_idx *
555 model_param_.postprocess().num_output_box_feature() +
556 2];
557 float h =
558 detections[box_idx *
559 model_param_.postprocess().num_output_box_feature() +
560 5];
561 if (pz < (z - h / 2 -
562 model_param_.postprocess().bottom_enlarge_height()) ||
563 pz > (z + h / 2 + model_param_.postprocess().top_enlarge_height())) {
564 continue;
565 }
566
567 float x1 = box_corner[box_idx * 8 + 0];
568 float x2 = box_corner[box_idx * 8 + 2];
569 float x3 = box_corner[box_idx * 8 + 4];
570 float x4 = box_corner[box_idx * 8 + 6];
571 float y1 = box_corner[box_idx * 8 + 1];
572 float y2 = box_corner[box_idx * 8 + 3];
573 float y3 = box_corner[box_idx * 8 + 5];
574 float y4 = box_corner[box_idx * 8 + 7];
575
576 // double angl1 = (px - x1) * (x2 - x1) + (py - y1) * (y2 - y1);
577 // double angl2 = (px - x2) * (x3 - x2) + (py - y2) * (y3 - y2);
578 // double angl3 = (px - x3) * (x4 - x3) + (py - y3) * (y4 - y3);
579 // double angl4 = (px - x4) * (x1 - x4) + (py - y4) * (y1 - y4);
580
581 double angl1 = (px - x1) * (y2 - y1) - (py - y1) * (x2 - x1);
582 double angl2 = (px - x2) * (y3 - y2) - (py - y2) * (x3 - x2);
583 double angl3 = (px - x3) * (y4 - y3) - (py - y3) * (x4 - x3);
584 double angl4 = (px - x4) * (y1 - y4) - (py - y4) * (x1 - x4);
585
586 if ((angl1 <= 0 && angl2 <= 0 && angl3 <= 0 && angl4 <= 0) ||
587 (angl1 >= 0 && angl2 >= 0 && angl3 >= 0 && angl4 >= 0)) {
588 auto &object = objects->at(box_idx);
589 const auto &world_point = original_world_cloud_->at(point_idx);
590 const double timestamp =
591 original_cloud_->points_timestamp(point_idx);
592 const float height =
593 original_cloud_->points_height(point_idx);
594 const int32_t beam_id =
595 original_cloud_->points_beam_id(point_idx);
596 const uint8_t label =
597 original_cloud_->points_label(point_idx);
598 const uint8_t semantic_label =
599 original_cloud_->points_semantic_label(point_idx);
600 object->lidar_supplement.point_ids.push_back(point_idx);
601 object->lidar_supplement.cloud.push_back(
602 point, timestamp, height, beam_id, label, semantic_label);
603 object->lidar_supplement.cloud_world.push_back(
604 world_point, timestamp, height, beam_id, label, semantic_label);
605 }
606 }
607 }
608}
609
610void CenterPointDetection::GetObjects(
611 const Eigen::Affine3d &pose,
612 const std::vector<float> &detections,
613 const std::vector<int64_t> &labels,
614 const std::vector<float> &scores,
615 std::vector<std::shared_ptr<Object>> *objects) {
616 int num_objects =
617 detections.size() / model_param_.postprocess().num_output_box_feature();
618
619 objects->clear();
620 base::ObjectPool::Instance().BatchGet(num_objects, objects);
621
622 for (int i = 0; i < num_objects; ++i) {
623 auto &object = objects->at(i);
624 object->id = i;
625
626 // no velocity
627 float x = detections.at(
628 i * model_param_.postprocess().num_output_box_feature() + 0);
629 float y = detections.at(
630 i * model_param_.postprocess().num_output_box_feature() + 1);
631 float z = detections.at(
632 i * model_param_.postprocess().num_output_box_feature() + 2);
633 float dx = detections.at(
634 i * model_param_.postprocess().num_output_box_feature() + 4);
635 float dy = detections.at(
636 i * model_param_.postprocess().num_output_box_feature() + 3);
637 float dz = detections.at(
638 i * model_param_.postprocess().num_output_box_feature() + 5);
639 float yaw = detections.at(
640 i * model_param_.postprocess().num_output_box_feature() + 6);
641 yaw = -yaw - M_PI / 2;
642
643 object->size(0) = dx;
644 object->size(1) = dy;
645 object->size(2) = dz;
646 object->center(0) = x;
647 object->center(1) = y;
648 object->center(2) = z;
649
650 // directions
651 object->theta = yaw;
652 object->direction[0] = cosf(yaw);
653 object->direction[1] = sinf(yaw);
654 object->direction[2] = 0;
655 object->lidar_supplement.is_orientation_ready = true;
656 object->confidence = scores.at(i);
657
658 // centerpoint-model original output
659 object->lidar_supplement.detections.resize(7);
660 object->lidar_supplement.detections[0] = x;
661 object->lidar_supplement.detections[1] = y;
662 object->lidar_supplement.detections[2] = z;
663 object->lidar_supplement.detections[3] = dx;
664 object->lidar_supplement.detections[4] = dy;
665 object->lidar_supplement.detections[5] = dz;
666 object->lidar_supplement.detections[6] = yaw;
667
668 // compute vertexes of bounding box and transform to world coordinate
669 object->lidar_supplement.on_use = true;
670 object->lidar_supplement.is_background = false;
671
672 // classification
673 object->lidar_supplement.raw_probs.push_back(std::vector<float>(
674 static_cast<int>(base::ObjectType::MAX_OBJECT_TYPE), 0.f));
675 object->lidar_supplement.raw_classification_methods.push_back(Name());
676 object->sub_type = GetObjectSubType(labels.at(i));
677 object->type = base::kSubType2TypeMap.at(object->sub_type);
678 if (object->sub_type == base::ObjectSubType::TRAFFICCONE) {
679 object->type = base::ObjectType::UNKNOWN;
680 }
681 object->lidar_supplement.raw_probs.back()[static_cast<int>(object->type)] =
682 1.0f;
683 // copy to type
684 object->type_probs.assign(object->lidar_supplement.raw_probs.back().begin(),
685 object->lidar_supplement.raw_probs.back().end());
686 }
687
688 std::vector<float> box_corner(num_objects * 8);
689 std::vector<float> box_rectangular(num_objects * 4);
690 GetBoxCorner(num_objects, detections, box_corner, box_rectangular);
691 GetBoxIndices(
692 num_objects, detections, box_corner, box_rectangular, objects);
693 AINFO << "[CenterPoint] we get " << num_objects << " objs";
694}
695
696// for nuscenes model
697// base::ObjectSubType CenterPointDetection::GetObjectSubType(const int label) {
698// switch (label) {
699// case 0:
700// return base::ObjectSubType::CAR;
701// case 1:
702// return base::ObjectSubType::TRUCK;
703// case 3:
704// return base::ObjectSubType::BUS;
705// case 6:
706// return base::ObjectSubType::MOTORCYCLIST;
707// case 7:
708// return base::ObjectSubType::CYCLIST;
709// case 8:
710// return base::ObjectSubType::PEDESTRIAN;
711// case 9:
712// return base::ObjectSubType::TRAFFICCONE;
713// default:
714// return base::ObjectSubType::UNKNOWN;
715// }
716// }
717
718// for kitti model
719// base::ObjectSubType CenterPointDetection::GetObjectSubType(const int label) {
720// switch (label) {
721// case 0:
722// return base::ObjectSubType::CAR;
723// case 1:
724// return base::ObjectSubType::CYCLIST;
725// case 2:
726// return base::ObjectSubType::PEDESTRIAN;
727// default:
728// return base::ObjectSubType::UNKNOWN;
729// }
730// }
731
732// for apollo model
733base::ObjectSubType CenterPointDetection::GetObjectSubType(const int label) {
734 switch (label) {
735 case 0:
737 case 1:
739 case 2:
741 case 3:
743 default:
745 }
746}
747
748// for apollo model
749float CenterPointDetection::GetObjectScoreThreshold(const int label) {
750 switch (label) {
751 case 0:
752 return small_mot_score_threshold_;
753 case 1:
754 return big_mot_score_threshold_;
755 case 2:
756 return cyc_score_threshold_;
757 case 3:
758 return ped_score_threshold_;
759 default:
760 return cone_score_threshold_;
761 }
762}
763
764void CenterPointDetection::FilterScore(
765 const std::shared_ptr<apollo::perception::base::Blob<float>> &box3d,
766 const std::shared_ptr<apollo::perception::base::Blob<float>> &label,
767 const std::shared_ptr<apollo::perception::base::Blob<float>> &scores,
768 float score_threshold, std::vector<float> *box3d_filtered,
769 std::vector<int64_t> *label_preds_filtered,
770 std::vector<float> *scores_filtered) {
771 const auto bbox_ptr = box3d->cpu_data();
772 const auto label_ptr = label->cpu_data();
773 const auto score_ptr = scores->cpu_data();
774
775 for (int i = 0; i < scores->count(); ++i) {
776 if (score_ptr[i] > score_threshold) {
777 box3d_filtered->insert(
778 box3d_filtered->end(),
779 bbox_ptr + model_param_.postprocess().num_output_box_feature() * i,
780 bbox_ptr +
781 model_param_.postprocess().num_output_box_feature() * (i + 1));
782 label_preds_filtered->insert(label_preds_filtered->end(),
783 static_cast<int64_t>(label_ptr[i]));
784
785 scores_filtered->push_back(score_ptr[i]);
786 }
787 }
788}
789
790void CenterPointDetection::FilterDiffScore(
791 const std::shared_ptr<apollo::perception::base::Blob<float>> &box3d,
792 const std::shared_ptr<apollo::perception::base::Blob<float>> &label,
793 const std::shared_ptr<apollo::perception::base::Blob<float>> &scores,
794 std::vector<float> *box3d_filtered,
795 std::vector<int64_t> *label_preds_filtered,
796 std::vector<float> *scores_filtered) {
797 const auto bbox_ptr = box3d->cpu_data();
798 const auto label_ptr = label->cpu_data();
799 const auto score_ptr = scores->cpu_data();
800
801 float threshold = 0.0;
802 for (int i = 0; i < scores->count(); ++i) {
803 threshold = GetObjectScoreThreshold(static_cast<int64_t>(label_ptr[i]));
804 if (score_ptr[i] > threshold) {
805 box3d_filtered->insert(box3d_filtered->end(),
806 bbox_ptr + model_param_.postprocess().num_output_box_feature() * i,
807 bbox_ptr +
808 model_param_.postprocess().num_output_box_feature() * (i + 1));
809 label_preds_filtered->insert(label_preds_filtered->end(),
810 static_cast<int64_t>(label_ptr[i]));
811 scores_filtered->push_back(score_ptr[i]);
812 }
813 }
814}
815
816void CenterPointDetection::FilterObjectsbyPoints(
817 std::vector<std::shared_ptr<Object>> *objects) {
818 size_t valid_num = 0;
819 for (uint32_t i = 0; i < objects->size(); i++) {
820 auto &object = objects->at(i);
821 uint32_t num_points_thresholds = model_param_.min_points_threshold();
822 if (object->lidar_supplement.cloud.size() >= num_points_thresholds) {
823 objects->at(valid_num) = object;
824 valid_num++;
825 }
826 }
827 objects->resize(valid_num);
828}
829
830void CenterPointDetection::FilterForegroundPoints(
831 std::vector<std::shared_ptr<Object>> *objects) {
832 CloudMask mask;
833 mask.Set(original_cloud_->size(), 0);
834 mask.AddIndicesOfIndices(lidar_frame_ref_->roi_indices,
835 lidar_frame_ref_->non_ground_indices, 1);
836 for (uint32_t i = 0; i < objects->size(); ++i) {
837 auto &object = objects->at(i);
838 base::PointIndices ind;
839 ind.indices = object->lidar_supplement.point_ids;
840 mask.RemoveIndices(ind);
841 }
842 mask.GetValidIndices(&lidar_frame_ref_->secondary_indices);
843}
844
845void CenterPointDetection::FilterObjectsbyClassNMS(
846 std::vector<std::shared_ptr<base::Object>> *objects) {
847 auto ordinary_nms_strategy = [&](size_t i, size_t j,
848 bool use_strategy = false) {
849 // return FILTER_INDEX
850 size_t type_i = static_cast<size_t>(objects->at(i)->type);
851 size_t type_j = static_cast<size_t>(objects->at(j)->type);
852 size_t filter_index =
853 (objects->at(i)->confidence < objects->at(j)->confidence) ? i : j;
854 // ordinary_nms_strategy: VEHICLE > BICYCLE > PEDESTRIAN > TRAFFICCONE
855 if (nms_strategy_ || use_strategy) {
856 return type_i > type_j ? j : i;
857 }
858 return filter_index;
859 };
860
861 auto special_nms_strategy = [&](size_t keep_index,
862 base::ObjectType keep_type, size_t filter_index,
863 base::ObjectType filter_type, float conf_buffer) {
864 if (nms_strategy_) {
865 return;
866 }
867 objects->at(keep_index)->lidar_supplement.raw_probs.clear();
868 objects->at(keep_index)->type_probs.clear();
869
870 objects->at(keep_index)->lidar_supplement.raw_probs.push_back(
871 std::vector<float>(static_cast<int>(
873 float sum_confidence = objects->at(keep_index)->confidence +
874 objects->at(filter_index)->confidence;
875 float filter_prob = 1.0 * (objects->at(filter_index)->confidence
876 + conf_buffer) / (sum_confidence + conf_buffer);
877 float keep_prob = 1.0 * objects->at(keep_index)->confidence /
878 (sum_confidence + conf_buffer);
879 objects->at(keep_index)->lidar_supplement.raw_probs.back()[
880 static_cast<int>(filter_type)] = filter_prob;
881 objects->at(keep_index)->lidar_supplement.raw_probs.back()[
882 static_cast<int>(keep_type)] = keep_prob;
883 objects->at(keep_index)->type_probs.assign(
884 objects->at(keep_index)->lidar_supplement.raw_probs.back().begin(),
885 objects->at(keep_index)->lidar_supplement.raw_probs.back().end());
886 };
887
888 auto get_corners = [&](const base::ObjectPtr obj) {
889 std::vector<float> box_corner;
890 box_corner.resize(8);
891 float x = obj->center(0);
892 float y = obj->center(1);
893 float l = obj->size(0);
894 float w = obj->size(1);
895 float r = obj->theta;
896 // if (length_enlarge_value_ > 0) {
897 // l = l + length_enlarge_value_;
898 // }
899 // if (width_enlarge_value_ > 0) {
900 // w = w + width_enlarge_value_;
901 // }
902 float cos_r = cos(r);
903 float sin_r = sin(r);
904 float hl = l * 0.5;
905 float hw = w * 0.5;
906 float x1 = (-hl) * cos_r - (-hw) * sin_r + x;
907 float y1 = (-hl) * sin_r + (-hw) * cos_r + y;
908 float x2 = (hl) * cos_r - (-hw) * sin_r + x;
909 float y2 = (hl) * sin_r + (-hw) * cos_r + y;
910 float x3 = (hl) * cos_r - (hw) * sin_r + x;
911 float y3 = (hl) * sin_r + (hw) * cos_r + y;
912 float x4 = (-hl) * cos_r - (hw) * sin_r + x;
913 float y4 = (-hl) * sin_r + (hw) * cos_r + y;
914 box_corner[0] = x1;
915 box_corner[1] = y1;
916 box_corner[2] = x2;
917 box_corner[3] = y2;
918 box_corner[4] = x3;
919 box_corner[5] = y3;
920 box_corner[6] = x4;
921 box_corner[7] = y4;
922 return box_corner;
923 };
924
925 auto trangle_area_cpu = [&](float* a, float* b, float* c) {
926 return ((a[0] - c[0]) * (b[1] - c[1]) -
927 (a[1] - c[1]) * (b[0] - c[0])) / 2.f;
928 };
929
930 auto sort_vertex_in_convex_polygon_cpu = [&](float* int_pts,
931 int num_of_inter) {
932 if (num_of_inter == 0) {
933 return;
934 }
935 float center_x = 0.f;
936 float center_y = 0.f;
937 for (int i = 0; i < num_of_inter; i++) {
938 center_x += int_pts[2 * i];
939 center_y += int_pts[2 * i + 1];
940 }
941 center_x /= num_of_inter;
942 center_y /= num_of_inter;
943 float v0;
944 float v1;
945 float vs[16];
946 for (int i = 0; i < num_of_inter; i++) {
947 v0 = int_pts[2 * i] - center_x;
948 v1 = int_pts[2 * i + 1] - center_y;
949 float d = sqrt(v0 * v0 + v1 * v1);
950 v0 = v0 / d;
951 v1 = v1 / d;
952 if (v1 < 0) {
953 v0 = -2 - v0;
954 }
955 vs[i] = v0;
956 }
957 int j = 0;
958 float temp = 0.f;
959 for (int i = 0; i < num_of_inter; i++) {
960 if (vs[i - 1] > vs[i]) {
961 temp = vs[i];
962 float tx = int_pts[2 * i];
963 float ty = int_pts[2 * i + 1];
964 j = i;
965 while (j > 0 && vs[j - 1] > temp) {
966 vs[j] = vs[j - 1];
967 int_pts[j * 2] = int_pts[j * 2 - 2];
968 int_pts[j * 2 + 1] = int_pts[j * 2 - 1];
969 j -= 1;
970 }
971 vs[j] = temp;
972 int_pts[j * 2] = tx;
973 int_pts[j * 2 + 1] = ty;
974 }
975 }
976 };
977
978 auto line_segment_intersection_cpu = [&](const float* pts1, const float* pts2,
979 int i, int j, float* temp_pts) {
980 float A0 = pts1[2 * i];
981 float A1 = pts1[2 * i + 1];
982
983 float B0 = pts1[2 * ((i + 1) % 4)];
984 float B1 = pts1[2 * ((i + 1) % 4) + 1];
985
986 float C0 = pts2[2 * j];
987 float C1 = pts2[2 * j + 1];
988
989 float D0 = pts2[2 * ((j + 1) % 4)];
990 float D1 = pts2[2 * ((j + 1) % 4) + 1];
991 float BA0 = B0 - A0;
992 float BA1 = B1 - A1;
993 float DA0 = D0 - A0;
994 float CA0 = C0 - A0;
995 float DA1 = D1 - A1;
996 float CA1 = C1 - A1;
997 bool acd = DA1 * CA0 > CA1 * DA0;
998 bool bcd = (D1 - B1) * (C0 - B0) > (C1 - B1) * (D0 - B0);
999 if (acd != bcd) {
1000 bool abc = CA1 * BA0 > BA1 * CA0;
1001 bool abd = DA1 * BA0 > BA1 * DA0;
1002 if (abc != abd) {
1003 float DC0 = D0 - C0;
1004 float DC1 = D1 - C1;
1005 float ABBA = A0 * B1 - B0 * A1;
1006 float CDDC = C0 * D1 - D0 * C1;
1007 float DH = BA1 * DC0 - BA0 * DC1;
1008 float Dx = ABBA * DC0 - BA0 * CDDC;
1009 float Dy = ABBA * DC1 - BA1 * CDDC;
1010 temp_pts[0] = Dx / DH;
1011 temp_pts[1] = Dy / DH;
1012 return true;
1013 }
1014 }
1015 return false;
1016 };
1017
1018 auto point_in_quadrilateral_cpu = [&](float pt_x, float pt_y,
1019 const float* corners) {
1020 float ab0 = corners[2] - corners[0];
1021 float ab1 = corners[3] - corners[1];
1022 float ad0 = corners[6] - corners[0];
1023 float ad1 = corners[7] - corners[1];
1024 float ap0 = pt_x - corners[0];
1025 float ap1 = pt_y - corners[1];
1026 float abab = ab0 * ab0 + ab1 * ab1;
1027 float abap = ab0 * ap0 + ab1 * ap1;
1028 float adad = ad0 * ad0 + ad1 * ad1;
1029 float adap = ad0 * ap0 + ad1 * ap1;
1030 return abab >= abap && abap >= 0 && adad >= adap && adap >= 0;
1031 };
1032
1033 auto rotate_inter = [&](const float *corners1, const float *corners2) {
1034 float intersection_corners[16];
1035 // quadrilateral_intersection
1036 int num_of_inter = 0;
1037 for (int i = 0; i < 4; i++) {
1038 if (point_in_quadrilateral_cpu(corners1[2 * i],
1039 corners1[2 * i + 1], corners2)) {
1040 intersection_corners[num_of_inter * 2] = corners1[2 * i];
1041 intersection_corners[num_of_inter * 2 + 1] = corners1[2 * i + 1];
1042 num_of_inter += 1;
1043 }
1044 if (point_in_quadrilateral_cpu(corners2[2 * i],
1045 corners2[2 * i + 1], corners1)) {
1046 intersection_corners[num_of_inter * 2] = corners2[2 * i];
1047 intersection_corners[num_of_inter * 2 + 1] = corners2[2 * i + 1];
1048 num_of_inter += 1;
1049 }
1050 }
1051 for (int i = 0; i < 4; i++) {
1052 for (int j = 0; j < 4; j++) {
1053 if (line_segment_intersection_cpu(corners1, corners2, i, j,
1054 intersection_corners + num_of_inter * 2)) {
1055 ++num_of_inter;
1056 }
1057 }
1058 }
1059 sort_vertex_in_convex_polygon_cpu(intersection_corners, num_of_inter);
1060 // area
1061 float area_val = 0.f;
1062 for (int i = 0; i < num_of_inter - 2; i++) {
1063 area_val += abs(trangle_area_cpu(intersection_corners,
1064 intersection_corners + 2 * (i + 1),
1065 intersection_corners + 2 * (i + 2)));
1066 }
1067 return area_val;
1068 };
1069
1070 auto calculate_nms = [&](base::ObjectPtr obj1, base::ObjectPtr obj2) {
1071 std::vector<float> box_corner1 = get_corners(obj1);
1072 std::vector<float> box_corner2 = get_corners(obj2);
1073 float area_inter = rotate_inter(box_corner1.data(), box_corner2.data());
1074 float overlap = area_inter / std::max(
1075 obj1->size(0) * obj1->size(1) +
1076 obj2->size(0) * obj2->size(1) - area_inter,
1077 0.001f);
1078 return overlap;
1079 };
1080
1081 std::vector<bool> delete_array(objects->size(), false);
1082 std::vector<bool> nms_visited(objects->size(), false);
1083 std::vector<std::vector<size_t>> nms_pairs;
1084 nms_pairs.resize(objects->size());
1085 // different class nms
1086 for (size_t i = 0; i < objects->size(); i++) {
1087 auto &obj_i = objects->at(i);
1088 if (!obj_i || nms_visited[i]) {
1089 continue;
1090 }
1091 for (size_t j = i + 1; j < objects->size(); j++) {
1092 auto &obj_j = objects->at(j);
1093 if (!obj_j) {
1094 continue;
1095 }
1096 if (calculate_nms(obj_i, obj_j) <= diff_class_iou_) {
1097 continue;
1098 }
1099 if (static_cast<int>(obj_i->type) == static_cast<int>(obj_j->type)) {
1100 continue;
1101 }
1102 nms_visited[j] = true;
1103 nms_pairs[i].push_back(j);
1104 }
1105 }
1106 // do NMS
1107 for (size_t i = 0; i < objects->size(); i++) {
1108 if (nms_pairs[i].size() == 0) {
1109 continue;
1110 }
1111 if (nms_pairs[i].size() == 1) {
1112 size_t filter_index = ordinary_nms_strategy(i, nms_pairs[i][0]);
1113 size_t keep_index = filter_index == i ? nms_pairs[i][0] : i;
1114
1115 delete_array[keep_index] = false;
1116 delete_array[filter_index] = true;
1117
1118 // special-nms-strategy
1119 auto filter_type = objects->at(filter_index)->type;
1120 auto reserve_type = objects->at(keep_index)->type;
1121 // Only trafficcone reserve but bicycle filter -> add bicycle conf
1122 if (filter_type == base::ObjectType::BICYCLE &&
1123 reserve_type == base::ObjectType::UNKNOWN) {
1124 special_nms_strategy(keep_index, base::ObjectType::UNKNOWN,
1125 filter_index, base::ObjectType::BICYCLE, 0.3);
1126 }
1127 // Only pedestrian reserve but bicycle filter -> add bicycle conf
1128 if (filter_type == base::ObjectType::BICYCLE &&
1129 reserve_type == base::ObjectType::PEDESTRIAN) {
1130 special_nms_strategy(keep_index, base::ObjectType::PEDESTRIAN,
1131 filter_index, base::ObjectType::BICYCLE, 0.2);
1132 }
1133 // Only trafficcone reserve but ped filter -> add ped conf
1134 // if (filter_type == base::ObjectType::PEDESTRIAN &&
1135 // reserve_type == base::ObjectType::UNKNOWN) {
1136 // special_nms_strategy(keep_index, base::ObjectType::UNKNOWN,
1137 // filter_index, base::ObjectType::PEDESTRIAN, 0.2);
1138 // }
1139 // Only ped reserve but trafficcone filter -> add trafficcone conf
1140 if (filter_type == base::ObjectType::UNKNOWN &&
1141 reserve_type == base::ObjectType::PEDESTRIAN) {
1142 special_nms_strategy(keep_index, base::ObjectType::PEDESTRIAN,
1143 filter_index, base::ObjectType::UNKNOWN, 0.2);
1144 }
1145 ADEBUG << "Only Two NMS: reserve " << keep_index
1146 << " filter " << filter_index;
1147 }
1148 if (nms_pairs[i].size() >= 2) {
1149 // car strategy
1150 bool have_car = false;
1151 if (objects->at(i)->type == base::ObjectType::VEHICLE) {
1152 have_car = true;
1153 }
1154 for (size_t k = 0; k < nms_pairs[i].size() && !have_car; k++) {
1155 auto type = objects->at(nms_pairs[i][k])->type;
1156 if (type == base::ObjectType::VEHICLE) {
1157 have_car = true;
1158 break;
1159 }
1160 }
1161 // no car -> BICYCLE priorTo PEDESTRIAN priorTo TRAFFICCONE
1162 // have car -> confidence
1163 if (have_car) {
1164 auto keep_conf = objects->at(i)->confidence;
1165 auto keep_index = i;
1166 for (size_t k = 0; k < nms_pairs[i].size(); k++) {
1167 if (objects->at(nms_pairs[i][k])->confidence > keep_conf) {
1168 delete_array[keep_index] = true;
1169 keep_conf = objects->at(nms_pairs[i][k])->confidence;
1170 keep_index = nms_pairs[i][k];
1171 } else {
1172 delete_array[nms_pairs[i][k]] = true;
1173 ADEBUG << "NMS filter_index: " << nms_pairs[i][k];
1174 }
1175 }
1176 } else {
1177 auto keep_type = static_cast<size_t>(objects->at(i)->type);
1178 auto keep_index = i;
1179 for (size_t k = 0; k < nms_pairs[i].size(); k++) {
1180 if (static_cast<size_t>(
1181 objects->at(nms_pairs[i][k])->type) > keep_type) {
1182 delete_array[keep_index] = true;
1183 keep_type = static_cast<size_t>(
1184 objects->at(nms_pairs[i][k])->type);
1185 keep_index = nms_pairs[i][k];
1186 } else {
1187 delete_array[nms_pairs[i][k]] = true;
1188 ADEBUG << "NMS filter_index: " << nms_pairs[i][k];
1189 }
1190 }
1191 }
1192 }
1193 }
1194 size_t valid_num = 0;
1195 for (size_t i = 0; i < objects->size(); i++) {
1196 auto &object = objects->at(i);
1197 if (!delete_array[i]) {
1198 objects->at(valid_num) = object;
1199 valid_num++;
1200 }
1201 }
1202 objects->resize(valid_num);
1203}
1204
1205void CenterPointDetection::FilterObjectsbySemanticType(
1206 std::vector<std::shared_ptr<base::Object>> *objects) {
1207 std::vector<bool> filter_flag(objects->size(), false);
1208 for (size_t i = 0; i < objects->size(); i++) {
1209 auto object = objects->at(i);
1210 std::vector<int> type_count(static_cast<int>(
1212 for (size_t k = 0; k < object->lidar_supplement.cloud.size(); k++) {
1214 object->lidar_supplement.cloud.points_semantic_label(k));
1215 int index = static_cast<int>(label);
1216 if (index >= 0 &&
1217 index < static_cast<int>(PointSemanticLabel::MAX_LABEL)) {
1218 type_count[index]++;
1219 }
1220 }
1221 // get max index
1222 int max_value = -1;
1223 int max_index = 0;
1224 for (size_t j = 0; j < type_count.size(); j++) {
1225 if (type_count.at(j) > max_value) {
1226 max_value = type_count.at(j);
1227 max_index = j;
1228 }
1229 }
1230 if (max_index != static_cast<int>(PointSemanticLabel::OBJECT)) {
1231 filter_flag.at(i) = true;
1232 }
1233 }
1234 // filter object which semantic type is not unknown
1235 int valid_size = 0;
1236 for (size_t i = 0; i < objects->size(); i++) {
1237 if (filter_flag.at(i)) {
1238 continue;
1239 }
1240 objects->at(valid_size) = objects->at(i);
1241 valid_size++;
1242 }
1243 AINFO << "Filter " << (objects->size() - valid_size)
1244 << " objects from " << objects->size() << " objects.";
1245 objects->resize(valid_size);
1246}
1247
1248void CenterPointDetection::SetPointsInROI(
1249 std::vector<std::shared_ptr<Object>> *objects) {
1250 CloudMask roi_mask_;
1251 roi_mask_.Set(original_cloud_->size(), 0);
1252 roi_mask_.AddIndices(lidar_frame_ref_->roi_indices, 1);
1253 for (uint32_t i = 0; i < objects->size(); ++i) {
1254 auto &object = objects->at(i);
1255 object->lidar_supplement.num_points_in_roi =
1256 roi_mask_.ValidIndicesCount(object->lidar_supplement.point_ids);
1257 }
1258}
1259
1261
1262} // namespace lidar
1263} // namespace perception
1264} // namespace apollo
#define PERCEPTION_REGISTER_LIDARDETECTOR(name)
static PluginManager * Instance()
get singleton instance of PluginManager
std::shared_ptr< Base > CreateInstance(const std::string &derived_class)
create plugin instance of derived class based on Base
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
Definition blob.h:88
CenterPointDetection()
Construct a new Center Point Detection object
bool Init(const LidarDetectorInitOptions &options=LidarDetectorInitOptions()) override
Init of Center Point Detection module
std::string Name() const
Name of Center Point Detection module
bool Detect(const LidarDetectorOptions &options, LidarFrame *frame) override
Detect foreground object using centerpoint
static std::string GetFullClassName(const std::string &class_name)
Given the class name of perception module, combine the namespace "apollo::perception::lidar::" with i...
double toc(bool reset=false)
Definition lidar_timer.h:28
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
float cos(Angle16 a)
Definition angle.cc:42
float sin(Angle16 a)
Definition angle.cc:25
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
uint32_t height
Height of point cloud
Point< float > PointF
Definition point.h:56
std::shared_ptr< PointDCloud > PointDCloudPtr
std::shared_ptr< PointFCloud > PointFCloudPtr
const std::map< ObjectSubType, ObjectType > kSubType2TypeMap
ObjectSubType mapping
std::shared_ptr< Object > ObjectPtr
Definition object.h:127
Point< double > PointD
Definition point.h:57
std::vector< std::string > GetBlobNames(const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
Definition model_util.cc:23
void AddShape(std::map< std::string, std::vector< int > > *shape_map, const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
Definition model_util.cc:32
Inference * CreateInferenceByName(const std::string &frame_work, const std::string &proto_file, const std::string &weight_file, const std::vector< std::string > &outputs, const std::vector< std::string > &inputs, const std::string &model_root)
PointSemanticLabel GetSemanticLabel(uint8_t value)
Image< uchar > * threshold(Image< T > *src, int t)
Threshold image
Definition imutil.h:79
float get_3dbox_iou(base::ObjectPtr obj1, base::ObjectPtr obj2)
T abs(const T &x)
Get absolute value of x
Definition misc.h:63
float get_3Dbox_iou_len(float center1, float len1, float center2, float len2)
std::string GetModelFile(const std::string &model_name, const std::string &file_name)
Get the model file path by model path and file name
Definition util.cc:55
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
Definition util.cc:80
std::string GetModelPath(const std::string &model_name)
Get the model path by model name, search from APOLLO_MODEL_PATH
Definition util.cc:44
class register implement
Definition arena_queue.h:37
#define PERF_BLOCK_END
Definition profiler.h:53
#define PERF_BLOCK(...)
Definition profiler.h:52
std::shared_ptr< base::AttributePointCloud< base::PointD > > world_cloud
Definition lidar_frame.h:37
std::vector< std::shared_ptr< base::Object > > segmented_objects
Definition lidar_frame.h:53
std::shared_ptr< base::AttributePointCloud< base::PointF > > cloud
Definition lidar_frame.h:35
optional common::PointCloudPostProcess postprocess
optional common::PointCloudPreProcess preprocess