Apollo 11.0
自动驾驶开放平台
apollo::perception::camera::Yolox3DObstacleDetector类 参考

#include <yolox3d_obstacle_detector.h>

类 apollo::perception::camera::Yolox3DObstacleDetector 继承关系图:
apollo::perception::camera::Yolox3DObstacleDetector 的协作图:

Public 成员函数

 Yolox3DObstacleDetector ()
 
virtual ~Yolox3DObstacleDetector ()
 
bool Init (const ObstacleDetectorInitOptions &options=ObstacleDetectorInitOptions()) override
 Necessary, Init yolox3d model params normal, but now use pipline instead
 
bool Detect (onboard::CameraFrame *frame) override
 Interface for obstacle detector main part
 
std::string Name () const override
 return detector name
 
- Public 成员函数 继承自 apollo::perception::camera::BaseObstacleDetector
 BaseObstacleDetector ()=default
 
virtual ~BaseObstacleDetector ()=default
 
virtual bool Detect (CameraFrame *frame)=0
 Interface for obstacle detector main part
 
virtual bool InitNetwork (const common::ModelInfo &model_info, const std::string &model_root)
 Interface for network initialization
 
 BaseObstacleDetector ()=default
 
virtual ~BaseObstacleDetector ()=default
 
virtual bool InitNetwork (const common::ModelInfo &model_info, const std::string &model_root)
 Interface for network initialization
 

Protected 成员函数

bool Preprocess (const base::Image8U *image, base::BlobPtr< float > input_blob)
 Preprocess of image before inference, resize input data blob and fill image data to blob
 
void LoadInputShape (const yolox3d::ModelParam &model_param)
 Resize model input picture size according to the config file
 
void LoadParam (const yolox3d::ModelParam &model_param)
 Load yolo libtorch model params from model file
 
void Yolo3DInference (const base::Image8U *image, std::vector< base::ObjectPtr > &detect_objs)
 Load yolo3D libtorch model params from model file
 
bool Init3DNetwork (const common::ModelInfo &model_info, const std::string &model_path)
 Init model inference
 
- Protected 成员函数 继承自 apollo::perception::camera::BaseObstacleDetector
 DISALLOW_COPY_AND_ASSIGN (BaseObstacleDetector)
 
 DISALLOW_COPY_AND_ASSIGN (BaseObstacleDetector)
 

额外继承的成员函数

- Protected 属性 继承自 apollo::perception::camera::BaseObstacleDetector
int gpu_id_ = 0
 
std::shared_ptr< inference::Inference > net_
 

详细描述

在文件 yolox3d_obstacle_detector.h 第 39 行定义.

构造及析构函数说明

◆ Yolox3DObstacleDetector()

apollo::perception::camera::Yolox3DObstacleDetector::Yolox3DObstacleDetector ( )
inline

◆ ~Yolox3DObstacleDetector()

virtual apollo::perception::camera::Yolox3DObstacleDetector::~Yolox3DObstacleDetector ( )
inlinevirtual

在文件 yolox3d_obstacle_detector.h 第 42 行定义.

42 {
43 if (stream_ != nullptr) {
44 cudaStreamDestroy(stream_);
45 }
46 }

成员函数说明

◆ Detect()

bool apollo::perception::camera::Yolox3DObstacleDetector::Detect ( onboard::CameraFrame *  frame)
overridevirtual

Interface for obstacle detector main part

参数
frameobstacle type and 2D bbox should be filled, required, 3D information of obstacle can be filled, optional.
返回
true
false

实现了 apollo::perception::camera::BaseObstacleDetector.

在文件 yolox3d_obstacle_detector.cc 第 360 行定义.

360 {
361 if (frame == nullptr) {
362 return false;
363 }
364
365 if (cudaSetDevice(gpu_id_) != cudaSuccess) {
366 AERROR << "Failed to set device to " << gpu_id_;
367 return false;
368 }
369
370 auto model_inputs = model_param_.info().inputs();
371 auto input_blob_2d = net_->get_blob(model_inputs[0].name());
372
373 DataProvider::ImageOptions image_options;
374 image_options.target_color = base::Color::BGR;
375
376 base::Image8U image;
377 frame->data_provider->GetImage(image_options, &image);
378
380 // gpu preprocess
381 int left_pad = 0;
382 int right_pad = 0;
383 int top_pad = 0;
384 int bottom_pad = 0;
385 int roi_width = image_width_;
386 int roi_height = image_height_;
387
388 // do down pad on image
389 if (roi_width > roi_height) {
390 top_pad = 0;
391 bottom_pad = roi_width - roi_height;
392 } else if (roi_height > roi_width) {
393 left_pad = 0;
394 right_pad = roi_height - roi_width;
395 }
396
397 int dst_height = roi_height + top_pad + bottom_pad;
398 int dst_width = roi_width + left_pad + right_pad;
399
400 base::Image8U padding_image_container_ = base::Image8U(dst_width, dst_height, base::Color::BGR);
401
402 base::Image8U tmp_image = padding_image_container_(base::RectI(0, 0, dst_width, dst_height));
403
404 PERF_BLOCK("2d padding stage")
405 inference::ImageZeroPadding(
406 image, &tmp_image, roi_width, left_pad, right_pad, top_pad, bottom_pad, 114, stream_, true);
408
409 input_blob_2d->Reshape(
410 {input_blob_2d->shape(0), input_blob_2d->shape(1), input_blob_2d->shape(2), input_blob_2d->shape(3)});
411
412 PERF_BLOCK("2d resize stage")
413 int mean_bgr[3] = {114, 114, 114};
415 tmp_image,
416 input_blob_2d,
417 frame->data_provider->src_width(),
418 0,
419 mean_bgr[0],
420 mean_bgr[1],
421 mean_bgr[2],
422 false,
423 1.0);
425 // //////////////////////////
426
427 // model infer, save to output blob
428 net_->Infer();
429
430 img_ = cv::Mat(image.rows(), image.cols(), CV_8UC3);
431 memcpy(img_.data, image.cpu_data(), image.rows() * image.cols() * image.channels() * sizeof(uint8_t));
432
433 // get objects from network inference result
434 auto model_outputs = model_param_.info().outputs();
435
436 // Attention(lordon): onnx predict blob is 1, pth is 0
437 auto predict_blob = net_->get_blob(model_outputs[1].name());
438 frame->feature_blob = net_->get_blob(model_outputs[0].name());
439
440 PERF_BLOCK("2d postprocess stage")
442 predict_blob, model_param_, nms_, width_, height_, image_width_, image_height_, &frame->detected_objects);
444
445 // post process for 3d
446 Yolo3DInference(&image, frame->detected_objects);
447 return true;
448}
std::shared_ptr< inference::Inference > net_
void Yolo3DInference(const base::Image8U *image, std::vector< base::ObjectPtr > &detect_objs)
Load yolo3D libtorch model params from model file
#define AERROR
Definition log.h:44
Rect< int > RectI
Definition box.h:159
void YoloxGetObjectsCpu(const std::shared_ptr< base::Blob< float > > &objects_blob, const yolox3d::ModelParam &model_param, const yolox3d::NMSParam &nms_param, const int width, const int height, const int image_width, const int image_height, std::vector< base::ObjectPtr > *objects)
Return Yolox Objects
bool ResizeGPU(const base::Image8U &src, std::shared_ptr< apollo::perception::base::Blob< float > > dst, int stepwidth, int start_axis)
#define PERF_BLOCK_END
Definition profiler.h:53
#define PERF_BLOCK(...)
Definition profiler.h:52

◆ Init()

bool apollo::perception::camera::Yolox3DObstacleDetector::Init ( const ObstacleDetectorInitOptions &  options = ObstacleDetectorInitOptions())
overridevirtual

Necessary, Init yolox3d model params normal, but now use pipline instead

参数
optionsobstacle detection init options
返回
init status, yolox3d detector stage status

实现了 apollo::perception::camera::BaseObstacleDetector.

在文件 yolox3d_obstacle_detector.cc 第 283 行定义.

283 {
284 options_ = options;
285
286 gpu_id_ = options.gpu_id;
287 BASE_GPU_CHECK(cudaSetDevice(gpu_id_));
288 BASE_GPU_CHECK(cudaStreamCreate(&stream_));
289
290 std::string config_file = GetConfigFile(options.config_path, options.config_file);
291 if (!cyber::common::GetProtoFromFile(config_file, &model_param_)) {
292 AERROR << "Read proto_config failed! " << config_file;
293 return false;
294 }
295
296 LoadInputShape(model_param_);
297 LoadParam(model_param_);
298
299 const auto &model_info = model_param_.info();
300 std::string model_path = GetModelPath(model_info.name());
301 if (!InitNetwork(model_info, model_path)) {
302 AERROR << "Init network failed!";
303 return false;
304 }
305 net_->Infer();
306 AERROR << "[INFO] yolox3d 2D model init success";
307
308 const auto &model_info_3d = model_param_.info_3d().info();
309 std::string model_path_3d = GetModelPath(model_info_3d.name());
310 if (!Init3DNetwork(model_info_3d, model_path_3d)) {
311 AERROR << "Init network failed!";
312 return false;
313 }
314 net_3D_->Infer();
315 AERROR << "[INFO] yolox3d 3D model init success";
316
317 return true;
318}
virtual bool InitNetwork(const common::ModelInfo &model_info, const std::string &model_root)
Interface for network initialization
bool Init3DNetwork(const common::ModelInfo &model_info, const std::string &model_path)
Init model inference
void LoadInputShape(const yolox3d::ModelParam &model_param)
Resize model input picture size according to the config file
void LoadParam(const yolox3d::ModelParam &model_param)
Load yolo libtorch model params from model file
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
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

◆ Init3DNetwork()

bool apollo::perception::camera::Yolox3DObstacleDetector::Init3DNetwork ( const common::ModelInfo &  model_info,
const std::string &  model_path 
)
protected

Init model inference

参数
model_info
model_path
返回
true
false

在文件 yolox3d_obstacle_detector.cc 第 73 行定义.

73 {
74 // Network files
75 std::string proto_file = GetModelFile(model_path, model_info.proto_file().file());
76 std::string weight_file = GetModelFile(model_path, model_info.weight_file().file());
77
78 // Network input and output names
79 std::vector<std::string> input_names = GetBlobNames3DYolox(model_info.inputs());
80 std::vector<std::string> output_names = GetBlobNames3DYolox(model_info.outputs());
81
82 // Network type
83 const auto &framework = model_info.framework();
84 std::string plugin_name = model_info.infer_plugin();
85 static const std::string class_namespace = "apollo::perception::inference::";
86 if (model_info.has_infer_plugin() && !plugin_name.empty()) {
87 plugin_name = class_namespace + plugin_name;
89 plugin_name);
90 net_3D_->set_model_info(proto_file, input_names, output_names);
91 AINFO << "net_3D load plugin success: " << plugin_name;
92 } else {
94 framework, proto_file, weight_file, output_names, input_names, model_path));
95 }
96
97 ACHECK(net_3D_ != nullptr);
98 net_3D_->set_gpu_id(gpu_id_);
99 net_3D_->set_max_batch_size(max_batch_size_);
100
101 std::map<std::string, std::vector<int>> shape_map;
102 AddShape3DYolox(&shape_map, model_info.inputs());
103 AddShape3DYolox(&shape_map, model_info.outputs());
104
105 if (!net_3D_->Init(shape_map)) {
106 AERROR << model_info.name() << "init failed!";
107 return false;
108 }
109 return true;
110}
static PluginManager * Instance()
get singleton instance of PluginManager
std::shared_ptr< Base > CreateInstance(const std::string &derived_class)
create plugin instance of derived class based on Base
#define ACHECK(cond)
Definition log.h:80
#define AINFO
Definition log.h:42
void AddShape3DYolox(std::map< std::string, std::vector< int > > *shape_map, const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
std::vector< std::string > GetBlobNames3DYolox(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)
std::string GetModelFile(const std::string &model_name, const std::string &file_name)
Get the model file path by model path and file name
Definition util.cc:55

◆ LoadInputShape()

void apollo::perception::camera::Yolox3DObstacleDetector::LoadInputShape ( const yolox3d::ModelParam &  model_param)
protected

Resize model input picture size according to the config file

参数
model_paramyolox3d proto param read from yolox3d.pt
返回
None

在文件 yolox3d_obstacle_detector.cc 第 33 行定义.

33 {
34 // loading config params
35 width_ = model_param.resize().width();
36 height_ = model_param.resize().height();
37
38 image_width_ = options_.image_width;
39 image_height_ = options_.image_height;
40
41 AINFO << " image_height =" << image_height_ << ", image_width=" << image_width_ << ", height=" << height_
42 << ", width=" << width_;
43}

◆ LoadParam()

void apollo::perception::camera::Yolox3DObstacleDetector::LoadParam ( const yolox3d::ModelParam &  model_param)
protected

Load yolo libtorch model params from model file

参数
yolox3d_paramyolox3d proto param read from yolox3d.pt, include ModelParam、NetworkParam and NMSParam
返回
None

在文件 yolox3d_obstacle_detector.cc 第 45 行定义.

45 {
46 confidence_threshold_ = model_param.confidence_threshold();
47 border_ratio_ = model_param.border_ratio();
48
49 // Init NMS proto param by config file
50 const auto &nms_param = model_param.nms_param();
51 nms_.set_sigma(nms_param.sigma());
52 nms_.set_type(nms_param.type());
53 nms_.set_threshold(nms_param.threshold());
54}

◆ Name()

std::string apollo::perception::camera::Yolox3DObstacleDetector::Name ( ) const
inlineoverridevirtual

return detector name

参数
None
返回
now detector type

实现了 apollo::perception::camera::BaseObstacleDetector.

在文件 yolox3d_obstacle_detector.h 第 63 行定义.

63 {
64 return "Yolox3DObstacleDetector";
65 }

◆ Preprocess()

bool apollo::perception::camera::Yolox3DObstacleDetector::Preprocess ( const base::Image8U *  image,
base::BlobPtr< float >  input_blob 
)
protected

Preprocess of image before inference, resize input data blob and fill image data to blob

参数
imageimage read from camera frame of 6mm camera
input_blobimage input blob address pointer
返回
preprocess status

在文件 yolox3d_obstacle_detector.cc 第 320 行定义.

320 {
321 ACHECK(image != nullptr);
322 ACHECK(input_blob != nullptr);
323
324 // init cv img containter, same to image row and col
325 img_ = cv::Mat(image->rows(), image->cols(), CV_8UC3);
326 memcpy(img_.data, image->cpu_data(), image->rows() * image->cols() * image->channels() * sizeof(uint8_t));
327
328 // generate new pure black bg as same size as ratio
329 float ratio = std::max(image_width_, image_height_);
330 cv::Mat out(ratio, ratio, CV_8UC3, {114, 114, 114});
331
332 // pad to bottom
333 img_.copyTo(out(cv::Rect(0, 0, img_.cols, img_.rows)));
334
335 cv::resize(out, out, cv::Size(width_, height_), cv::INTER_LINEAR);
336
337 out.convertTo(out, CV_32F, 1.0);
338 // cv::imwrite("pics/yolox3d_pad_image.png", out);
339
340 int model_input_chs = out.channels();
341 int model_input_rows = out.rows;
342 int model_input_cols = out.cols;
343
344 // fill input_blob -> tensor_image will be used by model
345 input_blob->Reshape({1, model_input_chs, model_input_rows, model_input_cols});
346 float *input_data = input_blob->mutable_cpu_data();
347
348 for (int i = 0; i < model_input_chs; ++i) {
349 cv::extractChannel(
350 out,
351 cv::Mat(model_input_rows,
352 model_input_cols,
353 CV_32FC1,
354 input_data + i * model_input_rows * model_input_cols),
355 i);
356 }
357 return true;
358}

◆ Yolo3DInference()

void apollo::perception::camera::Yolox3DObstacleDetector::Yolo3DInference ( const base::Image8U *  image,
std::vector< base::ObjectPtr > &  detect_objs 
)
protected

Load yolo3D libtorch model params from model file

参数
image
detect_objs

在文件 yolox3d_obstacle_detector.cc 第 133 行定义.

133 {
134 ACHECK(image != nullptr);
135 // init input blobs data space
136 auto model_inputs = model_param_.info_3d().info().inputs();
137
138 auto input_blob_3d = net_3D_->get_blob(model_inputs[0].name());
139 ACHECK(input_blob_3d != nullptr);
140
141 int model_input_rows = 224;
142 int model_input_cols = 224;
143 int model_input_chs = 3;
144 // reshape max batch size
145 input_blob_3d->Reshape({max_batch_size_, model_input_chs, model_input_rows, model_input_cols});
146
147 // image preprocess
148 PERF_BLOCK("net_3D_ preprocess, batch_size: unknown")
149 for (int obj_id = 0; obj_id < (int)detect_objs.size(); obj_id++) {
150 float *input_data = input_blob_3d->mutable_cpu_data() + input_blob_3d->offset(obj_id);
151
152 if (obj_id >= max_batch_size_) {
153 AERROR << "The detected target in this frame is greater than max batch "
154 "size.";
155 AERROR << "which is max batch size " << max_batch_size_;
156 AERROR << "Abandon greater than part.";
157 continue;
158 }
159
160 auto obj = detect_objs[obj_id];
161 obj->camera_supplement.area_id = 1;
162
163 // get left top and right bottom point
164 float left_x = Yoloxclamp(obj->camera_supplement.box.xmin, 0.f, static_cast<float>(image->cols()));
165 float left_y = Yoloxclamp(obj->camera_supplement.box.ymin, 0.f, static_cast<float>(image->rows()));
166 float right_x = Yoloxclamp(obj->camera_supplement.box.xmax, 0.f, static_cast<float>(image->cols()));
167 float right_y = Yoloxclamp(obj->camera_supplement.box.ymax, 0.f, static_cast<float>(image->rows()));
168
169 float width = right_x - left_x;
170 float height = right_y - left_y;
171
172 cv::Rect object_roi(left_x, left_y, width, height);
173 cv::Mat cropped_obj = img_(object_roi);
174 // resize croped image to 224*224, no padding
175 cv::resize(cropped_obj, cropped_obj, cv::Size(224, 224));
176 cropped_obj.convertTo(cropped_obj, CV_32F, 1.0f / 255.0);
177
178 // BGR
179 std::vector<float> mean_values{0.406, 0.456, 0.485};
180 std::vector<float> std_values{0.225, 0.224, 0.229};
181
182 // normallize channel value from 0~255 to 0~1 and change it to float type
183 std::vector<cv::Mat> bgrChannels(3);
184 cv::split(cropped_obj, bgrChannels);
185 for (int i = 0; i < 3; ++i) {
186 bgrChannels[i].convertTo(
187 bgrChannels[i], CV_32FC1, 1 / std_values[i], (0.0 - mean_values[i]) / std_values[i]);
188 }
189 cv::Mat dst;
190 cv::merge(bgrChannels, dst);
191 cropped_obj = dst;
192
193 for (int i = 0; i < model_input_chs; ++i) {
194 // put img model_input_chs i data to input_blob
195 cv::extractChannel(
196 cropped_obj,
197 cv::Mat(model_input_rows,
198 model_input_cols,
199 CV_32FC1,
200 input_data + i * model_input_rows * model_input_cols),
201 i);
202 }
203 }
204 int total_objs = max_batch_size_ < (int)detect_objs.size() ? max_batch_size_ : (int)detect_objs.size();
205 // reshape real batch
206 input_blob_3d->Reshape({total_objs, model_input_chs, model_input_rows, model_input_cols});
207
208 // get model output
209 auto model_outputs = model_param_.info_3d().info().outputs();
210 auto blob_orient = net_3D_->get_blob(model_outputs[0].name()); // sin and cos 0~1
211 auto blob_conf = net_3D_->get_blob(model_outputs[1].name()); // front or back 0 or 1
212 auto blob_dim = net_3D_->get_blob(model_outputs[2].name()); // deviation value
213
214 // reshape dynamic output blob, for multibatch plugin
215 blob_orient->Reshape({total_objs, 1, 2, 2});
216 blob_conf->Reshape({total_objs, 1, 2, 1});
217 blob_dim->Reshape({total_objs, 1, 3, 1});
219
220 // run infer
221 PERF_BLOCK("net_3D_ infer, batch_size: " + std::to_string(total_objs))
222 net_3D_->Infer();
224
225 ACHECK(blob_orient != nullptr);
226 ACHECK(blob_conf != nullptr);
227 ACHECK(blob_dim != nullptr);
228
229 PERF_BLOCK("net_3D_ postprocess, batch_size: " + std::to_string(total_objs))
230 const int bin_number = model_param_.info_3d().bin_num();
231 // post processing
232 float border_ratio = 0.01;
233 int left_boundary = static_cast<int>(border_ratio * static_cast<float>(image->cols()));
234 int right_boundary = static_cast<int>((1.0f - border_ratio) * static_cast<float>(image->cols()));
235
236 for (int obj_id = 0; obj_id < total_objs; obj_id++) {
237 auto orient_data = blob_orient->mutable_cpu_data() + blob_orient->offset(obj_id);
238 auto conf_data = blob_conf->mutable_cpu_data() + blob_conf->offset(obj_id);
239 auto dim_data = blob_dim->mutable_cpu_data() + blob_dim->offset(obj_id);
240 auto &obj = detect_objs[obj_id];
241
242 int max_index = 0;
243 int max_conf = conf_data[max_index];
244 for (int i = 1; i < bin_number; ++i) {
245 if (conf_data[i] > max_conf) {
246 max_conf = conf_data[i];
247 max_index = i;
248 }
249 }
250
251 int orient_index = 2 * max_index;
252 float alpha = 0.f;
253 float cos_result = orient_data[orient_index];
254 float sin_result = orient_data[orient_index + 1];
255 float angle_offset = std::atan2(sin_result, cos_result);
256
257 float wedge = 2 * M_PI / bin_number;
258 alpha = angle_offset + max_index * wedge;
259 alpha = alpha + wedge / 2 - M_PI;
260 if (alpha > M_PI) {
261 alpha -= 2 * M_PI;
262 }
263 obj->camera_supplement.alpha = alpha;
264
265 // add dim to object here
266 obj->size[0] += dim_data[2];
267 obj->size[1] += dim_data[1];
268 obj->size[2] += dim_data[0];
269
270 // clear cut off ratios
271 auto &box = obj->camera_supplement.box;
272 if (box.xmin >= left_boundary) {
273 obj->camera_supplement.cut_off_ratios[2] = 0;
274 }
275 if (box.xmax <= right_boundary) {
276 obj->camera_supplement.cut_off_ratios[3] = 0;
277 }
278 }
280 return;
281}
uint32_t height
Height of point cloud
uint32_t width
Width of point cloud
constexpr T Yoloxclamp(const T &val, const T &low, const T &high)
Clamp target value between low and high tools for iou

该类的文档由以下文件生成: