Apollo 10.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
 Detect stage
 
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 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, base::ObjectPtr obj)
 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)
 
 DISALLOW_COPY_AND_ASSIGN (BaseObstacleDetector)
 

额外继承的成员函数

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

详细描述

在文件 yolox3d_obstacle_detector.h39 行定义.

构造及析构函数说明

◆ Yolox3DObstacleDetector()

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

◆ ~Yolox3DObstacleDetector()

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

在文件 yolox3d_obstacle_detector.h42 行定义.

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

成员函数说明

◆ Detect()

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

Detect stage

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

在文件 yolox3d_obstacle_detector.cc340 行定义.

340 {
341 if (frame == nullptr) {
342 return false;
343 }
344
345 if (cudaSetDevice(gpu_id_) != cudaSuccess) {
346 AERROR << "Failed to set device to " << gpu_id_;
347 return false;
348 }
349
350 auto model_inputs = model_param_.info().inputs();
351 auto input_blob_2d = net_->get_blob(model_inputs[0].name());
352
353 // use bgr to infer
354 DataProvider::ImageOptions image_options;
355 image_options.target_color = base::Color::BGR;
356
357 base::Image8U image;
358 frame->data_provider->GetImage(image_options, &image);
359
360 // cpu preprocess
361 PERF_BLOCK("2d image preprocess time: ")
362 Preprocess(&image, input_blob_2d);
364
365 // model infer, save to output blob
366 PERF_BLOCK("2d infer time: ")
367 net_->Infer();
369
370 // get objects from network inference result
371 auto model_outputs = model_param_.info().outputs();
372
373 // Attention(lordon): onnx predict blob is 1, pth is 0
374 auto predict_blob = net_->get_blob(model_outputs[1].name());
375 frame->feature_blob = net_->get_blob(model_outputs[0].name());
376
377 PERF_BLOCK("2d postprocess stage: ")
378 YoloxGetObjectsCpu(predict_blob, model_param_, nms_, width_, height_,
379 image_width_, image_height_, &frame->detected_objects);
381
382 // post processing
383 float border_ratio = 0.01;
384 int left_boundary =
385 static_cast<int>(border_ratio * static_cast<float>(image.cols()));
386 int right_boundary = static_cast<int>((1.0f - border_ratio) *
387 static_cast<float>(image.cols()));
388 for (auto &obj : frame->detected_objects) {
389 obj->camera_supplement.area_id = 1;
390
391 PERF_BLOCK("3d process of per object: ")
392 Yolo3DInference(&image, obj);
394
395 // clear cut off ratios
396 auto &box = obj->camera_supplement.box;
397 if (box.xmin >= left_boundary) {
398 obj->camera_supplement.cut_off_ratios[2] = 0;
399 }
400 if (box.xmax <= right_boundary) {
401 obj->camera_supplement.cut_off_ratios[3] = 0;
402 }
403 }
404
405 return true;
406}
double f
std::shared_ptr< inference::Inference > net_
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 Yolo3DInference(const base::Image8U *image, base::ObjectPtr obj)
Load yolo3D libtorch model params from model file
#define AERROR
Definition log.h:44
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
#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.cc259 行定义.

259 {
260 options_ = options;
261
262 gpu_id_ = options.gpu_id;
263 BASE_GPU_CHECK(cudaSetDevice(gpu_id_));
264 BASE_GPU_CHECK(cudaStreamCreate(&stream_));
265
266 std::string config_file =
267 GetConfigFile(options.config_path, options.config_file);
268 if (!cyber::common::GetProtoFromFile(config_file, &model_param_)) {
269 AERROR << "Read proto_config failed! " << config_file;
270 return false;
271 }
272
273 LoadInputShape(model_param_);
274 LoadParam(model_param_);
275
276 const auto &model_info = model_param_.info();
277 std::string model_path = GetModelPath(model_info.name());
278 if (!InitNetwork(model_info, model_path)) {
279 AERROR << "Init network failed!";
280 return false;
281 }
282 net_->Infer();
283 AINFO << "yolox3d 2D model init success";
284 std::cout << "yolox3d 2D model init success " << std::endl;
285
286 const auto &model_info_3d = model_param_.info_3d().info();
287 std::string model_path_3d = GetModelPath(model_info_3d.name());
288 if (!Init3DNetwork(model_info_3d, model_path_3d)) {
289 AERROR << "Init network failed!";
290 return false;
291 }
292 net_3D_->Infer();
293 AINFO << "yolox3d 3D model init success";
294 std::cout << "yolox3d 3D model init success " << std::endl;
295
296 return true;
297}
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
#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
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.cc76 行定义.

77 {
78 // Network files
79 std::string proto_file =
80 GetModelFile(model_path, model_info.proto_file().file());
81 std::string weight_file =
82 GetModelFile(model_path, model_info.weight_file().file());
83
84 // Network input and output names
85 std::vector<std::string> input_names =
86 GetBlobNames3DYolox(model_info.inputs());
87 std::vector<std::string> output_names =
88 GetBlobNames3DYolox(model_info.outputs());
89
90 // Network type
91 const auto &framework = model_info.framework();
92 std::string plugin_name = model_info.infer_plugin();
93 static const std::string class_namespace = "apollo::perception::inference::";
94 if (model_info.has_infer_plugin() && !plugin_name.empty()) {
95 plugin_name = class_namespace + plugin_name;
97 ->CreateInstance<inference::Inference>(plugin_name);
98 net_3D_->set_model_info(proto_file, input_names, output_names);
99 AINFO << "net_3D load plugin success: " << plugin_name;
100 } else {
101 net_3D_.reset(inference::CreateInferenceByName(framework, proto_file,
102 weight_file, output_names,
103 input_names, model_path));
104 }
105
106 ACHECK(net_3D_ != nullptr);
107 net_3D_->set_gpu_id(gpu_id_);
108
109 std::map<std::string, std::vector<int>> shape_map;
110 AddShape3DYolox(&shape_map, model_info.inputs());
111 AddShape3DYolox(&shape_map, model_info.outputs());
112
113 if (!net_3D_->Init(shape_map)) {
114 AERROR << model_info.name() << "init failed!";
115 return false;
116 }
117 return true;
118}
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
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.cc32 行定义.

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_
42 << ", image_width=" << image_width_ << ", resize height=" << height_
43 << ", width=" << width_;
44}

◆ 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.cc46 行定义.

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

◆ Name()

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

return detector name

参数
None
返回
now detector type

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

在文件 yolox3d_obstacle_detector.h68 行定义.

68{ return "Yolox3DObstacleDetector"; }

◆ 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.cc299 行定义.

300 {
301 ACHECK(image != nullptr);
302 ACHECK(input_blob != nullptr);
303
304 // init cv img containter, same to image row and col
305 img_ = cv::Mat(image->rows(), image->cols(), CV_8UC3);
306 memcpy(img_.data, image->cpu_data(),
307 image->rows() * image->cols() * image->channels() * sizeof(uint8_t));
308
309 // generate new pure black bg as same size as ratio
310 float ratio = std::max(image_width_, image_height_);
311 cv::Mat out(ratio, ratio, CV_8UC3, {114, 114, 114}); // 114 sames to yolox3d
312
313 img_.copyTo(out(cv::Rect(0, 0, img_.cols,
314 img_.rows))); // pad to bottom, sames to yolox3d
315
316 cv::resize(out, out, cv::Size(width_, height_),
317 cv::INTER_LINEAR); // use INTER_LINEAR, sames to yolox3d
318
319 out.convertTo(out, CV_32F, 1.0); // without normalize, sames to yolox3d
320 // cv::imwrite("pics/yolox3d_pad_image.png", out);
321
322 int model_input_chs = out.channels();
323 int model_input_rows = out.rows;
324 int model_input_cols = out.cols;
325
326 // fill input_blob -> tensor_image will be used by model
327 input_blob->Reshape({1, model_input_chs, model_input_rows, model_input_cols});
328 float *input_data = input_blob->mutable_cpu_data();
329
330 for (int i = 0; i < model_input_chs; ++i) {
331 cv::extractChannel(
332 out,
333 cv::Mat(model_input_rows, model_input_cols, CV_32FC1,
334 input_data + i * model_input_rows * model_input_cols),
335 i);
336 }
337 return true;
338}

◆ Yolo3DInference()

void apollo::perception::camera::Yolox3DObstacleDetector::Yolo3DInference ( const base::Image8U image,
base::ObjectPtr  obj 
)
protected

Load yolo3D libtorch model params from model file

参数
image
obj
返回
None

在文件 yolox3d_obstacle_detector.cc144 行定义.

145 {
146 ACHECK(image != nullptr);
147
148 // get left top and right bottom point
149 float left_x = Yoloxclamp(obj->camera_supplement.box.xmin, 0.f,
150 static_cast<float>(image->cols()));
151 float left_y = Yoloxclamp(obj->camera_supplement.box.ymin, 0.f,
152 static_cast<float>(image->rows()));
153 float right_x = Yoloxclamp(obj->camera_supplement.box.xmax, 0.f,
154 static_cast<float>(image->cols()));
155 float right_y = Yoloxclamp(obj->camera_supplement.box.ymax, 0.f,
156 static_cast<float>(image->rows()));
157
158 // get width and height of object
159 float width = right_x - left_x;
160 float height = right_y - left_y;
161
162 // crop object
163 cv::Rect object_roi(left_x, left_y, width, height);
164 cv::Mat cropped_obj = img_(object_roi);
165
166 // resize croped image to 224*224, no padding
167 // cropped_obj =
168 // resizeKeepAspectRatioYolox(cropped_obj, cv::Size(224, 224), {0, 0, 0});
169 cv::resize(cropped_obj, cropped_obj, cv::Size(224, 224));
170
171 // normallize channel value from 0~255 to 0~1 and change it to float type
172 cropped_obj.convertTo(cropped_obj, CV_32F, 1.0f / 255.0);
173
174 // BGR
175 std::vector<float> mean_values{0.406, 0.456, 0.485};
176 std::vector<float> std_values{0.225, 0.224, 0.229};
177
178 std::vector<cv::Mat> bgrChannels(3);
179 cv::split(cropped_obj, bgrChannels);
180 for (int i = 0; i < 3; ++i) {
181 bgrChannels[i].convertTo(bgrChannels[i], CV_32FC1, 1 / std_values[i],
182 (0.0 - mean_values[i]) / std_values[i]);
183 }
184 cv::Mat dst;
185 cv::merge(bgrChannels, dst);
186 cropped_obj = dst;
187
188 auto model_inputs = model_param_.info_3d().info().inputs();
189
190 auto input_blob_3d = net_3D_->get_blob(model_inputs[0].name());
191
192 ACHECK(input_blob_3d != nullptr);
193
194 int model_input_chs = cropped_obj.channels();
195 int model_input_rows = cropped_obj.rows;
196 int model_input_cols = cropped_obj.cols;
197 float *input_data = input_blob_3d->mutable_cpu_data();
198
199 // copy to blob
200 input_blob_3d->Reshape(
201 {1, model_input_chs, model_input_rows, model_input_cols});
202 for (int i = 0; i < model_input_chs; ++i) {
203 cv::extractChannel(
204 cropped_obj,
205 cv::Mat(model_input_rows, model_input_cols, CV_32FC1,
206 input_data + i * model_input_rows * model_input_cols),
207 i);
208 }
209
210 // 3D model infer
211 net_3D_->Infer();
212
213 // get results
214 auto model_outputs = model_param_.info_3d().info().outputs();
215 auto blob_orient = net_3D_->get_blob(model_outputs[0].name());
216 auto blob_conf = net_3D_->get_blob(model_outputs[1].name());
217 auto blob_dim = net_3D_->get_blob(model_outputs[2].name());
218
219 ACHECK(blob_orient != nullptr);
220 ACHECK(blob_conf != nullptr);
221 ACHECK(blob_dim != nullptr);
222
223 const float *orient_data = blob_orient->cpu_data();
224 const float *conf_data = blob_conf->cpu_data();
225 const float *dim_data = blob_dim->cpu_data();
226
227 // recover to alpha according to bin number
228 const int bin_number = model_param_.info_3d().bin_num();
229 int max_index = 0;
230 int max_conf = conf_data[max_index];
231 for (int i = 1; i < bin_number; ++i) {
232 if (conf_data[i] > max_conf) {
233 max_conf = conf_data[i];
234 max_index = i;
235 }
236 }
237
238 int orient_index = 2 * max_index;
239 float alpha = 0.f;
240 float cos_result = orient_data[orient_index];
241 float sin_result = orient_data[orient_index + 1];
242 float angle_offset = std::atan2(sin_result, cos_result);
243
244 float wedge = 2 * M_PI / bin_number;
245 alpha = angle_offset + max_index * wedge;
246 alpha = alpha + wedge / 2 - M_PI;
247 if (alpha > M_PI) {
248 alpha -= 2 * M_PI;
249 }
250 obj->camera_supplement.alpha = alpha;
251
252 // add dim to object template
253 obj->size[0] += dim_data[2];
254 obj->size[1] += dim_data[1];
255 obj->size[2] += dim_data[0];
256 return;
257}
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

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