Apollo 10.0
自动驾驶开放平台
bevformer_obstacle_detector.cc
浏览该文件的文档.
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 *****************************************************************************/
17
18#include <unistd.h>
19
20#include <limits>
21#include <map>
22#include <memory>
23
24#include <cuda_runtime.h>
25#include <pcl/features/normal_3d.h>
26#include <pcl/io/pcd_io.h>
27#include <pcl/search/kdtree.h>
28#include <pcl/search/search.h>
29#include <pcl/segmentation/region_growing.h>
30
31#include "cyber/common/file.h"
32#include "cyber/common/log.h"
43
44namespace apollo {
45namespace perception {
46namespace camera {
50using base::PointF;
51
52const std::map<std::string, base::ObjectSubType> kNuScenesName2SubTypeMap = {
55 {"construction_vehicle", base::ObjectSubType::CAR},
57 {"trailer", base::ObjectSubType::CAR},
61 {"pedestrian", base::ObjectSubType::PEDESTRIAN},
62 {"traffic_cone", base::ObjectSubType::TRAFFICCONE},
63 {"MAX_OBJECT_TYPE", base::ObjectSubType::MAX_OBJECT_TYPE},
64};
65
66const std::map<int, std::string> kIndex2NuScenesName = {
67 {0, "car"}, {1, "truck"}, {2, "construction_vehicle"},
68 {3, "bus"}, {4, "trailer"}, {5, "barrier"},
69 {6, "motorcycle"}, {7, "bicycle"}, {8, "pedestrian"},
70 {9, "traffic_cone"},
71};
72
73const std::map<std::string, base::ObjectSubType> kApolloName2SubTypeMap = {
74 {"smallMot", base::ObjectSubType::CAR},
75 {"bigMot", base::ObjectSubType::CAR},
77 {"pedestrian", base::ObjectSubType::PEDESTRIAN},
78 {"TrainedOthers", base::ObjectSubType::TRAFFICCONE},
79 {"MAX_OBJECT_TYPE", base::ObjectSubType::MAX_OBJECT_TYPE},
80};
81
82const std::map<int, std::string> kIndex2ApolloName = {{0, "smallMot"},
83 {1, "bigMot"},
84 {2, "nonMot"},
85 {3, "pedestrian"},
86 {4, "TrainedOthers"}};
87
88void BEVFORMERObstacleDetector::InitImageSize(
89 const bevformer::ModelParam &model_param) {
90 auto resize = model_param.resize();
91 if (resize.width() == 0 && resize.height() == 0) {
92 width_ = options_.image_width * resize.fx();
93 height_ = options_.image_height * resize.fy();
94 } else {
95 width_ = resize.width();
96 height_ = resize.height();
97 }
98
99 AINFO << "height=" << height_ << ", "
100 << "width=" << width_;
101}
102
103bool BEVFORMERObstacleDetector::InitTypes(
104 const bevformer::ModelParam &model_param) {
105 for (const auto &class_name : model_param.info().class_names()) {
106 if (kNuScenesName2SubTypeMap.find(class_name) !=
108 types_.push_back(kNuScenesName2SubTypeMap.at(class_name));
109 } else {
110 AERROR << "Unsupported subtype type!" << class_name;
111 return false;
112 }
113 }
114 return true;
115}
116
118 const ObstacleDetectorInitOptions &options) {
119 options_ = options;
120 gpu_id_ = options.gpu_id;
121 BASE_GPU_CHECK(cudaSetDevice(gpu_id_));
122 BASE_GPU_CHECK(cudaStreamCreate(&stream_));
123
124 std::string config_file =
125 GetConfigFile(options_.config_path, options_.config_file);
126 std::cout << " config file is " << config_file << std::endl;
127 if (!cyber::common::GetProtoFromFile(config_file, &model_param_)) {
128 AERROR << "Read model param failed!";
129 return false;
130 }
131
132 InitTypes(model_param_);
133 InitImageSize(model_param_);
134
135 common::Normalize normalize = model_param_.normalize();
136 mean_bgr_ = {normalize.mean()[0], normalize.mean()[1], normalize.mean()[2]};
137 std_bgr_ = {normalize.std()[0], normalize.std()[1], normalize.std()[2]};
138
139 const auto &model_info = model_param_.info();
140 std::string model_path = GetModelPath(model_info.name());
141
142 if (!InitNetwork(model_param_.info(), model_path)) {
143 AERROR << "Init network failed!";
144 return false;
145 }
146 std::cout << "bevformer model init success from "
147 << model_info.proto_file().file() << std::endl;
148
149 auto model_outputs = model_param_.info().outputs();
150 num_decoder_layer_ = model_outputs[1].shape()[0];
151 num_queries_ = model_outputs[1].shape()[2];
152 num_classes_det_ = model_outputs[1].shape()[3];
153 code_size_ = model_outputs[2].shape()[3];
154 class_blob_start_index_ =
155 (num_decoder_layer_ - 1) * num_queries_ * num_classes_det_;
156 class_blob_end_index_ =
157 (num_decoder_layer_)*num_queries_ * num_classes_det_;
158 box_blob_start_index_ =
159 (num_decoder_layer_ - 1) * num_queries_ * code_size_;
160 AINFO << "number of decoder layer:" << num_decoder_layer_
161 << " number of query: " << num_queries_
162 << " number of classes: " << num_classes_det_
163 << " code size: " << code_size_
164 << " class blob start index: " << class_blob_start_index_
165 << " class blob end index: " << class_blob_end_index_
166 << " box blob start index: " << box_blob_start_index_;
167
168 num_voxels_ = model_outputs[occ_blob_index_].shape()[1];
169 num_classes_occ_ = model_outputs[occ_blob_index_].shape()[2];
170 AINFO << " number of occ voxels " << num_voxels_
171 << " number of occ classes " << num_classes_occ_;
172 occ_xmin_ = model_param_.occ_xmin();
173 occ_xmax_ = model_param_.occ_xmax();
174 occ_ymin_ = model_param_.occ_ymin();
175 occ_ymax_ = model_param_.occ_ymax();
176 occ_zmin_ = model_param_.occ_zmin();
177 occ_zmax_ = model_param_.occ_zmax();
178 voxel_size_ = model_param_.voxel_size();
179 occ_x_grid_ = (occ_xmax_ - occ_xmin_) / voxel_size_;
180 occ_y_grid_ = (occ_ymax_ - occ_ymin_) / voxel_size_;
181 occ_z_grid_ = (occ_zmax_ - occ_zmin_) / voxel_size_;
182
183
184 auto model_inputs = model_param_.info().inputs();
185 auto prev_bev_shape = model_inputs[1].shape();
186 for (auto size : prev_bev_shape) {
187 prev_bev_size_ *= size;
188 }
189 use_prev_bev_ = new float(0.0);
190
191 float no_pad_image_width = model_param_.no_pad_image_width();
192 float no_pad_image_height = model_param_.no_pad_image_height();
193 CHECK(no_pad_image_width <= model_inputs[0].shape()[3]);
194 CHECK(no_pad_image_height <= model_inputs[0].shape()[4]);
195 no_pad_image_shape_[0] = no_pad_image_width;
196 no_pad_image_shape_[1] = no_pad_image_height;
197 occ_threshold_ = model_param_.occ_threshold();
198
199 trans_wrapper_.reset(new onboard::TransformWrapper());
200 // tf_camera_frame_id
201 trans_wrapper_->Init("CAM_FRONT");
202 return true;
203}
204
205void BEVFORMERObstacleDetector::Mat2Vec(const cv::Mat &im, float *data) {
206 ACHECK(nullptr != data);
207 int rh = im.rows;
208 int rw = im.cols;
209 int rc = im.channels();
210
211 for (int i = 0; i < rc; ++i) {
212 cv::extractChannel(im, cv::Mat(rh, rw, CV_32FC1, data + i * rh * rw), i);
213 }
214}
215
216bool BEVFORMERObstacleDetector::ImagePreprocessGPU(
217 const CameraFrame *frame, base::BlobPtr<float> input_img_blob) {
218 ACHECK(frame != nullptr);
219 ACHECK(input_img_blob != nullptr);
220
221 DataProvider::ImageOptions image_options;
222 image_options.target_color = base::Color::RGB;
223 base::Image8U image;
224
225 float scale = model_param_.img_scale();
226
227 std::vector<int> img_blob_shape(input_img_blob->shape().begin(),
228 input_img_blob->shape().end());
229
230 std::vector<int> value(1);
231 auto resized_image = std::make_shared<Blob<float>>(value);
232 resized_image->Reshape({img_blob_shape[0], img_blob_shape[2],
233 img_blob_shape[3], img_blob_shape[4]});
234
235 PERF_BLOCK("stage bev process image")
236 for (int i = 0; i < img_blob_shape[1]; ++i) {
237 PERF_BLOCK("stage bev readimage")
238 frame->data_provider[i]->GetImage(image_options, &image);
240
241 int left_pad = 0;
242 int right_pad = 0;
243 int top_pad = 0;
244 int bottom_pad = 0;
245
246 int roi_width = image.cols();
247 int roi_height = image.rows();
248
249 // int bg_rows = 0;
250 // if (std::ceil(roi_height * scale / 32) * 32 < roi_height * scale) {
251 // bg_rows = (std::ceil(roi_height * scale / 32) + 1) * 32;
252 // } else {
253 // bg_rows = std::ceil(roi_height * scale / 32) * 32;
254 // }
255
256 // // do down padding on image
257 // if (roi_width > roi_height) {
258 // top_pad = 0;
259 // bottom_pad = (bg_rows - image.rows() * scale) / scale;
260 // }
261
262 // int dst_height = roi_height + bottom_pad + top_pad; // 960
263 // int dst_width = roi_width + left_pad + right_pad; // 1600
264
265 // top_pad = 0;
266 // bottom_pad = 960 - height_;
267
268 bottom_pad = img_blob_shape[3] / scale - roi_height;
269
270 int dst_height = roi_height + bottom_pad + top_pad;
271 int dst_width = roi_width + left_pad + right_pad;
272 // AERROR << " dst_height: " << dst_height
273 // << " dst_width: " << dst_width
274 // << " bottom_pad: " << bottom_pad;
275
276 CHECK(dst_height * scale == img_blob_shape[3]);
277 CHECK(dst_width * scale == img_blob_shape[4]);
278
279 base::Image8U padding_image_container_ =
280 base::Image8U(dst_height, dst_width, base::Color::RGB);
281
282 base::Image8U tmp_image =
283 padding_image_container_(base::RectI(0, 0, dst_width, dst_height));
284 PERF_BLOCK("stage bev padding")
285 inference::ImageZeroPadding(image, &tmp_image, roi_width, left_pad,
286 right_pad, top_pad, bottom_pad, 0, stream_,
287 true);
289
290 PERF_BLOCK("stage bev resize")
291 inference::ResizeGPU(tmp_image, resized_image,
292 frame->data_provider[i]->src_width(), 0, mean_bgr_[0],
293 mean_bgr_[1], mean_bgr_[2], false, std_bgr_[0],
294 std_bgr_[1], std_bgr_[2]);
296
297 PERF_BLOCK("stage bev memcpy")
298
299 cudaMemcpy(input_img_blob->mutable_gpu_data() + i * img_blob_shape[2] *
300 img_blob_shape[3] *
301 img_blob_shape[4],
302 resized_image->gpu_data(),
303 img_blob_shape[2] * img_blob_shape[3] * img_blob_shape[4] *
304 sizeof(float),
305 cudaMemcpyHostToDevice);
307 }
309 return true;
310}
311
312bool BEVFORMERObstacleDetector::ImagePreprocess(
313 const CameraFrame *frame, base::BlobPtr<float> input_img_blob) {
314 ACHECK(frame != nullptr);
315 ACHECK(input_img_blob != nullptr);
316
317 DataProvider::ImageOptions image_options;
318 image_options.target_color = base::Color::RGB;
319
320 float scale = 1.0;
321 int camera_num = 6;
322 base::Image8U image;
323 std::vector<float> images_data;
324
325 input_img_blob->Reshape({1, camera_num, 3, 480, 800});
326 // Attention: img_data_ptr will change after reshape
327 float *img_data_ptr = input_img_blob->mutable_cpu_data();
328
329 PERF_BLOCK("stage bev preprocess")
330 for (int i = 0; i < camera_num; ++i) {
331 PERF_BLOCK("stage bev readimage")
332 frame->data_provider[i]->GetImage(image_options, &image);
333 cv::Mat img(image.rows(), image.cols(), CV_8UC3, cv::Scalar(0, 0, 0));
334 memcpy(img.data, image.cpu_data(), image.total() * sizeof(uint8_t));
336
337 // step2 : resize
338 PERF_BLOCK("stage bev resize")
339 cv::resize(img, img, cv::Size(width_, height_));
341
342 // step3 : padding
343 PERF_BLOCK("stage bev padding")
344 int bg_rows = 0;
345 if (std::ceil(img.rows / 32) * 32 < img.rows) {
346 bg_rows = (std::ceil(img.rows / 32) + 1) * 32;
347 } else {
348 bg_rows = std::ceil(img.rows / 32) * 32;
349 }
350 cv::Mat out(bg_rows, img.cols, CV_8UC3, {0, 0, 0});
351
352 img.copyTo(out(cv::Rect(0, 0, img.cols, img.rows)));
354
355 PERF_BLOCK("stage bev normalize")
356 common::Normalize normalize = model_param_.normalize();
357 std::vector<float> mean{normalize.mean().begin(), normalize.mean().end()};
358 std::vector<float> std{normalize.std().begin(), normalize.std().end()};
359 std::reverse(mean.begin(), mean.end());
360 std::reverse(std.begin(), std.end());
361 BevFormerNormalize(mean, std, scale, &out);
363
364 std::vector<float> image_data(1 * 3 * out.cols * out.rows, 0.0f);
365 Mat2Vec(out, image_data.data());
366
367 images_data.insert(images_data.end(), image_data.begin(), image_data.end());
368 }
369 memcpy(img_data_ptr, images_data.data(), images_data.size() * sizeof(float));
371 return true;
372}
373
374bool BEVFORMERObstacleDetector::ImageExtrinsicPreprocess(
375 const CameraFrame *frame, base::BlobPtr<float> input_blob_lidar2img) {
376 if (resize_flag_ == false) {
377 resized_lidar2img_.resize(96);
378 for (int i = 0; i < 96; i++) {
379 if (i % 16 < 8) {
380 resized_lidar2img_.at(i) =
381 frame->k_lidar2img.at(i) * model_param_.img_scale();
382 } else {
383 resized_lidar2img_.at(i) = frame->k_lidar2img.at(i);
384 }
385 }
386 resize_flag_ = true;
387 }
388 memcpy(input_blob_lidar2img->mutable_cpu_data(), resized_lidar2img_.data(),
389 resized_lidar2img_.size() * sizeof(float));
390 return true;
391}
392
393void BEVFORMERObstacleDetector::FillCanBus(const CameraFrame *frame,
394 base::BlobPtr<float> can_bus_blob) {
395 apollo::cyber::Time query_time(frame->timestamp);
396 apollo::transform::TransformStamped stamped_transform;
397
398 try {
399 stamped_transform =
400 tf2_buffer_->lookupTransform("world", "localization", query_time);
401 // AERROR << "find tf! " << query_time;
402 } catch (tf2::TransformException &ex) {
403 AERROR << ex.what();
404 AERROR << "can't find tf! " << query_time;
405 return;
406 }
407
408 Eigen::Quaterniond rotation(stamped_transform.transform().rotation().qw(),
409 stamped_transform.transform().rotation().qx(),
410 stamped_transform.transform().rotation().qy(),
411 stamped_transform.transform().rotation().qz());
412 std::vector<double> current_can_bus;
413 std::vector<double> input_can_bus;
414 std::vector<float> input_can_bus_float;
415 current_can_bus.push_back(stamped_transform.transform().translation().x());
416 current_can_bus.push_back(stamped_transform.transform().translation().y());
417 current_can_bus.push_back(stamped_transform.transform().translation().z());
418 // note: instead of qw, qx, qy, qz, here use 4*qw as same as training
419 current_can_bus.push_back(stamped_transform.transform().rotation().qw());
420 current_can_bus.push_back(stamped_transform.transform().rotation().qw());
421 current_can_bus.push_back(stamped_transform.transform().rotation().qw());
422 current_can_bus.push_back(stamped_transform.transform().rotation().qw());
423 for (int ii = 0; ii < 9; ii++) {
424 current_can_bus.push_back(0.0);
425 }
426 Eigen::Vector3d vec(1.0, 0.0, 0.0);
427 vec = rotation.toRotationMatrix() * vec;
428 double yaw = atan2(vec(1), vec(0));
429 yaw = yaw / M_PI * 180;
430 if (yaw < 0) {
431 yaw += 360;
432 }
433 current_can_bus.push_back(yaw / 180 * M_PI);
434 current_can_bus.push_back(yaw);
435
436 input_can_bus = current_can_bus;
437 if (*use_prev_bev_) {
438 input_can_bus[0] -= last_can_bus_[0];
439 input_can_bus[1] -= last_can_bus_[1];
440 input_can_bus[2] -= last_can_bus_[2];
441 input_can_bus[17] -= last_can_bus_[17];
442 } else {
443 input_can_bus[0] = 0.0;
444 input_can_bus[1] = 0.0;
445 input_can_bus[2] = 0.0;
446 input_can_bus[17] = 0.0;
447 }
448
449 last_can_bus_ = current_can_bus;
450 for (int ii = 0; ii < input_can_bus.size(); ii++) {
451 input_can_bus_float.push_back(static_cast<float>(input_can_bus.at(ii)));
452 }
453 // can_bus_blob:
454 // 0-2: ego-car x/y/z offset (m) of current frame and last frame in world
455 // coordiante 3-6: ego-car qw of current frame and last frame in world
456 // coordiante 7-16: 0 16: yaw 17: (yaw/pi) * 180 diff of current frame and
457 // last frame
458
459 for (int ii = 0; ii < 3; ii++) {
460 if (input_can_bus.at(ii) >= model_param_.location_dist_threshold()) {
461 AERROR << "warning, ego-car location is too large!";
462 }
463 }
464
465 memcpy(can_bus_blob->mutable_cpu_data(), input_can_bus_float.data(),
466 sizeof(float) * input_can_bus_float.size());
467}
468
469void BEVFORMERObstacleDetector::GetObjects(
470 const CameraFrame *frame, const float *outputs_scores,
471 const float *outputs_coords, std::vector<base::ObjectPtr> *objects) {
472 int num_objects = 0;
473 ACHECK(objects != nullptr);
474 objects->clear();
475 float score_threshold = model_param_.score_threshold();
476 for (int i = class_blob_start_index_; i < class_blob_end_index_; i++) {
477 int current_layer_index = i - class_blob_start_index_;
478 float score = outputs_scores[i];
479 if (score >= score_threshold) {
480 num_objects += 1;
481 int label = floor(current_layer_index % num_classes_det_);
482 int box_index = current_layer_index / num_classes_det_;
483 int current_layer_box_index =
484 box_blob_start_index_ + box_index * code_size_;
485 float cx = outputs_coords[current_layer_box_index];
486 float cy = outputs_coords[current_layer_box_index + 1];
487 float cz = outputs_coords[current_layer_box_index + 4];
488 float w = exp(outputs_coords[current_layer_box_index + 2]);
489 float l = exp(outputs_coords[current_layer_box_index + 3]);
490 float h = exp(outputs_coords[current_layer_box_index + 5]);
491 float rot = atan2(outputs_coords[current_layer_box_index + 6],
492 outputs_coords[current_layer_box_index + 7]);
493
494 base::ObjectPtr obj = nullptr;
495 obj.reset(new base::Object);
496 obj->sub_type =
498 obj->sub_type_probs.assign(
499 static_cast<int>(base::ObjectSubType::MAX_OBJECT_TYPE), 0);
500 obj->sub_type_probs[static_cast<int>(obj->sub_type)] = score;
501 obj->type = base::kSubType2TypeMap.at(obj->sub_type);
502 obj->type_probs.assign(
503 static_cast<int>(base::ObjectType::MAX_OBJECT_TYPE), 0);
504 obj->type_probs[static_cast<int>(obj->type)] = score;
505 obj->confidence = score;
506 obj->center(0) = cx;
507 obj->center(1) = cy;
508 obj->center(2) = cz;
509 obj->size[0] = l;
510 obj->size[1] = w;
511 obj->size[2] = h;
512 obj->theta = -rot - M_PI / 2;
513 if (obj->theta > M_PI) {
514 obj->theta = obj->theta - 2 * M_PI;
515 }
516 if (obj->theta < -M_PI) {
517 obj->theta = obj->theta + 2 * M_PI;
518 }
519 objects->push_back(obj);
520 AINFO << "timestamp " << std::to_string(frame->timestamp)
521 << " type: " << label << " score: " << score << " center: " << cx
522 << " " << cy << " " << cz << " lwh: " << l << " " << w << " " << h
523 << " rot " << rot;
524 }
525 }
526 AINFO << " bevformer detect " << num_objects << " objects";
527}
528
529bool BEVFORMERObstacleDetector::GetOccResults(CameraFrame *frame,
530 const float *outputs_occupancy) {
531 if (frame == nullptr) {
532 return false;
533 }
534 occ_results_.clear();
535 int valid_occ_point = 0;
536 for (int voxel_index = 0; voxel_index < num_voxels_; voxel_index++) {
537 float max_prob = 0.0;
538 int class_pred = num_classes_occ_ + 1;
539 for (int class_index = 0; class_index < num_classes_occ_; class_index++) {
540 float class_prob =
541 outputs_occupancy[voxel_index * num_classes_occ_ + class_index];
542 if (class_prob > max_prob) {
543 max_prob = class_prob;
544 class_pred = class_index;
545 }
546 }
547 if (max_prob >= occ_threshold_) {
548 occ_results_.push_back(std::make_pair(voxel_index, class_pred));
549 valid_occ_point += 1;
550 }
551 }
552 AINFO << "number of valid occ voxels: " << valid_occ_point;
553
554
555 if (access(model_param_.occ_save_path().c_str(), 0) == -1) {
556 system(("mkdir " + model_param_.occ_save_path()).c_str());
557 }
558 std::string out_file = model_param_.occ_save_path() + '/' +
559 std::to_string(frame->timestamp) + ".bin";
560 std::ofstream out_stream;
561 out_stream.open(out_file);
562 for (int i = 0; i < occ_results_.size(); i++) {
563 out_stream << occ_results_.at(i).first << " " << occ_results_.at(i).second
564 << " ";
565 }
566 out_stream.close();
567
568 return true;
569}
570
572 if (frame == nullptr) {
573 return false;
574 }
575 // AERROR << "current time is " << std::to_string(frame->timestamp);
576
577 auto model_inputs = model_param_.info().inputs();
578 auto input_blob_img = net_->get_blob(model_inputs[0].name());
579 auto input_blob_prev_bev = net_->get_blob(model_inputs[1].name());
580 auto input_blob_use_prev_bev = net_->get_blob(model_inputs[2].name());
581 auto input_blob_can_bus = net_->get_blob(model_inputs[3].name());
582 auto input_blob_lidar2img = net_->get_blob(model_inputs[4].name());
583 auto input_blob_no_pad_image_shape = net_->get_blob(model_inputs[5].name());
584 auto model_outputs = model_param_.info().outputs();
585
586 PERF_BLOCK("stage bev process")
587 memcpy(input_blob_no_pad_image_shape->mutable_cpu_data(),
588 no_pad_image_shape_.data(),
589 sizeof(float) * no_pad_image_shape_.size());
590 ImageExtrinsicPreprocess(frame, input_blob_lidar2img);
591 ImagePreprocessGPU(frame, input_blob_img);
592 FillCanBus(frame, input_blob_can_bus);
593 memcpy(input_blob_use_prev_bev->mutable_cpu_data(), use_prev_bev_,
594 sizeof(float));
595 if (*use_prev_bev_) {
596 auto bev_embed = net_->get_blob(model_outputs[0].name());
597 cudaMemcpy(input_blob_prev_bev->mutable_gpu_data(), bev_embed->gpu_data(),
598 prev_bev_size_ * sizeof(float), cudaMemcpyHostToDevice);
599 }
601
602 PERF_BLOCK("stage bev infer")
603 net_->Infer();
605
606 PERF_BLOCK("stage bev get objects")
607 auto outputs_classes = net_->get_blob(model_outputs[1].name());
608 auto outputs_coords = net_->get_blob(model_outputs[2].name());
609 const float *outputs_classes_ptr = outputs_classes->cpu_data();
610 const float *outputs_coords_ptr = outputs_coords->cpu_data();
611 GetObjects(frame, outputs_classes_ptr, outputs_coords_ptr,
612 &frame->detected_objects);
614
615 PERF_BLOCK("stage bev get occ")
616 if (model_param_.save_occ_result()) {
617 auto outputs_occupancy =
618 net_->get_blob(model_outputs[occ_blob_index_].name());
619 const float *outputs_occupancy_ptr = outputs_occupancy->cpu_data();
620 GetOccResults(frame, outputs_occupancy_ptr);
621 }
623
624 Nuscenes2Apollo(&frame->detected_objects);
625 *use_prev_bev_ = 1.0;
626 return true;
627}
628
629bool BEVFORMERObstacleDetector::Nuscenes2Apollo(
630 std::vector<base::ObjectPtr> *objects) {
631 ACHECK(objects != nullptr);
632 for (auto &obj : *objects) {
633 // if (model_param_.info().dataset() == "nuScenes") {
634 // obj->theta += M_PI / 2;
635 // }
636 obj->direction[0] = cosf(obj->theta);
637 obj->direction[1] = sinf(obj->theta);
638 obj->direction[2] = 0;
639
640 // if (model_param_.info().dataset() == "nuScenes") {
641 // Eigen::AngleAxisd rotation_vector(M_PI / 2, Eigen::Vector3d(0, 0, 1));
642 // obj->center = rotation_vector.matrix() * obj->center;
643 // }
644 obj->camera_supplement.local_center[0] = static_cast<float>(obj->center[0]);
645 obj->camera_supplement.local_center[1] = static_cast<float>(obj->center[1]);
646 obj->camera_supplement.local_center[2] = static_cast<float>(obj->center[2]);
647 }
648 return true;
649}
650
652
653} // namespace camera
654} // namespace perception
655} // namespace apollo
#define REGISTER_OBSTACLE_DETECTOR(name)
Cyber has builtin time type Time.
Definition time.h:31
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
Definition blob.h:88
bool Detect(CameraFrame *frame) override
Get obstacles detection result
bool Init(const ObstacleDetectorInitOptions &options=ObstacleDetectorInitOptions()) override
Init ObstacleDetector constructor.
virtual bool InitNetwork(const common::ModelInfo &model_info, const std::string &model_root)
Interface for network initialization
std::shared_ptr< inference::Inference > net_
virtual TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const cyber::Time &time, const float timeout_second=0.01f) const
Get the transform between two frames by frame ID.
Definition buffer.cc:168
#define ACHECK(cond)
Definition log.h:80
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
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,...
Definition file.cc:132
Point< float > PointF
Definition point.h:56
const std::map< ObjectSubType, ObjectType > kSubType2TypeMap
ObjectSubType mapping
std::shared_ptr< Object > ObjectPtr
Definition object.h:127
const std::map< int, std::string > kIndex2ApolloName
void Normalize(const std::vector< float > &mean, const std::vector< float > &std, float scale, cv::Mat *img)
Image normalize function
Definition preprocess.cc:33
cv::Mat GetImage(const std::string &path, bool to_rgb)
const std::map< std::string, base::ObjectSubType > kNuScenesName2SubTypeMap
const std::map< std::string, base::ObjectSubType > kApolloName2SubTypeMap
const std::map< int, std::string > kIndex2NuScenesName
void BevFormerNormalize(const std::vector< float > &mean, const std::vector< float > &std, float scale, cv::Mat *img)
Image normalize function
Definition preprocess.cc:34
void TransformToPCLXYZI(const base::AttributePointCloud< PointT > &org_cloud, const pcl::PointCloud< pcl::PointXYZI >::Ptr &out_cloud_ptr)
Definition pcl_util.h:100
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
Definition util.cc:80
std::string GetModelPath(const std::string &model_name)
Get the model path by model name, search from APOLLO_MODEL_PATH
Definition util.cc:44
class register implement
Definition arena_queue.h:37
Definition future.h:29
#define PERF_BLOCK_END
Definition profiler.h:53
#define PERF_BLOCK(...)
Definition profiler.h:52
Contains a number of helper functions related to quaternions.
std::vector< base::ObjectPtr > detected_objects
optional apollo::common::Quaternion rotation
optional apollo::common::Point3D translation