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>
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) {}
65 std::string config_file =
69 const auto &model_info = model_param_.
info();
70 std::string model_path =
GetModelPath(model_info.name());
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());
81 model_info.framework(), proto_file, weight_file, output_blob_names_,
84 std::map<std::string, std::vector<int>> shape_map;
88 if (!inference_->Init(shape_map)) {
93 z_min_range_ = std::max(
104 small_mot_score_threshold_ =
106 big_mot_score_threshold_ =
109 if (model_param_.has_plugins()) {
110 const auto &plugin = model_param_.
plugins();
111 const auto &name = plugin.
name();
116 AINFO <<
"Failed to find down_sample plugin: " << name <<
", skipped";
122 if (!down_sample_->Init(option)) {
123 AINFO <<
"Failed to init down_sample plugin: " << name <<
", skipped";
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) {
147 return std::min(x22, x21) - std::max(x12, x11);
151 auto center1 = obj1->center;
152 auto center2 = obj2->center;
153 auto size1 = obj1->size;
154 auto size2 = obj2->size;
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);
183 if (frame ==
nullptr) {
184 AERROR <<
"Input null frame ptr.";
187 if (frame->
cloud ==
nullptr) {
188 AERROR <<
"Input null frame cloud.";
191 if (frame->
cloud->size() == 0) {
192 AERROR <<
"Input none points.";
197 original_cloud_ = frame->
cloud;
199 lidar_frame_ref_ = frame;
205 AERROR <<
"Failed to set device to gpu "
213 cur_cloud_ptr_ = std::shared_ptr<base::PointFCloud>(
217 cur_cloud_ptr_->CopyPointCloud(*original_cloud_, frame->
roi_indices);
223 if (DownSamplePointCloudBeams(
224 cur_cloud_ptr_, downsample_beams_cloud_ptr,
226 cur_cloud_ptr_ = downsample_beams_cloud_ptr;
228 AWARN <<
"Down-sample beams factor must be >= 1. Cancel down-sampling."
237 ACHECK(down_sample_ !=
nullptr);
238 down_sample_->Process(down_sample_options, cur_cloud_ptr_);
241 downsample_time_ = timer.
toc(
true);
242 num_points = cur_cloud_ptr_->size();
243 AINFO <<
"num points before fusing: " << num_points;
246 cur_cloud_ptr_->mutable_points_timestamp()->assign(cur_cloud_ptr_->size(),
251 while (!prev_world_clouds_.empty() &&
252 frame->
timestamp - prev_world_clouds_.front()->get_timestamp() >
254 prev_world_clouds_.pop_front();
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);
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);
270 cur_world_cloud_ptr->set_timestamp(frame->
timestamp);
273 for (
auto &prev_world_cloud_ptr : prev_world_clouds_) {
274 num_points += prev_world_cloud_ptr->size();
276 FuseCloud(cur_cloud_ptr_, prev_world_clouds_);
279 while (
static_cast<int>(prev_world_clouds_.size()) >=
281 prev_world_clouds_.pop_front();
283 prev_world_clouds_.emplace_back(cur_world_cloud_ptr);
285 fuse_time_ = timer.
toc(
true);
291 std::vector<int> point_indices = GenerateIndices(0, num_points,
true);
294 cur_cloud_ptr_ = shuffle_cloud_ptr;
296 shuffle_time_ = timer.
toc(
true);
299 std::vector<float> points_data(num_points *
302 CloudToArray(cur_cloud_ptr_, points_data.data(),
304 cloud_to_array_time_ = timer.
toc(
true);
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));
311 std::vector<int> points_shape{num_points,
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));
319 inference_time_ = timer.
toc(
true);
322 std::vector<float> out_detections;
323 std::vector<int64_t> out_labels;
324 std::vector<float> out_scores;
330 FilterDiffScore(output_bbox_blob, output_label_blob, output_score_blob,
331 &out_detections, &out_labels, &out_scores);
336 std::stringstream sstr;
337 sstr <<
"[CenterPointDetection BeforeNMS] "
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;
355 if (diff_class_nms_) {
359 nms_time_ = timer.
toc(
true);
370 postprocess_time_ = timer.
toc(
true);
372 AINFO <<
"CenterPoint: "
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";
382 std::stringstream ssstr;
383 ssstr <<
"[CenterPointDetection AfterNMS] "
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;
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);
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_) {
416 intensity / normalizing_factor;
420 static_cast<float>(pc_ptr->points_timestamp(i));
425void CenterPointDetection::FuseCloud(
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();
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);
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);
441 out_cloud_ptr->push_back(pt, delta_t);
446std::vector<int> CenterPointDetection::GenerateIndices(
int start_index,
447 int size,
bool shuffle) {
449 std::vector<int> indices(size);
450 std::iota(indices.begin(), indices.end(), start_index);
455 std::shuffle(indices.begin(), indices.end(),
456 std::default_random_engine(seed));
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) {
487 float cos_a =
cos(a);
488 float sin_a =
sin(a);
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;
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;
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);
521void CenterPointDetection::GetBoxIndices(
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);
530 original_cloud_->points_label(point_idx) ==
static_cast<uint8_t
>(
540 for (
int box_idx = 0; box_idx < num_objects; box_idx++) {
544 if (px < box_rectangular[box_idx * 4 + 0] ||
545 px > box_rectangular[box_idx * 4 + 2]) {
548 if (py < box_rectangular[box_idx * 4 + 1] ||
549 py > box_rectangular[box_idx * 4 + 3]) {
561 if (pz < (z - h / 2 -
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];
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);
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);
591 original_cloud_->points_timestamp(point_idx);
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);
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) {
620 base::ObjectPool::Instance().BatchGet(num_objects, objects);
622 for (
int i = 0; i < num_objects; ++i) {
623 auto &
object = objects->at(i);
627 float x = detections.at(
629 float y = detections.at(
631 float z = detections.at(
633 float dx = detections.at(
635 float dy = detections.at(
637 float dz = detections.at(
639 float yaw = detections.at(
641 yaw = -yaw - M_PI / 2;
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;
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);
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;
669 object->lidar_supplement.on_use =
true;
670 object->lidar_supplement.is_background =
false;
673 object->lidar_supplement.raw_probs.push_back(std::vector<float>(
675 object->lidar_supplement.raw_classification_methods.push_back(
Name());
676 object->sub_type = GetObjectSubType(labels.at(i));
681 object->lidar_supplement.raw_probs.back()[
static_cast<int>(
object->type)] =
684 object->type_probs.assign(object->lidar_supplement.raw_probs.back().begin(),
685 object->lidar_supplement.raw_probs.back().end());
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);
692 num_objects, detections, box_corner, box_rectangular, objects);
693 AINFO <<
"[CenterPoint] we get " << num_objects <<
" objs";
749float CenterPointDetection::GetObjectScoreThreshold(
const int label) {
752 return small_mot_score_threshold_;
754 return big_mot_score_threshold_;
756 return cyc_score_threshold_;
758 return ped_score_threshold_;
760 return cone_score_threshold_;
764void CenterPointDetection::FilterScore(
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();
775 for (
int i = 0; i < scores->count(); ++i) {
776 if (score_ptr[i] > score_threshold) {
777 box3d_filtered->insert(
778 box3d_filtered->end(),
782 label_preds_filtered->insert(label_preds_filtered->end(),
783 static_cast<int64_t
>(label_ptr[i]));
785 scores_filtered->push_back(score_ptr[i]);
790void CenterPointDetection::FilterDiffScore(
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();
802 for (
int i = 0; i < scores->count(); ++i) {
803 threshold = GetObjectScoreThreshold(
static_cast<int64_t
>(label_ptr[i]));
805 box3d_filtered->insert(box3d_filtered->end(),
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]);
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);
822 if (object->lidar_supplement.cloud.size() >= num_points_thresholds) {
823 objects->at(valid_num) = object;
827 objects->resize(valid_num);
830void CenterPointDetection::FilterForegroundPoints(
831 std::vector<std::shared_ptr<Object>> *objects) {
833 mask.Set(original_cloud_->size(), 0);
834 mask.AddIndicesOfIndices(lidar_frame_ref_->
roi_indices,
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);
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) {
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;
855 if (nms_strategy_ || use_strategy) {
856 return type_i > type_j ? j : i;
861 auto special_nms_strategy = [&](
size_t keep_index,
867 objects->at(keep_index)->lidar_supplement.raw_probs.clear();
868 objects->at(keep_index)->type_probs.clear();
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());
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;
902 float cos_r =
cos(r);
903 float sin_r =
sin(r);
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;
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;
930 auto sort_vertex_in_convex_polygon_cpu = [&](
float* int_pts,
932 if (num_of_inter == 0) {
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];
941 center_x /= num_of_inter;
942 center_y /= num_of_inter;
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);
959 for (
int i = 0; i < num_of_inter; i++) {
960 if (vs[i - 1] > vs[i]) {
962 float tx = int_pts[2 * i];
963 float ty = int_pts[2 * i + 1];
965 while (j > 0 && vs[j - 1] > temp) {
967 int_pts[j * 2] = int_pts[j * 2 - 2];
968 int_pts[j * 2 + 1] = int_pts[j * 2 - 1];
973 int_pts[j * 2 + 1] = ty;
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];
983 float B0 = pts1[2 * ((i + 1) % 4)];
984 float B1 = pts1[2 * ((i + 1) % 4) + 1];
986 float C0 = pts2[2 * j];
987 float C1 = pts2[2 * j + 1];
989 float D0 = pts2[2 * ((j + 1) % 4)];
990 float D1 = pts2[2 * ((j + 1) % 4) + 1];
997 bool acd = DA1 * CA0 > CA1 * DA0;
998 bool bcd = (D1 - B1) * (C0 - B0) > (C1 - B1) * (D0 - B0);
1000 bool abc = CA1 * BA0 > BA1 * CA0;
1001 bool abd = DA1 * BA0 > BA1 * DA0;
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;
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;
1033 auto rotate_inter = [&](
const float *corners1,
const float *corners2) {
1034 float intersection_corners[16];
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];
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];
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)) {
1059 sort_vertex_in_convex_polygon_cpu(intersection_corners, num_of_inter);
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)));
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,
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());
1086 for (
size_t i = 0; i < objects->size(); i++) {
1087 auto &obj_i = objects->at(i);
1088 if (!obj_i || nms_visited[i]) {
1091 for (
size_t j = i + 1; j < objects->size(); j++) {
1092 auto &obj_j = objects->at(j);
1096 if (calculate_nms(obj_i, obj_j) <= diff_class_iou_) {
1099 if (
static_cast<int>(obj_i->type) ==
static_cast<int>(obj_j->type)) {
1102 nms_visited[j] =
true;
1103 nms_pairs[i].push_back(j);
1107 for (
size_t i = 0; i < objects->size(); i++) {
1108 if (nms_pairs[i].size() == 0) {
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;
1115 delete_array[keep_index] =
false;
1116 delete_array[filter_index] =
true;
1119 auto filter_type = objects->at(filter_index)->type;
1120 auto reserve_type = objects->at(keep_index)->type;
1145 ADEBUG <<
"Only Two NMS: reserve " << keep_index
1146 <<
" filter " << filter_index;
1148 if (nms_pairs[i].size() >= 2) {
1150 bool have_car =
false;
1154 for (
size_t k = 0; k < nms_pairs[i].size() && !have_car; k++) {
1155 auto type = objects->at(nms_pairs[i][k])->type;
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];
1172 delete_array[nms_pairs[i][k]] =
true;
1173 ADEBUG <<
"NMS filter_index: " << nms_pairs[i][k];
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];
1187 delete_array[nms_pairs[i][k]] =
true;
1188 ADEBUG <<
"NMS filter_index: " << nms_pairs[i][k];
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;
1202 objects->resize(valid_num);
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);
1218 type_count[index]++;
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);
1231 filter_flag.at(i) =
true;
1236 for (
size_t i = 0; i < objects->size(); i++) {
1237 if (filter_flag.at(i)) {
1240 objects->at(valid_size) = objects->at(i);
1243 AINFO <<
"Filter " << (objects->size() - valid_size)
1244 <<
" objects from " << objects->size() <<
" objects.";
1245 objects->resize(valid_size);
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);
#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,...
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)
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,...
uint32_t height
Height of point cloud
std::shared_ptr< PointDCloud > PointDCloudPtr
std::shared_ptr< PointFCloud > PointFCloudPtr
const std::map< ObjectSubType, ObjectType > kSubType2TypeMap
ObjectSubType mapping
std::shared_ptr< Object > ObjectPtr
std::vector< std::string > GetBlobNames(const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
void AddShape(std::map< std::string, std::vector< int > > *shape_map, const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
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
float get_3dbox_iou(base::ObjectPtr obj1, base::ObjectPtr obj2)
T abs(const T &x)
Get absolute value of x
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
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
std::string GetModelPath(const std::string &model_name)
Get the model path by model name, search from APOLLO_MODEL_PATH
optional float width_enlarge_value
optional float ped_score_threshold
optional float length_enlarge_value
optional float bottom_enlarge_height
optional float small_mot_score_threshold
optional float cyc_score_threshold
optional float top_enlarge_height
optional int32 num_output_box_feature
optional float big_mot_score_threshold
optional float cone_score_threshold
optional bool enable_downsample_beams
optional bool enable_fuse_frames
optional bool enable_roi_outside_removal
optional int32 max_num_points
optional int32 num_point_feature
optional bool enable_downsample_pointcloud
optional bool enable_shuffle_points
optional double fuse_time_interval
optional double ground_removal_height
optional bool enable_ground_removal
optional int32 downsample_beams_factor
optional double normalizing_factor
optional int32 num_fuse_frames
base::PointIndices roi_indices
Eigen::Affine3d lidar2world_pose
std::shared_ptr< base::AttributePointCloud< base::PointD > > world_cloud
base::PointIndices non_ground_indices
std::vector< std::shared_ptr< base::Object > > segmented_objects
base::PointIndices secondary_indices
std::shared_ptr< base::AttributePointCloud< base::PointF > > cloud
optional PluginParam plugins
optional int32 point2box_max_num
optional bool filter_by_points
optional bool nms_strategy
optional float diff_class_iou
optional bool diff_class_nms
optional common::PointCloudPostProcess postprocess
optional common::ModelInfo info
optional bool filter_ground_points
optional int32 min_points_threshold
optional bool filter_by_semantic_type
optional common::PointCloudPreProcess preprocess