133 {
135
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
145 input_blob_3d->Reshape({max_batch_size_, model_input_chs, model_input_rows, model_input_cols});
146
147
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
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
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
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
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
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
206 input_blob_3d->Reshape({total_objs, model_input_chs, model_input_rows, model_input_cols});
207
208
209 auto model_outputs = model_param_.
info_3d().
info().outputs();
210 auto blob_orient = net_3D_->get_blob(model_outputs[0].name());
211 auto blob_conf = net_3D_->get_blob(model_outputs[1].name());
212 auto blob_dim = net_3D_->get_blob(model_outputs[2].name());
213
214
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
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))
231
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
266 obj->size[0] += dim_data[2];
267 obj->size[1] += dim_data[1];
268 obj->size[2] += dim_data[0];
269
270
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