Apollo 11.0
自动驾驶开放平台
cpdet.h
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2024 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
17#pragma once
18
19#include <deque>
20#include <map>
21#include <memory>
22#include <string>
23#include <vector>
24
35
36#include "modules/perception/lidar_cpdet_detection/detector/cpdet/proto/model_param.pb.h"
37
38namespace apollo {
39namespace perception {
40namespace lidar {
41
42static const int kBoxBlockSize = 7;
43
45 float x = 0.0;
46 float y = 0.0;
47 float z = 0.0;
48 float l = 0.0;
49 float w = 0.0;
50 float h = 0.0;
51 float yaw = 0.0;
53 float confidence = 0.0;
54 std::vector<int> point_ids;
55 inline void AddPointId(int point_id) {
56 point_ids.push_back(point_id);
57 }
58 inline void clear() {
59 x = 0.0;
60 y = 0.0;
61 z = 0.0;
62 l = 0.0;
63 w = 0.0;
64 h = 0.0;
65 yaw = 0.0;
67 confidence = 0.0;
68 point_ids.clear();
69 }
70};
71
73 public:
75 virtual ~CPDetection() = default;
76
77 bool Init(const CPDetectorInitOptions &options =
78 CPDetectorInitOptions()) override;
79
80 bool Detect(const CPDetectorOptions &options,
81 LidarFrame *frame) override;
82
83 std::string Name() const { return "CPDetection"; }
84
86 if (use_gpu_generate_feature_) {
87 GeneratePfnFeatureGPU();
88 } else {
89 GeneratePfnFeatureCPU();
90 }
91 }
92
94 const base::Blob<float>* pillar_feature_blob) {
95 if (use_gpu_generate_feature_) {
96 GenerateBackboneFeatureGPU(pillar_feature_blob);
97 } else {
98 GenerateBackboneFeatureCPU(pillar_feature_blob);
99 }
100 }
101
103 // all-gpu
104 if (!use_cpu_get_objects_ && !use_cpu_assign_points_) {
105 GetObjectsAndAssignPointsGPU();
106 return;
107 }
108 if (use_cpu_get_objects_) {
109 GetObjectsCPU();
110 } else {
111 GetObjectsGPU();
112 }
113 if (use_cpu_assign_points_) {
114 AssignPointsCPU();
115 } else {
116 AERROR << "Error: Not Support AssignPoints is False when GetObjects is not False";
117 return;
118 }
119 }
120 private:
121 void LoadParams(const cpdet::CPDetConfig &cpdet_config);
122
123 bool InitModel(const cpdet::CPDetModelParam &model_param);
124
125 void PointCloudPreprocess();
126
127 base::ObjectSubType GetObjectSubType(const int label);
128
129 void GenerateObjects(LidarFrame *frame);
130
131 void SetPointsInROI(std::vector<base::ObjectPtr> *objects);
132
133 void RemoveForePoints(std::vector<base::ObjectPtr> *objects);
134
135 void MapPointsToGridCpu(int* point2grid_data);
136
137 void GeneratePfnFeatureGPU();
138 void GeneratePfnFeatureCPU();
139 void GenerateBackboneFeatureCPU(const base::Blob<float>* pillar_feature_blob);
140 void GenerateBackboneFeatureGPU(const base::Blob<float>* pillar_feature_blob);
141
142 void GetObjectsAndAssignPointsGPU();
143 void GetObjectsGPU();
144 void GetObjectsCPU();
145 void AssignPointsCPU();
146
147 void FilterObjectsbyClassNMS(
148 std::vector<std::shared_ptr<base::Object>> *objects);
149
150 void FilterObjectsbySemanticType(
151 std::vector<std::shared_ptr<base::Object>> *objects);
152
153 void AssignPoints2Boxid(const std::vector<int>& kept_indices);
154
155 void SimpleAssignPoints2Boxid(const std::vector<int>& kept_indices);
156
157 void ApplyRotateNms(const bool *rotate_overlapped,
158 const int valid_box_num, const int* all_sorted_indices,
159 std::vector<int> *box_reverve_flag, bool skip_suppressed);
160
161 std::vector<ResultsOutput> ApplyNMSCPU(std::vector<ResultsOutput>& boxes);
162
163 int ApplyNmsGPU(const int box_num_pre, const int all_res_num, std::vector<int>* kept_indices);
164
165 void DecodeValidObjects(std::vector<int>* kept_indices);
166
167 float CalculateUnionArea(const float *corners1, const float *corners2);
168
169 template <typename T>
170 void HOST_SAVE(const T *array, int row, int col,
171 std::string filename, bool is_canvus) {
172 std::ofstream out_file(filename, std::ios::out);
173 if (out_file.is_open()) {
174 for (int i = 0; i < row; ++i) {
175 for (int j = 0; j < col; ++j) {
176 if (is_canvus) {
177 if (array[i * col + j] == 0) {
178 continue;
179 }
180 out_file << array[i * col + j] << ", i: " << i << ", j: " << j << "\n";
181 } else{
182 out_file << array[i * col + j] << " ";
183 }
184 }
185 out_file << "\n";
186 }
187 }
188 out_file.close();
189 };
190
191 template <typename T>
192 void DEVICE_SAVE(const T *array, int row, int col,
193 std::string filename, bool is_canvus = false) {
194 T *temp_ = new T[row * col];
195 cudaMemcpy(temp_, array,
196 row * col * sizeof(T), cudaMemcpyDeviceToHost);
197 HOST_SAVE<T>(temp_, row, col, filename, is_canvus);
198 delete[] temp_;
199 };
200
201 private:
202 // cpdet model param
203 cpdet::CPDetConfig cpdet_config_;
204
205 std::shared_ptr<inference::Inference> pfn_inference_;
206 std::shared_ptr<inference::Inference> backbone_inference_;
207
208 // pfn model blobs
209 // input: (points_size, 9)
210 std::shared_ptr<base::Blob<float>> voxels_blob_;
211 // output: (points_size, 48/64)
212 std::shared_ptr<base::Blob<float>> pfn_pillar_feature_blob_;
213 // backbone model blobs
214 // input: (1, 64, map_x, map_y)
215 std::shared_ptr<base::Blob<float>> canvas_feature_blob_;
216 // output-box: (1, 6 * task_number, head_x, head_y)
217 // output-cls: (1, 4, head_x, head_y)
218 // output-dir: (1, 2 * task_number, head_x, head_y)
219 std::shared_ptr<base::Blob<float>> output_box_blob_;
220 std::shared_ptr<base::Blob<float>> output_cls_blob_;
221 std::shared_ptr<base::Blob<float>> output_dir_blob_;
222
223 // feature generate
224 std::shared_ptr<base::Blob<int>> point2grid_blob_ = nullptr;
225 std::shared_ptr<base::Blob<int>> grid2pointnum_blob_ = nullptr;
226
227 // get objects
228 std::shared_ptr<base::Blob<float>> all_res_box_blob_ = nullptr;
229 std::shared_ptr<base::Blob<float>> all_res_conf_blob_ = nullptr;
230 std::shared_ptr<base::Blob<int>> all_res_cls_blob_ = nullptr;
231 std::shared_ptr<base::Blob<float>> res_box_blob_ = nullptr;
232 std::shared_ptr<base::Blob<float>> res_conf_blob_ = nullptr;
233 std::shared_ptr<base::Blob<int>> res_cls_blob_ = nullptr;
234 std::shared_ptr<base::Blob<int>> res_box_num_blob_ = nullptr;
235 std::shared_ptr<base::Blob<float>> score_class_map_blob_ = nullptr;
236
237 // NMS
238 std::shared_ptr<base::Blob<int>> res_sorted_indices_blob_ = nullptr;
239 std::shared_ptr<base::Blob<float>> box_for_nms_blob_ = nullptr;
240 std::shared_ptr<base::Blob<float>> box_corner_blob_ = nullptr;
241 std::shared_ptr<base::Blob<float>> remain_conf_blob_ = nullptr;
242 std::shared_ptr<base::Blob<bool>> rotate_overlapped_blob_ = nullptr;
243 std::shared_ptr<base::Blob<int>> kept_indices_blob_ = nullptr;
244 // assign point
245 std::shared_ptr<base::Blob<float>> box_corners_blob_ = nullptr;
246 std::shared_ptr<base::Blob<float>> box_rects_blob_ = nullptr;
247 std::shared_ptr<base::Blob<int>> valid_point_num_blob_ = nullptr;
248 std::shared_ptr<base::Blob<int>> valid_point_indices_blob_ = nullptr;
249 std::shared_ptr<base::Blob<int>> valid_point2boxid_blob_ = nullptr;
250
251 // reference pointer of lidar frame
252 LidarFrame *lidar_frame_ref_ = nullptr;
253 std::shared_ptr<
254 base::AttributePointCloud<base::PointF>> original_cloud_;
255 std::shared_ptr<
256 base::AttributePointCloud<base::PointD>> original_world_cloud_;
257 base::PointFCloudPtr cur_cloud_ptr_;
258 base::PointF* pc_gpu_ = nullptr;
259 int model_cloud_size_ = 0;
260 int total_cloud_size_ = 0;
261 int max_point_number_ = 200000;
262 int max_valid_point_size_ = 0;
263
264 // point cloud range
265 float x_min_range_ = -51.2;
266 float x_max_range_ = 51.2;
267 float y_min_range_ = -51.2;
268 float y_max_range_ = 51.2;
269 float z_min_range_ = -3.5;
270 float z_max_range_ = 3.5;
271 float voxel_x_size_ = 0.2;
272 float voxel_y_size_ = 0.2;
273 float voxel_z_size_ = 7;
274 float x_offset_ = 0.0;
275 float y_offset_ = 0.0;
276 float z_offset_ = 0.0;
277 int grid_x_size_ = 512;
278 int grid_y_size_ = 512;
279 int grid_z_size_ = 1;
280 int map_size_ = 512 * 512;
281 float point_dim_ = 4;
282 bool enable_rotate_45degree_ = true;
283 bool use_input_norm_ = true;
284
285 // cnnseg feature
286 bool use_cnnseg_features_ = true;
287 int cnnseg_feature_dim_ = 16;
288 float height_bin_min_height_ = -3.5;
289 float height_bin_max_height_ = 3.5;
290 float height_bin_voxel_size_ = 0.5;
291 int height_bin_dim_ = 10;
292
293 // cnnseg feature data
294 float* max_height_data_ = nullptr;
295 float* mean_height_data_ = nullptr;
296 float* count_data_ = nullptr;
297 float* top_intensity_data_ = nullptr;
298 float* mean_intensity_data_ = nullptr;
299 float* nonempty_data_ = nullptr;
300 float* height_bin_data_ = nullptr;
301
302 // feature generate
303 bool use_gpu_generate_feature_ = true;
304 int max_voxel_num_ = 40000;
305 int max_points_in_voxel_ = 20;
306 int voxel_feature_dim_ = 9;
307 int pillar_feature_dim_ = 48;
308 int num_classes_ = 4;
309
310 // pointcloud preprocess
311 bool enable_downsample_ = false;
312
313 // post process
314 int downsample_size_ = 4;
315 int num_tasks_ = 1;
316 int head_x_size_ = 212;
317 int head_y_size_ = 212;
318 int head_map_size_ = 44944;
319 int nms_pre_max_size_ = 500;
320 int nms_post_max_size_ = 300;
321 int score_thresh_ = 0.1;
322 int nms_overlap_thresh_ = 0.01;
323 int min_pts_num_fg_ = 5;
324 float max_candidate_num_ = 1;
325 float top_enlarge_value_ = 0.0;
326 float bottom_enlarge_value_ = 0.0;
327 float width_enlarge_value_ = 0.0;
328 float length_enlarge_value_ = 0.0;
329 bool use_cpu_get_objects_ = false;
330 bool use_cpu_assign_points_ = false;
331
332 // model objects filter strategy
333 bool remove_semantic_ground_ = false;
334 bool remove_raw_ground_ = false;
335 bool point_unique_ = false;
336 bool inter_class_nms_ = false;
337 bool filter_by_semantic_type_ = false;
338 std::map<int, std::pair<float, float>> fore_semantic_filter_map_;
339 float class_nms_iou_thres_ = 0.25;
340 bool nms_strategy_ = false;
341
342 std::vector<int> num_classes_in_task_;
343 std::vector<float> score_thresh_map_;
344 std::map<int, std::pair<std::string, float>> score_thresh_per_class_;
345
346 std::map<std::string, int> head_map_;
347 std::map<std::string, int> feature_offset_;
348
349 const int kGPUThreadSize = 512;
350
351 std::vector<ResultsOutput> res_outputs_;
352
353 cudaStream_t stream_ = 0;
354
355 std::shared_ptr<BaseDownSample> down_sample_;
356}; // class CPDetection
357
358} // namespace lidar
359} // namespace perception
360} // namespace apollo
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
Definition blob.h:88
bool Init(const CPDetectorInitOptions &options=CPDetectorInitOptions()) override
Init the Base Lidar Detector object
Definition cpdet.cc:56
bool Detect(const CPDetectorOptions &options, LidarFrame *frame) override
Detect foreground objects
Definition cpdet.cc:1551
std::string Name() const
Name of Base Lidar Detector class
Definition cpdet.h:83
void GenerateBackboneFeature(const base::Blob< float > *pillar_feature_blob)
Definition cpdet.h:93
#define AERROR
Definition log.h:44
Point< float > PointF
Definition point.h:56
std::shared_ptr< PointFCloud > PointFCloudPtr
class register implement
Definition arena_queue.h:37