37using base::AttributePointCloud;
43 std::string config_file =
50 width_ = feature_param.
width();
51 height_ = feature_param.
height();
55 const auto& model_info = model_param_.
info();
56 std::string model_path =
GetModelPath(model_info.name());
57 std::string proto_file =
58 GetModelFile(model_path, model_info.proto_file().file());
59 std::string weight_file =
60 GetModelFile(model_path, model_info.weight_file().file());
63 std::vector<std::string> input_names =
65 std::vector<std::string> output_names =
69 model_param_.
info().framework(), proto_file, weight_file, output_names,
71 CHECK_NOTNULL(inference_.get());
73 gpu_id_ = model_param_.
preprocess().has_gpu_id()
76 BASE_GPU_CHECK(cudaSetDevice(gpu_id_));
77 inference_->set_gpu_id(gpu_id_);
79 std::map<std::string, std::vector<int>> input_shapes;
81 auto& input_shape = input_shapes[input_names.at(0)];
88 ACHECK(inference_->Init(input_shapes)) <<
"Failed to init inference.";
91 instance_pt_blob_ = inference_->get_blob(output_names.at(0));
92 CHECK_NOTNULL(instance_pt_blob_.get());
93 category_pt_blob_ = inference_->get_blob(output_names.at(1));
94 CHECK_NOTNULL(category_pt_blob_.get());
95 confidence_pt_blob_ = inference_->get_blob(output_names.at(2));
96 CHECK_NOTNULL(confidence_pt_blob_.get());
97 height_pt_blob_ = inference_->get_blob(output_names.at(3));
98 CHECK_NOTNULL(height_pt_blob_.get());
99 feature_blob_ = inference_->get_blob(input_names.at(0));
100 CHECK_NOTNULL(feature_blob_.get());
102 classify_pt_blob_ = inference_->get_blob(output_names.at(5));
103 CHECK_NOTNULL(classify_pt_blob_.get());
106 heading_pt_blob_ = inference_->get_blob(output_names.at(4));
107 CHECK_NOTNULL(heading_pt_blob_.get());
112 ACHECK(feature_generator_->Init(feature_param, feature_blob_.get()))
113 <<
"Failed to init feature generator.";
115 point2grid_.reserve(kDefaultPointCloudSize);
118 ACHECK(InitClusterAndBackgroundSegmentation());
123bool CNNSegmentation::InitClusterAndBackgroundSegmentation() {
132 spp_data.category_pt_blob = category_pt_blob_.get();
133 spp_data.confidence_pt_blob = confidence_pt_blob_.get();
139 if (height_pt_blob_ !=
nullptr) {
140 spp_data.height_pt_blob = height_pt_blob_.get();
143 spp_data.classify_pt_blob = classify_pt_blob_.get();
146 spp_data.heading_pt_blob = heading_pt_blob_.get();
148 spp_data.MakeReference(width_, height_, range_);
151 spp_engine_.
Init(width_, height_, range_, params, sensor_name_);
153 roi_cloud_ = base::PointFCloudPool::Instance().Get();
154 roi_world_cloud_ = base::PointDCloudPool::Instance().Get();
159void CNNSegmentation::MapPointToGrid(
160 const std::shared_ptr<AttributePointCloud<PointF>>& pc_ptr) {
161 float inv_res_x = 0.5f *
static_cast<float>(width_) / range_;
163 point2grid_.assign(pc_ptr->size(), -1);
166 for (
size_t i = 0; i < pc_ptr->size(); ++i) {
167 const auto& pt = pc_ptr->at(i);
168 if (pt.z <= min_height_ || pt.z >= max_height_) {
176 GroupPc2Pixel(pt.x, pt.y, inv_res_x, range_, &pos_x, &pos_y);
177 if (pos_y < 0 || pos_y >= height_ || pos_x < 0 || pos_x >= width_) {
180 point2grid_[i] = pos_y * width_ + pos_x;
187 if (frame ==
nullptr) {
188 AERROR <<
"Input null frame ptr.";
191 if (frame->
cloud ==
nullptr) {
192 AERROR <<
"Input null frame cloud.";
196 AERROR <<
"Input null frame world cloud.";
199 if (frame->
cloud->size() == 0) {
200 AERROR <<
"Input none points.";
204 AERROR <<
"Cloud size and world cloud size not consistent.";
208 original_cloud_ = frame->
cloud;
210 lidar_frame_ref_ = frame;
213 roi_cloud_->CopyPointCloud(*lidar_frame_ref_->
cloud,
215 roi_world_cloud_->CopyPointCloud(*lidar_frame_ref_->
world_cloud,
224 MapPointToGrid(original_cloud_);
225 mapping_time_ = timer.
toc(
true);
227 if (cudaSetDevice(gpu_id_) != cudaSuccess) {
228 AERROR <<
"Failed to set device to " << gpu_id_;
233 feature_generator_->Generate(original_cloud_, point2grid_);
234 feature_time_ = timer.
toc(
true);
238 infer_time_ = timer.
toc(
true);
243 AINFO <<
"CNNSEG: mapping: " << mapping_time_ <<
"\t"
244 <<
" feature: " << feature_time_ <<
"\t"
245 <<
" infer: " << infer_time_ <<
"\t"
246 <<
" fg-seg: " << fg_seg_time_ <<
"\t"
247 <<
" collect: " << collect_time_;
251void CNNSegmentation::GetObjectsFromSppEngine(
252 std::vector<std::shared_ptr<Object>>* objects) {
256 size_t num_foreground =
258 fg_seg_time_ = timer.
toc(
true);
263 AINFO <<
"Use origin cloud and copy height";
267 original_cloud_->mutable_points_height()->at(roi_id) =
268 roi_cloud_->points_height(i);
269 if (roi_cloud_->mutable_points_label()->at(i) ==
271 original_cloud_->mutable_points_label()->at(roi_id) =
272 roi_cloud_->points_label().at(i);
276 memcpy(&original_world_cloud_->mutable_points_height()->at(0),
277 &original_cloud_->points_height().at(0),
278 sizeof(
float) * original_cloud_->size());
279 memcpy(&original_world_cloud_->mutable_points_label()->at(0),
280 &original_cloud_->points_label().at(0),
281 sizeof(uint8_t) * original_cloud_->size());
286 if (num_foreground == 0) {
287 ADEBUG <<
"No foreground segmentation output";
291 const auto& clusters = spp_engine_.
clusters();
293 base::ObjectPool::Instance().BatchGet(clusters.size(), objects);
300 mask.Set(original_cloud_->size(), 0);
301 mask.AddIndicesOfIndices(lidar_frame_ref_->
roi_indices,
305 for (
int i = 0; i < static_cast<int>(clusters.size()); ++i) {
306 if (clusters[i]->points.size() <= model_param_.
min_pts_num() &&
307 clusters[i]->pixels.size() < model_param_.
min_pts_num()) {
310 auto& cluster = clusters[i];
311 auto&
object = objects->at(valid);
312 object->lidar_supplement.num_points_in_roi = cluster->points_in_roi;
313 object->lidar_supplement.on_use =
true;
314 object->lidar_supplement.is_background =
false;
318 object->lidar_supplement.cloud.CopyPointCloud(*original_cloud_,
320 object->lidar_supplement.cloud_world.CopyPointCloud(*original_world_cloud_,
325 base::PointIndices ind;
326 std::vector<int> indices(cluster->point_ids.begin(),
327 cluster->point_ids.end());
328 ind.indices = std::move(indices);
329 mask.RemoveIndices(ind);
336 object->confidence = cluster->confidence;
337 object->id =
static_cast<int>(valid);
339 object->lidar_supplement.raw_probs.push_back(std::vector<float>(
341 object->lidar_supplement.raw_classification_methods.push_back(
Name());
342 object->lidar_supplement.raw_probs
345 object->lidar_supplement.raw_probs
348 object->lidar_supplement.raw_probs
351 object->lidar_supplement.raw_probs
356 object->type_probs.assign(
357 object->lidar_supplement.raw_probs.back().begin(),
358 object->lidar_supplement.raw_probs.back().end());
360 std::distance(object->type_probs.begin(),
361 std::max_element(object->type_probs.begin(),
362 object->type_probs.end())));
371 static const float quater_pi =
static_cast<float>(M_PI) * 0.25f;
372 object->theta = cluster->yaw - quater_pi;
373 object->direction[0] = cosf(cluster->yaw - quater_pi);
374 object->direction[1] = sinf(cluster->yaw - quater_pi);
375 object->direction[2] = 0;
376 object->lidar_supplement.is_orientation_ready =
true;
380 objects->resize(valid);
387 collect_time_ = timer.
toc(
true);
#define PERCEPTION_REGISTER_LIDARDETECTOR(name)
std::string Name() const override
Name of CNNSegmentation module
bool Detect(const LidarDetectorOptions &options, LidarFrame *frame) override
Detect foreground objects using CNNSegmentation
bool Init(const LidarDetectorInitOptions &options=LidarDetectorInitOptions()) override
Init of CNNSegmentation object
void Init(size_t width, size_t height, float range, const SppParams ¶m=SppParams(), const std::string &sensor_name="velodyne64")
size_t RemoveGroundPointsInForegroundCluster(const base::PointFCloudConstPtr full_point_cloud, const base::PointIndices &roi_indices, const base::PointIndices &roi_non_ground_indices)
const SppClusterList & clusters() const
size_t ProcessForegroundSegmentation(const base::PointFCloudConstPtr point_cloud)
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,...
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)
void GroupPc2Pixel(float pc_x, float pc_y, float scale, float range, int *x, int *y)
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
std::vector< int > indices
base::PointIndices roi_indices
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
base::Blob< float > * instance_pt_blob
optional bool use_intensity_feature
optional bool use_constant_feature
optional float max_height
optional float min_height
optional float point_cloud_range
optional FeatureParam feature_param
optional bool fill_recall_with_segmentor
optional float confidence_range
optional float confidence_thresh
optional uint32 min_pts_num
optional common::PointCloudPreProcess preprocess
optional bool do_classification
optional common::ModelInfo info
optional float height_thresh
optional bool remove_ground_points
optional SppEngineConfig engine_config
optional float objectness_thresh
optional float height_gap