28namespace trafficlight {
34 BASE_GPU_CHECK(cudaSetDevice(gpu_id_));
35 BASE_GPU_CHECK(cudaStreamCreate(&stream_));
42 scale_ = model_param_.
scale();
44 float* p = mean_->mutable_cpu_data();
45 if (model_param_.
is_bgr()) {
47 p[0] = model_param_.
mean_b();
48 p[1] = model_param_.
mean_g();
49 p[2] = model_param_.
mean_r();
52 p[0] = model_param_.
mean_r();
53 p[1] = model_param_.
mean_g();
54 p[2] = model_param_.
mean_b();
56 std::vector<int> shape = {1, 3, resize_height_, resize_width_};
61 AERROR <<
"Init model error.";
70bool EfficientNetRecognition::InitModel() {
72 std::map<std::string, std::vector<int>> blob_maps;
73 auto model_info = model_param_.
info();
75 std::string model_path =
GetModelPath(model_info.name());
76 std::string onnx_file =
GetModelFile(model_path, model_info.proto_file().file());
80 "apollo::perception::inference::" + model_info.infer_plugin());
81 inference_->set_model_info(onnx_file, input_names, output_names);
82 inference_->set_gpu_id(gpu_id_);
88 inference_->Init(blob_maps);
91 if (input_names.size() == 1) {
92 input_blob_ = inference_->get_blob(input_names.at(0));
93 CHECK_NOTNULL(input_blob_.get());
95 AERROR <<
"Init inferece input blob error.";
99 if (output_names.size() == 2) {
100 outputs_cls_ = inference_->get_blob(output_names.at(0));
101 outputs_status_ = inference_->get_blob(output_names.at(1));
102 CHECK_NOTNULL(outputs_cls_.get());
103 CHECK_NOTNULL(outputs_status_.get());
105 AERROR <<
"Init inferece output blob error.";
114 AINFO <<
"No recognizable traffic lights";
117 std::vector<base::TrafficLightPtr> candidate;
121 if (light->region.is_detected) {
122 candidate.push_back(light);
125 light->status.confidence = 0;
129 Perform(frame, &candidate);
134void EfficientNetRecognition::Perform(
136 std::vector<base::TrafficLightPtr>* lights) {
138 input_blob_->Reshape({lights->size(), 3, resize_height_, resize_width_});
140 outputs_cls_->Reshape({lights->size(), 4});
141 outputs_status_->Reshape({lights->size(), 1});
146 if (!light->region.is_detected) {
150 data_provider_image_option_.
crop_roi = light->region.detection_roi;
151 data_provider_image_option_.
do_crop =
true;
153 frame->
data_provider->GetImage(data_provider_image_option_, image_.get());
154 AINFO <<
"get img done";
156 base::Image8U roi_tmp_image;
161 ZeroPadding(light->region.detection_roi, &roi_tmp_image, &dst_width, &dst_height, provider_w, provider_h);
163 const float* mean = mean_.get()->cpu_data();
167 roi_tmp_image.cols(),
175 AINFO <<
"resize gpu finish.";
177 PERF_BLOCK(
"traffic_light_recognition_inference")
180 AINFO << "infer finish.";
183 for (base::TrafficLightPtr light : *lights) {
184 if (!light->region.is_detected) {
188 float* output_data = outputs_cls_->mutable_cpu_data() + outputs_cls_->offset(valid_index);
190 Prob2Color(output_data, unknown_threshold_, light);
195void EfficientNetRecognition::ZeroPadding(
197 base::Image8U* roi_tmp_image,
200 const int& provider_w,
201 const int& provider_h) {
202 int roi_width = light_roi.width;
203 int roi_height = light_roi.height;
204 int max_len = std::max(roi_height, roi_width);
205 int min_len = std::min(roi_height, roi_width);
206 float edge_ratio =
static_cast<float>(max_len) /
static_cast<float>(min_len);
212 if (edge_ratio > 1.4 && roi_height > roi_width) {
213 pad_left = (roi_height - roi_width) / 2;
214 pad_right = roi_height - roi_width - pad_left;
215 }
else if (edge_ratio > 1.4 && roi_width > roi_height) {
216 pad_up = (roi_width - roi_height) / 2;
217 pad_down = roi_width - roi_height - pad_up;
219 int height_dis = (max_len - roi_height) / 2;
220 int width_dis = (max_len - roi_width) / 2;
221 pad_up = max_len + height_dis;
222 pad_down = 3 * max_len - roi_height - pad_up;
223 pad_left = max_len + width_dis;
224 pad_right = 3 * max_len - roi_width - pad_left;
226 *dst_height = roi_height + pad_up + pad_down;
227 *dst_width = roi_width + pad_left + pad_right;
228 if (*dst_height > provider_h) {
229 int dist = *dst_height - provider_h;
230 pad_up = pad_up - dist / 2 - 1;
231 pad_down = pad_down - dist / 2 - 1;
233 if (*dst_width > provider_w) {
234 int dist = *dst_width - provider_w;
235 pad_left = pad_left - dist / 2 - 1;
236 pad_right = pad_right - dist / 2 - 1;
239 *dst_height = roi_height + pad_up + pad_down;
240 *dst_width = roi_width + pad_left + pad_right;
242 float scale = resize_width_ * 1.0 / *dst_width;
244 *image_, roi_tmp_image, provider_w, pad_left, pad_right, pad_up, pad_down, 0, stream_,
true);
247void EfficientNetRecognition::Prob2Color(
const float* output_data,
float threshold,
base::TrafficLightPtr light) {
248 int max_color_id = 0;
249 std::vector<base::TLColor> status_map
251 std::vector<std::string> name_map = {
"Black",
"Red",
"Yellow",
"Green"};
252 std::vector<float> prob(output_data, output_data + status_map.size());
253 auto max_prob = std::max_element(prob.begin(), prob.end());
254 max_color_id = (*max_prob >
threshold) ?
static_cast<int>(std::distance(prob.begin(), max_prob)) : 0;
255 light->status.color = status_map[max_color_id];
256 light->status.confidence = output_data[max_color_id];
257 AINFO <<
"Light status recognized as " << name_map[max_color_id];
258 AINFO <<
"Color Prob:";
259 for (
size_t j = 0; j < status_map.size(); j++) {
260 AINFO << output_data[j];
#define REGISTER_TRAFFIC_LIGHT_DETECTOR(name)
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
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
A wrapper around Blob holders serving as the basic computational unit for images.
bool Init(const TrafficLightRecognitorInitOptions &options) override
Initialize traffic light recognitor parameters.
bool Detect(camera::TrafficLightFrame *frame) override
recogn traffic_light from image.
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,...
std::shared_ptr< TrafficLight > TrafficLightPtr
std::vector< std::string > GetBlobNames(const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
bool ImageZeroPadding(const base::Image8U &src, base::Image8U *dst, int stepwidth, int left_pad, int right_pad, int top_pad, int bottom_pad, int value, cudaStream_t stream, bool same_order)
void AddShape(std::map< std::string, std::vector< int > > *shape_map, const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
bool ResizeGPU(const base::Image8U &src, std::shared_ptr< apollo::perception::base::Blob< float > > dst, int stepwidth, int start_axis)
Image< uchar > * threshold(Image< T > *src, int t)
Threshold image
std::string GetModelFile(const std::string &model_name, const std::string &file_name)
Get the model file path by model path and file name
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
std::string GetModelPath(const std::string &model_name)
Get the model path by model name, search from APOLLO_MODEL_PATH
std::vector< base::TrafficLightPtr > traffic_lights
std::shared_ptr< camera::DataProvider > data_provider
optional int32 classify_resize_height
optional float classify_threshold
optional int32 classify_resize_width
optional common::ModelInfo info
optional int32 max_batch_size