31 intersect_bbox->
xmin = 0;
32 intersect_bbox->
ymin = 0;
33 intersect_bbox->
xmax = 0;
34 intersect_bbox->
ymax = 0;
52 float height = bbox.
ymax - bbox.
ymin;
53 return width * height;
62 float intersect_width = 0.f;
63 float intersect_height = 0.f;
64 intersect_width = intersect_bbox.
xmax - intersect_bbox.
xmin;
65 intersect_height = intersect_bbox.
ymax - intersect_bbox.
ymin;
67 if (intersect_width > 0 && intersect_height > 0) {
68 float intersect_size = intersect_width * intersect_height;
71 return intersect_size / (bbox1_size + bbox2_size - intersect_size);
78 const float threshold,
const int top_k,
79 std::vector<std::pair<float, int>> *score_index_vec) {
81 for (
int i = 0; i < static_cast<int>(scores.size()); ++i) {
82 if (scores[i] > threshold) {
83 score_index_vec->push_back(std::make_pair(scores[i], i));
88 std::stable_sort(score_index_vec->begin(), score_index_vec->end(),
89 sort_score_pair_descend<int>);
92 if (top_k > -1 && top_k <
static_cast<int>(score_index_vec->size())) {
93 score_index_vec->resize(top_k);
98 std::vector<float> *scores,
const float score_threshold,
99 const float nms_threshold,
const int top_k,
100 std::vector<int> *indices,
bool is_linear,
103 CHECK_EQ(bboxes.size(), scores->size())
104 <<
"bboxes and scores have different size.";
107 std::vector<std::pair<float, int>> score_index_vec;
112 while (!score_index_vec.empty()) {
114 max_element(std::begin(score_index_vec), std::end(score_index_vec));
115 const int best_idx = (*best_it).second;
116 score_index_vec.erase(best_it);
118 indices->push_back(best_idx);
119 for (std::vector<std::pair<float, int>>::iterator it =
120 score_index_vec.begin();
121 it != score_index_vec.end();) {
122 int cur_idx = it->second;
125 float cur_overlap = 0.;
128 (*scores)[cur_idx] *=
static_cast<float>((1.0 - cur_overlap));
130 (*scores)[cur_idx] *=
131 static_cast<float>(exp(-1.0 * pow(cur_overlap, 2) / sigma));
139 std::vector<float> *scores,
140 const float conf_threshold,
const float nms_threshold,
141 const float sigma, std::vector<int> *indices) {
142 if (bboxes->size() == 0) {
146 for (
int i = 0; i < static_cast<int>(bboxes->size()); i++) {
147 (*bboxes)[i].mask =
false;
148 if ((*scores)[i] > conf_threshold) {
149 indices->push_back(i);
152 for (
int count = 0; count < static_cast<int>(indices->size()); count++) {
155 for (
int i = 1; i < static_cast<int>(indices->size()); i++) {
156 int idx = indices->at(i);
157 if ((*bboxes)[idx].mask) {
160 if ((*scores)[idx] > (*scores)[max_box_idx]) {
166 best_bbox.
score = (*scores)[max_box_idx];
167 best_bbox.
mask =
true;
168 float s_vt = (*scores)[max_box_idx];
169 float x1_vt = best_bbox.
xmin * s_vt;
170 float x2_vt = best_bbox.
xmax * s_vt;
171 float y1_vt = best_bbox.
ymin * s_vt;
172 float y2_vt = best_bbox.
ymax * s_vt;
173 for (
int i = 0; i < static_cast<int>(indices->size()); i++) {
174 int sub_it = indices->at(i);
175 if ((*bboxes)[sub_it].mask) {
178 float cur_overlap = 0.;
181 (*bboxes)[sub_it].mask =
true;
184 static_cast<float>(exp(-1.0 * pow(cur_overlap, 2) / sigma));
186 (*bboxes)[sub_it].score = (*scores)[sub_it];
189 if (cur_overlap > nms_threshold) {
190 float s_vt_cur = (*bboxes)[sub_it].score;
192 x1_vt += (*bboxes)[sub_it].xmin * s_vt_cur;
193 x2_vt += (*bboxes)[sub_it].xmax * s_vt_cur;
194 y1_vt += (*bboxes)[sub_it].ymin * s_vt_cur;
195 y2_vt += (*bboxes)[sub_it].ymax * s_vt_cur;
199 (*bboxes)[max_box_idx].xmin = x1_vt / s_vt;
200 (*bboxes)[max_box_idx].xmax = x2_vt / s_vt;
201 (*bboxes)[max_box_idx].ymin = y1_vt / s_vt;
202 (*bboxes)[max_box_idx].ymax = y2_vt / s_vt;
208 const std::vector<float> &scores,
209 const float score_threshold,
const float nms_threshold,
210 const float eta,
const int top_k,
211 std::vector<int> *indices) {
213 CHECK_EQ(bboxes.size(), scores.size())
214 <<
"bboxes and scores have different size.";
217 std::vector<std::pair<float, int>> score_index_vec;
221 float adaptive_threshold = nms_threshold;
223 while (!score_index_vec.empty()) {
224 const int idx = score_index_vec.front().second;
226 for (
int k = 0; k < static_cast<int>(indices->size()); ++k) {
228 const int kept_idx = (*indices)[k];
230 keep = overlap <= adaptive_threshold;
236 indices->push_back(idx);
238 score_index_vec.erase(score_index_vec.begin());
239 if (keep && eta < 1 && adaptive_threshold > 0.5) {
240 adaptive_threshold *= eta;
246 std::vector<base::ObjectPtr> *objects) {
247 int valid_obj_idx = 0;
248 int total_obj_idx = 0;
249 while (total_obj_idx <
static_cast<int>(objects->size())) {
250 const auto &obj = (*objects)[total_obj_idx];
251 if ((obj->camera_supplement.box.ymax - obj->camera_supplement.box.ymin) >=
258 (*objects)[valid_obj_idx] = (*objects)[total_obj_idx];
263 AINFO << valid_obj_idx <<
" of " << total_obj_idx <<
" obstacles kept";
264 objects->resize(valid_obj_idx);
265 AINFO <<
"Number of detected obstacles: " << objects->size();
268 std::vector<base::ObjectPtr> *objects) {
269 for (
auto &obj : *objects) {
270 float xmin = obj->camera_supplement.box.xmin;
271 float ymin = obj->camera_supplement.box.ymin;
272 float xmax = obj->camera_supplement.box.xmax;
273 float ymax = obj->camera_supplement.box.ymax;
274 int x =
static_cast<int>(xmin *
static_cast<float>(roi_w));
275 int w =
static_cast<int>((xmax - xmin) *
static_cast<float>(roi_w));
276 int y =
static_cast<int>(ymin *
static_cast<float>(roi_h)) + offset_y;
277 int h =
static_cast<int>((ymax - ymin) *
static_cast<float>(roi_h));
278 base::RectF rect_det(
static_cast<float>(x),
static_cast<float>(y),
279 static_cast<float>(w),
static_cast<float>(h));
280 base::RectF rect_img(0, 0,
static_cast<float>(roi_w),
281 static_cast<float>(roi_h + offset_y));
283 obj->camera_supplement.box = rect;
288 if ((ymin < eps) || (ymax >= 1.0 - eps)) {
289 obj->camera_supplement.truncated_vertical = 0.5;
291 obj->camera_supplement.truncated_vertical = 0.0;
293 if ((xmin < eps) || (xmax >= 1.0 - eps)) {
294 obj->camera_supplement.truncated_horizontal = 0.5;
296 obj->camera_supplement.truncated_horizontal = 0.0;
299 obj->camera_supplement.front_box.xmin *=
static_cast<float>(roi_w);
300 obj->camera_supplement.front_box.ymin *=
static_cast<float>(roi_h);
301 obj->camera_supplement.front_box.xmax *=
static_cast<float>(roi_w);
302 obj->camera_supplement.front_box.ymax *=
static_cast<float>(roi_h);
304 obj->camera_supplement.back_box.xmin *=
static_cast<float>(roi_w);
305 obj->camera_supplement.back_box.ymin *=
static_cast<float>(roi_h);
306 obj->camera_supplement.back_box.xmax *=
static_cast<float>(roi_w);
307 obj->camera_supplement.back_box.ymax *=
static_cast<float>(roi_h);
309 obj->camera_supplement.front_box.ymin +=
static_cast<float>(offset_y);
310 obj->camera_supplement.front_box.ymax +=
static_cast<float>(offset_y);
311 obj->camera_supplement.back_box.ymin +=
static_cast<float>(offset_y);
312 obj->camera_supplement.back_box.ymax +=
static_cast<float>(offset_y);
317 obj->camera_supplement.box.xmin = bbox[0];
318 obj->camera_supplement.box.ymin = bbox[1];
319 obj->camera_supplement.box.xmax = bbox[2];
320 obj->camera_supplement.box.ymax = bbox[3];
325 obj->camera_supplement.alpha = bbox[0];
326 obj->size[2] = bbox[1];
327 obj->size[1] = bbox[2];
328 obj->size[0] = bbox[3];
334 obj->camera_supplement.front_box.xmin = bbox[0];
335 obj->camera_supplement.front_box.ymin = bbox[1];
336 obj->camera_supplement.front_box.xmax = bbox[2];
337 obj->camera_supplement.front_box.ymax = bbox[3];
339 obj->camera_supplement.back_box.xmin = bbox[4];
340 obj->camera_supplement.back_box.ymin = bbox[5];
341 obj->camera_supplement.back_box.xmax = bbox[6];
342 obj->camera_supplement.back_box.ymax = bbox[7];
348 obj->car_light.brake_visible = bbox[0];
349 obj->car_light.brake_switch_on = bbox[1];
350 obj->car_light.left_turn_visible = bbox[2];
351 obj->car_light.left_turn_switch_on = bbox[3];
352 obj->car_light.right_turn_visible = bbox[4];
353 obj->car_light.right_turn_switch_on = bbox[5];
360 obj->camera_supplement.visible_ratios[0] = bbox[0];
361 obj->camera_supplement.visible_ratios[1] = bbox[1];
362 obj->camera_supplement.visible_ratios[2] = bbox[2];
363 obj->camera_supplement.visible_ratios[3] = bbox[3];
366 obj->camera_supplement.cut_off_ratios[0] = bbox[4];
367 obj->camera_supplement.cut_off_ratios[1] = bbox[5];
369 obj->camera_supplement.cut_off_ratios[2] = bbox[6];
370 obj->camera_supplement.cut_off_ratios[3] = bbox[7];
376 obj->camera_supplement.area_id =
static_cast<int>(data[0]);
383 for (
int i = 1; i < 4; i++) {
384 if (visible_ratios[i] > visible_ratios[max_face]) {
388 int left_face = (max_face + 1) % 4;
389 int right_face = (max_face + 3) % 4;
390 const float eps = 1e-3f;
391 float max_ratio = visible_ratios[max_face];
392 float left_ratio = visible_ratios[left_face];
393 float right_ratio = visible_ratios[right_face];
394 memset(visible_ratios, 0, 4 *
sizeof(visible_ratios[0]));
395 if (left_ratio < eps && right_ratio < eps) {
396 area_id = (max_face * 2 + 1);
397 visible_ratios[max_face] = 1.f;
398 }
else if (left_ratio > right_ratio) {
399 area_id = (max_face * 2 + 2);
400 auto &&sum_ratio = left_ratio + max_ratio;
401 visible_ratios[max_face] = max_ratio / sum_ratio;
402 visible_ratios[left_face] = left_ratio / sum_ratio;
404 area_id = (max_face * 2);
408 auto &&sum_ratio = right_ratio + max_ratio;
409 visible_ratios[max_face] = max_ratio / sum_ratio;
410 visible_ratios[right_face] = right_ratio / sum_ratio;
416 return flag ? blob.
cpu_data() :
nullptr;
420 const std::vector<base::ObjectSubType> &types,
422 float light_vis_conf_threshold,
423 float light_swt_conf_threshold,
425 std::vector<base::ObjectPtr> *objects) {
426 std::map<base::ObjectSubType, std::vector<int>> indices;
427 std::map<base::ObjectSubType, std::vector<float>> conf_scores;
429 int num_classes = types.size();
430 num_kept =
get_objects_gpu(yolo_blobs, stream, types, nms, model_param,
431 light_vis_conf_threshold, light_swt_conf_threshold,
432 overlapped, idx_sm, indices, conf_scores);
439 objects->reserve(num_kept +
static_cast<int>(objects->size()));
440 const float *cpu_box_data = yolo_blobs.
res_box_blob->cpu_data();
443 for (
auto it = indices.begin(); it != indices.end(); ++it) {
445 if (conf_scores.find(label) == conf_scores.end()) {
449 const std::vector<float> &scores = conf_scores.find(label)->second;
450 std::vector<int> &indice = it->second;
451 for (
size_t j = 0; j < indice.size(); ++j) {
453 const float *bbox = cpu_box_data + idx * kBoxBlockSize;
461 obj->sub_type = label;
462 obj->type_probs.assign(
464 obj->sub_type_probs.assign(
467 for (
int k = 0; k < num_classes; ++k) {
468 auto &vis_type_k = types[k];
470 auto &conf_score = conf_scores[vis_type_k][idx];
471 obj->type_probs[
static_cast<int>(obj_type_k)] += conf_score;
472 obj->sub_type_probs[
static_cast<int>(vis_type_k)] = conf_score;
475 obj->confidence = obj->type_probs[
static_cast<int>(obj->type)];
476 for (
size_t k = 0; k < obj->type_probs.size(); ++k) {
477 obj->type_probs[k] /= total;
487 if (maintainer.
Add(idx, obj)) {
488 objects->push_back(obj);
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
const Dtype * cpu_data() const
bool Add(int idx, base::ObjectPtr obj)
Maintain a collection of objects that can be added based on the index.
const std::map< ObjectSubType, ObjectType > kSubType2TypeMap
ObjectSubType mapping
std::shared_ptr< Object > ObjectPtr
void get_max_score_index(const std::vector< float > &scores, const float threshold, const int top_k, std::vector< std::pair< float, int > > *score_index_vec)
Get the max score index object
void apply_softnms_fast(const std::vector< NormalizedBBox > &bboxes, std::vector< float > *scores, const float score_threshold, const float nms_threshold, const int top_k, std::vector< int > *indices, bool is_linear, const float sigma)
softnms for objects
void recover_bbox(int roi_w, int roi_h, int offset_y, std::vector< base::ObjectPtr > *objects)
recover detect bbox result to raw image
void apply_boxvoting_fast(std::vector< NormalizedBBox > *bboxes, std::vector< float > *scores, const float conf_threshold, const float nms_threshold, const float sigma, std::vector< int > *indices)
filter target detection results based on given thresholds and parameters.
const float * get_cpu_data(bool flag, const base::Blob< float > &blob)
float get_bbox_size(const NormalizedBBox &bbox)
int get_objects_gpu(const YoloBlobs &yolo_blobs, const cudaStream_t &stream, const std::vector< base::ObjectSubType > &types, const NMSParam &nms, const yolo::ModelParam &model_param, float light_vis_conf_threshold, float light_swt_conf_threshold, base::Blob< bool > *overlapped, base::Blob< int > *idx_sm, const std::map< base::ObjectSubType, std::vector< int > > &indices, const std::map< base::ObjectSubType, std::vector< float > > &conf_scores)
Get the objects gpu object
void fill_base(base::ObjectPtr obj, const float *bbox)
add bbox value to object
void fill_ratios(bool with_ratios, base::ObjectPtr obj, const float *bbox)
add ratio value to object
void fill_frbox(bool with_frbox, base::ObjectPtr obj, const float *bbox)
add car front and backward bbox value to object
int get_area_id(float visible_ratios[4])
calculate the area id based on the visible ratios
void get_intersect_bbox(const NormalizedBBox &bbox1, const NormalizedBBox &bbox2, NormalizedBBox *intersect_bbox)
Get the intersect bbox object
void fill_area_id(bool with_flag, base::ObjectPtr obj, const float *data)
add area id value to object
float get_jaccard_overlap(const NormalizedBBox &bbox1, const NormalizedBBox &bbox2)
Get the jaccard overlap object
void get_objects_cpu(const YoloBlobs &yolo_blobs, const cudaStream_t &stream, const std::vector< base::ObjectSubType > &types, const NMSParam &nms, const yolo::ModelParam &model_param, float light_vis_conf_threshold, float light_swt_conf_threshold, base::Blob< bool > *overlapped, base::Blob< int > *idx_sm, std::vector< base::ObjectPtr > *objects)
Get the objects cpu object
void fill_bbox3d(bool with_box3d, base::ObjectPtr obj, const float *bbox)
add alpha h w l to object
void filter_bbox(const MinDims &min_dims, std::vector< base::ObjectPtr > *objects)
filter out the objects in the object array based on the given minimum dimension conditions and retain...
void fill_lights(bool with_lights, base::ObjectPtr obj, const float *bbox)
add car lights value to object
void apply_nms_fast(const std::vector< NormalizedBBox > &bboxes, const std::vector< float > &scores, const float score_threshold, const float nms_threshold, const float eta, const int top_k, std::vector< int > *indices)
nms for objects
std::shared_ptr< base::Blob< float > > res_box_blob
optional float confidence_threshold
optional bool with_lights
optional bool with_ratios