Apollo 11.0
自动驾驶开放平台
efficient_net.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 *****************************************************************************/
16
18
19#include "cyber/common/file.h"
21
25
26namespace apollo {
27namespace perception {
28namespace trafficlight {
29
31
33 gpu_id_ = options.gpu_id;
34 BASE_GPU_CHECK(cudaSetDevice(gpu_id_));
35 BASE_GPU_CHECK(cudaStreamCreate(&stream_));
36
37 std::string config_file = GetConfigFile(options.config_path, options.config_file);
38 ACHECK(apollo::cyber::common::GetProtoFromFile(config_file, &model_param_));
39 resize_height_ = model_param_.classify_resize_height();
40 resize_width_ = model_param_.classify_resize_width();
41 unknown_threshold_ = model_param_.classify_threshold();
42 scale_ = model_param_.scale();
43 mean_.reset(new base::Blob<float>(1, 3, 1, 1));
44 float* p = mean_->mutable_cpu_data();
45 if (model_param_.is_bgr()) {
46 data_provider_image_option_.target_color = base::Color::BGR;
47 p[0] = model_param_.mean_b();
48 p[1] = model_param_.mean_g();
49 p[2] = model_param_.mean_r();
50 } else {
51 data_provider_image_option_.target_color = base::Color::RGB;
52 p[0] = model_param_.mean_r();
53 p[1] = model_param_.mean_g();
54 p[2] = model_param_.mean_b();
55 }
56 std::vector<int> shape = {1, 3, resize_height_, resize_width_};
57 mean_buffer_.reset(new base::Blob<float>(shape));
58
59 // Init model
60 if (!InitModel()) {
61 AERROR << "Init model error.";
62 return false;
63 }
64 // image data
65 image_.reset(new base::Image8U(resize_height_, resize_width_, base::Color::BGR));
66
67 return true;
68}
69
70bool EfficientNetRecognition::InitModel() {
71 // name:blob maps
72 std::map<std::string, std::vector<int>> blob_maps;
73 auto model_info = model_param_.info();
74 // efficientnet model file
75 std::string model_path = GetModelPath(model_info.name());
76 std::string onnx_file = GetModelFile(model_path, model_info.proto_file().file());
77 std::vector<std::string> input_names = inference::GetBlobNames(model_info.inputs());
78 std::vector<std::string> output_names = inference::GetBlobNames(model_info.outputs());
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_);
83 inference_->set_max_batch_size(model_param_.max_batch_size() * 2);
84
85 inference::AddShape(&blob_maps, model_info.inputs());
86 inference::AddShape(&blob_maps, model_info.outputs());
87
88 inference_->Init(blob_maps);
89
90 // init input blob
91 if (input_names.size() == 1) {
92 input_blob_ = inference_->get_blob(input_names.at(0));
93 CHECK_NOTNULL(input_blob_.get());
94 } else {
95 AERROR << "Init inferece input blob error.";
96 return false;
97 }
98 // init output blobs
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());
104 } else {
105 AERROR << "Init inferece output blob error.";
106 return false;
107 }
108
109 return true;
110}
111
113 if (frame->traffic_lights.size() <= 0) {
114 AINFO << "No recognizable traffic lights";
115 return true;
116 }
117 std::vector<base::TrafficLightPtr> candidate;
118 candidate.reserve(frame->traffic_lights.size());
119 // get traffic light region
120 for (base::TrafficLightPtr light : frame->traffic_lights) {
121 if (light->region.is_detected) {
122 candidate.push_back(light);
123 } else {
124 light->status.color = base::TLColor::TL_UNKNOWN_COLOR;
125 light->status.confidence = 0;
126 }
127 }
128 // classify color
129 Perform(frame, &candidate);
130
131 return true;
132}
133
134void EfficientNetRecognition::Perform(
135 const camera::TrafficLightFrame* frame,
136 std::vector<base::TrafficLightPtr>* lights) {
137 // input reshape
138 input_blob_->Reshape({lights->size(), 3, resize_height_, resize_width_});
139 // output shape
140 outputs_cls_->Reshape({lights->size(), 4});
141 outputs_status_->Reshape({lights->size(), 1});
142
143 // classify
144 int valid_index = 0;
145 for (base::TrafficLightPtr light : *lights) {
146 if (!light->region.is_detected) {
147 continue;
148 }
149 // get image
150 data_provider_image_option_.crop_roi = light->region.detection_roi;
151 data_provider_image_option_.do_crop = true;
152 data_provider_image_option_.target_color = base::Color::BGR;
153 frame->data_provider->GetImage(data_provider_image_option_, image_.get());
154 AINFO << "get img done";
155 // image zero padding
156 base::Image8U roi_tmp_image;
157 int dst_height = 0;
158 int dst_width = 0;
159 int provider_w = frame->data_provider->src_width();
160 int provider_h = frame->data_provider->src_height();
161 ZeroPadding(light->region.detection_roi, &roi_tmp_image, &dst_width, &dst_height, provider_w, provider_h);
162 // image reshape
163 const float* mean = mean_.get()->cpu_data();
165 roi_tmp_image,
166 input_blob_,
167 roi_tmp_image.cols(),
168 valid_index,
169 mean[0],
170 mean[1],
171 mean[2],
172 false,
173 scale_);
174 valid_index += 1;
175 AINFO << "resize gpu finish.";
176 }
177 PERF_BLOCK("traffic_light_recognition_inference")
178 inference_->Infer();
180 AINFO << "infer finish.";
181
182 valid_index = 0; // reset to 0
183 for (base::TrafficLightPtr light : *lights) {
184 if (!light->region.is_detected) {
185 continue;
186 }
187 // get output result
188 float* output_data = outputs_cls_->mutable_cpu_data() + outputs_cls_->offset(valid_index);
189 // float *output_status_data = outputs_status_->mutable_cpu_data();
190 Prob2Color(output_data, unknown_threshold_, light);
191 valid_index += 1;
192 }
193}
194
195void EfficientNetRecognition::ZeroPadding(
196 const base::RectI& light_roi,
197 base::Image8U* roi_tmp_image,
198 int* dst_width,
199 int* dst_height,
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);
207
208 int pad_left = 0;
209 int pad_right = 0;
210 int pad_up = 0;
211 int pad_down = 0;
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;
218 } else {
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;
225 }
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;
232 }
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;
237 }
238
239 *dst_height = roi_height + pad_up + pad_down;
240 *dst_width = roi_width + pad_left + pad_right;
241 *roi_tmp_image = base::Image8U(*dst_height, *dst_width, base::Color::BGR);
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);
245}
246
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];
261 }
262}
263
265
266} // namespace trafficlight
267} // namespace perception
268} // namespace apollo
#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,...
Definition blob.h:88
A wrapper around Blob holders serving as the basic computational unit for images.
Definition image_8u.h:44
bool Init(const TrafficLightRecognitorInitOptions &options) override
Initialize traffic light recognitor parameters.
bool Detect(camera::TrafficLightFrame *frame) override
recogn traffic_light from image.
#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
Rect< int > RectI
Definition box.h:159
std::shared_ptr< TrafficLight > TrafficLightPtr
std::vector< std::string > GetBlobNames(const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
Definition model_util.cc:23
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)
Definition model_util.cc:32
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
Definition imutil.h:79
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
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
#define PERF_BLOCK_END
Definition profiler.h:53
#define PERF_BLOCK(...)
Definition profiler.h:52
std::vector< base::TrafficLightPtr > traffic_lights
std::shared_ptr< camera::DataProvider > data_provider