166 {
167 if (frame == nullptr) {
168 AINFO <<
"camera frame is empty.";
169 return false;
170 }
171
172 auto start = std::chrono::high_resolution_clock::now();
173 auto data_provider = frame->data_provider;
174 if (input_width_ != data_provider->src_width()) {
175 AERROR <<
"Input size is not correct: " << input_width_ <<
" vs "
176 << data_provider->src_width();
177 return false;
178 }
179 if (input_height_ != data_provider->src_height()) {
180 AERROR <<
"Input size is not correct: " << input_height_ <<
" vs "
181 << data_provider->src_height();
182 return false;
183 }
184
185
186 if (!data_provider->GetImage(data_provider_image_option_, &image_src_)) {
187 return false;
188 }
189
190
191 auto input_blob = cnnadapter_lane_->get_blob(net_inputs_[0]);
192 auto blob_channel = input_blob->channels();
193 auto blob_height = input_blob->height();
194 auto blob_width = input_blob->width();
195 ADEBUG <<
"input_blob: " << blob_channel <<
" " << blob_height <<
" "
196 << blob_width << std::endl;
197
198 if (blob_height != resize_height_) {
199 AERROR <<
"height is not equal" << blob_height <<
" vs " << resize_height_;
200 return false;
201 }
202 if (blob_width != resize_width_) {
203 AERROR <<
"width is not equal" << blob_width <<
" vs " << resize_width_;
204 return false;
205 }
206 ADEBUG <<
"image_blob: " << image_src_.
blob()->shape_string();
207 ADEBUG <<
"input_blob: " << input_blob->shape_string();
208
210 image_src_, input_blob, static_cast<int>(crop_width_), 0,
211 static_cast<float>(image_mean_[0]), static_cast<float>(image_mean_[1]),
212 static_cast<float>(image_mean_[2]), false, static_cast<float>(1.0));
213 ADEBUG <<
"resize gpu finish.";
214 cudaDeviceSynchronize();
215 cnnadapter_lane_->Infer();
216 ADEBUG <<
"infer finish.";
217
218 auto elapsed_1 = std::chrono::high_resolution_clock::now() - start;
219 int64_t microseconds_1 =
220 std::chrono::duration_cast<std::chrono::microseconds>(elapsed_1).count();
221 time_1 += microseconds_1;
222
223
224 const auto seg_blob = cnnadapter_lane_->get_blob(net_outputs_[0]);
225 ADEBUG <<
"seg_blob: " << seg_blob->shape_string();
226 std::vector<cv::Mat> masks;
227 for (int i = 0; i < num_lanes_; ++i) {
228 cv::Mat tmp(lane_output_height_, lane_output_width_, CV_32FC1);
229 memcpy(tmp.data,
230 seg_blob->cpu_data() + lane_output_width_ * lane_output_height_ * i,
231 lane_output_width_ * lane_output_height_ * sizeof(float));
232
233
234
235 masks.push_back(tmp);
236 }
237 std::vector<int> cnt_pixels(13, 0);
238 cv::Mat mask_color(lane_output_height_, lane_output_width_, CV_32FC1);
239 mask_color.setTo(cv::Scalar(0));
240 for (int c = 0; c < num_lanes_; ++c) {
241 for (int h = 0; h < masks[c].rows; ++h) {
242 for (int w = 0; w < masks[c].cols; ++w) {
243 if (masks[c].at<float>(h, w) >= confidence_threshold_lane_) {
244 mask_color.at<float>(h, w) = static_cast<float>(c);
245 cnt_pixels[c]++;
246 }
247 }
248 }
249 }
250 memcpy(lane_blob_->mutable_cpu_data(),
251 reinterpret_cast<float *>(mask_color.data),
252 lane_output_width_ * lane_output_height_ * sizeof(float));
253
254
255 frame->lane_detected_blob = lane_blob_;
256
257
258 if (net_outputs_.size() > 1) {
259 const auto vpt_blob = cnnadapter_lane_->get_blob(net_outputs_[1]);
260 ADEBUG <<
"vpt_blob: " << vpt_blob->shape_string();
261 std::vector<float> v_point(2, 0);
262 std::copy(vpt_blob->cpu_data(), vpt_blob->cpu_data() + 2, v_point.begin());
263
264 v_point[0] = v_point[0] * vpt_std_[0] + vpt_mean_[0] +
265 (static_cast<float>(blob_width) / 2);
266 v_point[1] = v_point[1] * vpt_std_[1] + vpt_mean_[1] +
267 (static_cast<float>(blob_height) / 2);
268
269 v_point[0] = v_point[0] / static_cast<float>(blob_width) *
270 static_cast<float>(crop_width_) +
271 static_cast<float>(input_offset_x_);
272 v_point[1] = v_point[1] / static_cast<float>(blob_height) *
273 static_cast<float>(crop_height_) +
274 static_cast<float>(input_offset_y_);
275
276 ADEBUG <<
"vanishing point: " << v_point[0] <<
" " << v_point[1];
277 if (v_point[0] > 0 && v_point[0] < static_cast<float>(input_width_) &&
278 v_point[1] > 0 && v_point[0] < static_cast<float>(input_height_)) {
279 frame->pred_vpt = v_point;
280 }
281 }
282
283 auto elapsed_2 = std::chrono::high_resolution_clock::now() - start;
284 int64_t microseconds_2 =
285 std::chrono::duration_cast<std::chrono::microseconds>(elapsed_2).count();
286 time_2 += microseconds_2 - microseconds_1;
287
288 time_num += 1;
289 ADEBUG <<
"Avg detection infer time: " << time_1 / time_num
290 << " Avg detection merge output time: " << time_2 / time_num;
291 ADEBUG <<
"Lane detection done!";
292 return true;
293}
std::shared_ptr< Blob< uint8_t > > blob()
bool ResizeGPU(const base::Image8U &src, std::shared_ptr< apollo::perception::base::Blob< float > > dst, int stepwidth, int start_axis)