39 graph_segmentor_.
Init(threshold_);
49 grid_width_ =
static_cast<int>((bg_config_.
ymax() - bg_config_.
ymin()) * 1.0f / resolution_);
50 grid_height_ =
static_cast<int>((bg_config_.
xmax() - bg_config_.
xmin()) * 1.0f / resolution_);
55 AINFO <<
"graph segmentation config: " << bg_config_.DebugString();
65 AERROR <<
"bg_map_ Reset error.";
70 AERROR <<
"bg_map_ Update error.";
75 AERROR <<
"Graph Segment error.";
80 AERROR <<
"Split object error.";
85 AERROR <<
"SetBgObjectDefaulVal error.";
91 AINFO <<
"Graph segment, background objects number: " << bg_objects_.size();
96 std::vector<algorithm::Edge> edge_set;
99 for (
int x = 0; x < grid_height_; ++x) {
100 for (
int y = 0; y < grid_width_; ++y) {
101 int grid_idx = x * grid_width_ + y;
102 if (!bg_map_.
bg_nodes_.at(grid_idx).is_valid) {
110 for (
int ny = y; ny < grid_width_ && ny <= y + search_radius_; ++ny) {
111 int grid_ny = x * grid_width_ + ny;
112 if (bg_map_.
bg_nodes_.at(grid_ny).is_valid) {
116 edge_set.push_back(
edge);
120 for (
int nx = x + 1; nx < grid_height_ && nx <= x + search_radius_; ++nx) {
121 for (
int ny = y; ny < grid_width_ && ny < y + search_radius_; ++ny) {
122 int grid_nxny = nx * grid_width_ + ny;
123 if (bg_map_.
bg_nodes_.at(grid_nxny).is_valid) {
127 edge_set.push_back(
edge);
134 if (edge_set.size() == 0) {
135 AINFO <<
"Graph segmentation, edges are empty.";
140 graph_segmentor_.
SegmentGraph(bg_map_.
id(), edge_set.size(), edge_set.data());
142 std::vector<size_t> mapping(bg_map_.
id(), 0);
143 std::map<size_t, size_t> label_map;
145 for (
int i = 0; i < bg_map_.
id(); ++i) {
146 mapping[i] = universe->
Find(i);
147 auto iter = label_map.find(mapping[i]);
148 if (iter == label_map.end()) {
150 label_map.emplace(mapping[i], label);
154 mapping[i] = iter->second;
159 auto original_cloud = frame->
cloud;
162 clusters_.
resize(label_map.size());
163 for (
size_t i = 0; i < bg_map_.
point_mask_.size(); ++i) {
168 size_t cluster_label = mapping.at(bg_map_.
bg_nodes_.at(index).id);
169 clusters_.
AddPointSample(cluster_label, original_cloud->at(i), original_cloud->points_height(i), i);
173 for (
int i = 0; i <= clusters_.
size() - 1; i++) {
174 clusters_[i]->clear();
182 float x_diff =
static_cast<float>(x1 - x2) * resolution_;
183 float y_diff =
static_cast<float>(y1 - y2) * resolution_;
188 int max_label_1 =
static_cast<int>(std::distance(
190 int max_label_2 =
static_cast<int>(std::distance(
193 int max_motion_label_1 =
static_cast<int>(std::distance(
195 int max_motion_label_2 =
static_cast<int>(std::distance(
198 float total_cost = std::sqrt(
199 x_diff * x_diff + y_diff * y_diff + mean_height_diff * mean_height_diff + max_height_diff * max_height_diff
200 + mean_intensity * mean_intensity);
205 if (max_label_1 == max_label_2) {
215 if (max_motion_label_1 == max_motion_label_2) {
227 auto original_cloud_ = frame->
cloud;
232 for (
size_t i = 0; i < clusters_.
size(); ++i) {
233 auto cluster = clusters_[i];
234 if (cluster->point_ids.size() < min_pt_number_) {
239 for (
auto idx : cluster->point_ids) {
240 object.lidar_supplement.point_ids.push_back(
static_cast<int>(idx));
242 object.lidar_supplement.num_points_in_roi = cluster->point_ids.size();
243 object.lidar_supplement.cloud.CopyPointCloud(*original_cloud_, cluster->point_ids);
244 object.lidar_supplement.cloud_world.CopyPointCloud(*original_world_cloud_, cluster->point_ids);
248 bg_objects_.push_back(std::move(obj));
255 std::vector<std::shared_ptr<base::Object>> split_objects;
257 int before_split_num = bg_objects_.size();
259 int valid_number = 0;
260 for (
size_t i = 0; i < bg_objects_.size(); i++) {
261 std::shared_ptr<base::Object> obj = bg_objects_.at(i);
263 std::vector<base::ObjectPtr> this_split;
266 split_objects.insert(split_objects.end(), this_split.begin(), this_split.end());
269 bg_objects_.at(valid_number) = obj;
272 int split_number = bg_objects_.size() - valid_number;
273 bg_objects_.resize(valid_number);
276 bg_objects_.insert(bg_objects_.end(), split_objects.begin(), split_objects.end());
277 int after_split_num = bg_objects_.size();
279 AINFO <<
"Before split object number: " << before_split_num <<
", split number: " << split_number
280 <<
", after split number: " << after_split_num;
287 if (object->size(0) > object->size(1)) {
288 length =
object->size(0);
289 width =
object->size(1);
291 length =
object->size(1);
292 width =
object->size(0);
294 if ((width > kEpsilon) && (length / (width + kEpsilon) > bg_config_.
split_aspect_ratio())) {
302 for (
size_t i = 0; i < bg_objects_.size(); i++) {
303 std::shared_ptr<base::Object>
object = bg_objects_.at(i);
304 object->id = start_index++;
305 object->lidar_supplement.is_in_roi =
true;
306 object->lidar_supplement.is_background =
true;
307 object->lidar_supplement.is_clustered =
true;
310 object->lidar_supplement.raw_probs.push_back(
312 object->lidar_supplement.raw_probs.back()[
static_cast<int>(
object->type)] = 1.0f;
313 object->lidar_supplement.raw_classification_methods.push_back(
Name());
315 object->type_probs.assign(
316 object->lidar_supplement.raw_probs.back().begin(),
object->lidar_supplement.raw_probs.back().end());
318 object->lidar_supplement.detections.resize(7);
319 for (
size_t jj = 0; jj < 7; jj++) {
320 object->lidar_supplement.detections[jj] = 0.0;
#define PERCEPTION_REGISTER_LIDARDETECTOR(name)
void Init(const float initial_threshold)
Universe * mutable_universe()
void SegmentGraph(const int num_vertices, const int num_edges, Edge *edges, bool need_sort=true)
bool UpdateMap(LidarFrame *frame)
Update map, update mask and node
std::vector< size_t > point_idx_
int id()
Get valid node number
bool Init(int width, int height, float resolution, float height_threshold)
Init background map
bool Reset(size_t point_number)
Reset all data
std::vector< BgNode > bg_nodes_
std::vector< bool > point_mask_
bool SetBgObjectDefaulVal(LidarFrame *frame)
Set the Bacground Object Defaul Value
float NodeDistance(BgNode n1, int x1, int y1, BgNode n2, int x2, int y2)
Compute node distance
bool Segment(LidarFrame *frame)
Graph segment
bool NeedSplit(std::shared_ptr< base::Object > object)
judge if the object need to split
bool Detect(const LidarDetectorOptions &options, LidarFrame *frame) override
Segment pointcloud into objects
bool Split(LidarFrame *frame)
background filter
void GetObjectsFromClusters(LidarFrame *frame)
Get the Objects From Clusters
std::string Name() const override
Get class name
bool Init(const LidarDetectorInitOptions &options=LidarDetectorInitOptions()) override
Init graph segmentation
void AddPointSample(size_t cluster_id, const base::PointF &point, float height, uint32_t point_id)
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,...
void SplitObject(const base::ObjectPtr &obj, std::vector< base::ObjectPtr > *split_objs, float split_distance)
split object
bool BgObjectBuilder(std::vector< base::ObjectPtr > *objects, Eigen::Affine3d &lidar2novatel_pose)
background objects builder
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
std::vector< int > pc_semantic_types
std::vector< int > pc_motion_types
optional float height_threshold
optional uint32 search_radius
optional float semantic_cost
optional float diff_semantic_coefficient
optional float resolution
optional float split_aspect_ratio
optional float split_distance
optional float same_semantic_coefficient
optional float same_motion_coefficient
optional uint32 min_pt_number
std::shared_ptr< base::AttributePointCloud< base::PointD > > world_cloud
std::vector< std::shared_ptr< base::Object > > segmented_objects
Eigen::Affine3d lidar2novatel_extrinsics
std::shared_ptr< base::AttributePointCloud< base::PointF > > cloud