Apollo  6.0
Open source self driving car software
ncut.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2019 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 #pragma once
17 
18 #include <cmath>
19 #include <cstdlib>
20 #include <iostream>
21 #include <map>
22 #include <memory>
23 #include <string>
24 #include <tuple>
25 #include <vector>
26 
27 #include <opencv2/opencv.hpp>
28 #include "Eigen/Core"
29 
32 #include "modules/perception/lidar/lib/detector/ncut_segmentation/proto/ncut_config.pb.h"
33 #include "modules/perception/lidar/lib/detector/ncut_segmentation/proto/ncut_param.pb.h"
34 
35 namespace apollo {
36 namespace perception {
37 namespace lidar {
38 
39 class NCut {
40  public:
41  NCut();
42  ~NCut();
43  bool Init(const NCutParam& param);
44 
45  int NumSegments() const { return static_cast<int>(_segment_pids.size()); }
46  std::string GetSegmentLabel(int sid) const { return _segment_labels[sid]; }
47 
48  void GetSegmentSize(int sid, float* length, float* width,
49  float* height) const {
50  NcutBoundingBox box = _segment_bbox[sid];
51  *length = std::get<1>(box) - std::get<0>(box);
52  *width = std::get<3>(box) - std::get<2>(box);
53  *height = std::get<5>(box) - std::get<4>(box);
54  }
55 
58  new base::PointFCloud(*_cloud_obstacles, _segment_pids[sid]));
59  return pc;
60  }
61 
63 
64  std::string GetPcRoughLabel(const base::PointFCloudPtr& cloud,
65  bool only_check_pedestrian);
66 
67  void GetSegmentRoughSize(const base::PointFCloudPtr& cloud, float* length,
68  float* width, float* height);
69 
70  private:
71  struct gridIndex {
72  int irow;
73  int jcol;
74  };
75 
76  // x_min, x_max, y_min, y_max, z_min, z_max;
77  typedef std::tuple<float, float, float, float, float, float> NcutBoundingBox;
78  base::PointFCloudPtr _cloud_obstacles;
79  // super pixels related
80  float _grid_radius;
81  float _super_pixel_cell_size;
82  std::unique_ptr<LRClassifier> _classifier;
83  // felzenszwalb
84  double _felzenszwalb_sigma;
85  double _felzenszwalb_k;
86  int _felzenszwalb_min_size;
87  // graph cut related
88  double _sigma_feature;
89  double _sigma_space;
90  double _connect_radius;
91  int _num_cuts;
92  float _ncuts_stop_threshold;
93  double _ncuts_enable_classifier_threshold;
94  // component (cluster) information
95  std::vector<std::vector<int>> _cluster_points;
96  // x_min, x_max, y_min, y_max, z_min, z_max;
97  std::vector<NcutBoundingBox> _cluster_bounding_box;
98  std::vector<std::string> _cluster_labels;
99  // skeleton related
100  float _skeleton_cell_size; // skeleton sample size
101  int _patch_size;
102  cv::Mat _cv_feature_map;
103  FloodFill _ff_feature_grid;
104  std::vector<Eigen::MatrixXf> _cluster_skeleton_points;
105  std::vector<Eigen::MatrixXf> _cluster_skeleton_features;
106  // merge overlap
107  double _overlap_factor;
108  // final segments, each vector contains
109  std::vector<std::vector<int>> _segment_pids;
110  std::vector<std::string> _segment_labels;
111  std::vector<NcutBoundingBox> _segment_bbox;
112  std::vector<std::vector<int>> _outlier_pids;
113 
114  void SampleByGrid(const std::vector<int>& point_gids,
115  Eigen::MatrixXf* skeleton_coords,
116  Eigen::MatrixXf* skeleton_feature);
117 
118  void PrecomputeAllSkeletonAndBbox();
119 
120  bool Configure(const NCutParam& ncut_param_);
121 
122  void SuperPixelsFloodFill(base::PointFCloudConstPtr cloud, float radius,
123  float cell_size,
124  std::vector<std::vector<int>>* super_pixels);
125 
126  // super pixels
127  void BuildAverageHeightMap(base::PointFCloudConstPtr cloud,
128  const FloodFill& ff_map, cv::Mat* cv_height_map,
129  std::vector<gridIndex>* point_pixel_indices);
130 
131  // skeleton
132  void GetPatchFeature(const Eigen::MatrixXf& points,
133  Eigen::MatrixXf* features);
134 
135  // bounding box
136  NcutBoundingBox ComputeClusterBoundingBox(const std::vector<int>& point_gids);
137 
138  std::string GetPcLabel(const base::PointFCloudPtr& cloud);
139 
140  void NormalizedCut(float ncuts_threshold, bool use_classifier,
141  std::vector<std::vector<int>>* segment_clusters,
142  std::vector<std::string>* segment_labels);
143 
144  void ComputeSkeletonWeights(Eigen::MatrixXf* weights);
145 
146  float GetMinNcuts(const Eigen::MatrixXf& in_weights,
147  const std::vector<int>* in_clusters, std::vector<int>* seg1,
148  std::vector<int>* seg2);
149 
150  void LaplacianDecomposition(const Eigen::MatrixXf& weights,
151  Eigen::MatrixXf* eigenvectors);
152 
153  bool ComputeSquaredSkeletonDistance(const Eigen::MatrixXf& in1_points,
154  const Eigen::MatrixXf& in1_features,
155  const Eigen::MatrixXf& in2_points,
156  const Eigen::MatrixXf& in2_features,
157  float* dist_point, float* dist_feature);
158 
159  bool IsMovableObstacle(const std::vector<int>& cluster_ids,
160  std::string* label);
161 
162  inline bool IsPotentialPedestrianSize(float length, float width) {
163  return ((length > 0.5 && length < 1.5) && (width > 0.3 && width < 1));
164  }
165 
166  inline bool IsPotentialBicyclistSize(float length, float width) {
167  return ((length > 1 && length < 2.5) && (width > 0.3 && width < 1.5));
168  }
169 
170  inline bool IsPotentialCarSize(float length, float width) {
171  // return ( (length > 1.0 && length < 20.0) && (width > 1.0 && width < 3.5)
172  // );
173  return ((length > 1.0 && length < 8.0) && (width > 1.0 && width < 3.5));
174  }
175 
176  int GetComponentBoundingBox(const std::vector<int>& cluster_ids,
177  NcutBoundingBox* box);
178 
179  inline float GetBboxLength(const NcutBoundingBox& box) {
180  return (std::get<1>(box) - std::get<0>(box));
181  }
182 
183  inline float GetBboxWidth(const NcutBoundingBox& box) {
184  return (std::get<3>(box) - std::get<2>(box));
185  }
186 
187  inline float GetBboxHeight(const NcutBoundingBox& box) {
188  return (std::get<5>(box) - std::get<4>(box));
189  }
190 
191  std::string GetClustersLabel(const std::vector<int>& cluster_ids);
192 
193  void GetClustersPids(const std::vector<int>& cids, std::vector<int>* pids);
194 };
195 
196 } // namespace lidar
197 } // namespace perception
198 } // namespace apollo
int NumSegments() const
Definition: ncut.h:45
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
std::string GetSegmentLabel(int sid) const
Definition: ncut.h:46
std::shared_ptr< const PointFCloud > PointFCloudConstPtr
Definition: point_cloud.h:483
Definition: ncut.h:39
void Segment(base::PointFCloudConstPtr cloud)
void GetSegmentRoughSize(const base::PointFCloudPtr &cloud, float *length, float *width, float *height)
std::string GetPcRoughLabel(const base::PointFCloudPtr &cloud, bool only_check_pedestrian)
std::shared_ptr< PointFCloud > PointFCloudPtr
Definition: point_cloud.h:482
bool Init(const NCutParam &param)
base::PointFCloudPtr GetSegmentPointCloud(int sid) const
Definition: ncut.h:56
void GetSegmentSize(int sid, float *length, float *width, float *height) const
Definition: ncut.h:48
Definition: flood_fill.h:28