20#include <unordered_map>
62static void generate_grids_and_stride(
63 std::vector<int> &strides, std::vector<GridAndStride> &grid_strides) {
64 for (
auto stride : strides) {
65 int num_grid_y = 640 / stride;
66 int num_grid_x = 640 / stride;
67 for (
int g1 = 0; g1 < num_grid_y; g1++) {
68 for (
int g0 = 0; g0 < num_grid_x; g0++) {
86static void generate_yolox3d_proposals(std::vector<GridAndStride> grid_strides,
87 const float *feat_blob,
89 std::vector<Object> &objects) {
90 const int num_anchors = grid_strides.size();
92 for (
int anchor_idx = 0; anchor_idx < num_anchors; anchor_idx++) {
93 const int grid0 = grid_strides[anchor_idx].grid0;
94 const int grid1 = grid_strides[anchor_idx].grid1;
95 const int stride = grid_strides[anchor_idx].stride;
100 float x_center = (feat_blob[basic_pos + 0] + grid0) * stride;
101 float y_center = (feat_blob[basic_pos + 1] + grid1) * stride;
102 float w = exp(feat_blob[basic_pos + 2]) * stride;
103 float h = exp(feat_blob[basic_pos + 3]) * stride;
104 float x0 = x_center - w * 0.5f;
105 float y0 = y_center - h * 0.5f;
107 if (w - 10 < 0 || h - 10 < 0) {
111 std::vector<float> scores;
113 float box_objectness = feat_blob[basic_pos +
kScoreIndex];
115 float box_cls_score = feat_blob[basic_pos +
kLabelIndex + class_idx];
116 float box_prob = box_objectness * box_cls_score;
117 scores.push_back(box_prob);
119 auto max_iter = std::max_element(scores.begin(), scores.end());
120 int max_idx = std::distance(scores.begin(), max_iter);
122 if (*max_iter > prob_threshold) {
129 obj.prob = *max_iter;
130 objects.push_back(obj);
146static inline float intersection_area(
const Object &a,
const Object &b) {
147 cv::Rect_<float> inter = a.rect & b.rect;
158static void nms_sorted_bboxes(
const std::vector<Object> &faceobjects,
159 std::vector<int> &picked,
float nms_threshold) {
162 const int n = faceobjects.size();
164 std::vector<float> areas(n);
165 for (
int i = 0; i < n; i++) {
166 areas[i] = faceobjects[i].rect.area();
169 for (
int i = 0; i < n; i++) {
170 const Object &a = faceobjects[i];
173 for (
int j = 0; j < static_cast<int>(picked.size()); j++) {
174 const Object &b = faceobjects[picked[j]];
177 float inter_area = intersection_area(a, b);
178 float union_area = areas[i] + areas[picked[j]] - inter_area;
180 if (inter_area / union_area > nms_threshold) keep = 0;
183 if (keep) picked.push_back(i);
199static void qsort_descent_inplace(std::vector<Object> &faceobjects,
int left,
203 float p = faceobjects[(left + right) / 2].prob;
206 while (faceobjects[i].prob > p) i++;
208 while (faceobjects[j].prob < p) j--;
212 std::swap(faceobjects[i], faceobjects[j]);
219#pragma omp parallel sections
223 if (left < j) qsort_descent_inplace(faceobjects, left, j);
227 if (i < right) qsort_descent_inplace(faceobjects, i, right);
232static void qsort_descent_inplace(std::vector<Object> &objects) {
233 if (objects.empty())
return;
235 qsort_descent_inplace(objects, 0, objects.size() - 1);
241 std::vector<std::vector<float>> *objects_out) {
242 objects_out->clear();
244 std::vector<Object> objects;
245 std::vector<Object> proposals;
246 std::vector<int> strides = {8, 16, 32};
247 std::vector<GridAndStride> grid_strides;
248 generate_grids_and_stride(strides, grid_strides);
249 generate_yolox3d_proposals(grid_strides, data,
251 AINFO <<
"Yolox proposals size is " << proposals.size();
253 qsort_descent_inplace(proposals);
254 AINFO <<
"Yolox proposals after sort size is " << proposals.size();
256 std::vector<int> picked;
258 AINFO <<
"Yolox objects after nms is " << picked.size();
260 int count = picked.size();
261 objects.resize(count);
262 for (
int i = 0; i < count; i++) {
263 objects[i] = proposals[picked[i]];
266 float x0 = (objects[i].rect.x) / scale;
267 float y0 = (objects[i].rect.y) / scale;
268 float x1 = (objects[i].rect.x + objects[i].rect.width) / scale;
269 float y1 = (objects[i].rect.y + objects[i].rect.height) / scale;
272 x0 = std::max(std::min(x0,
static_cast<float>(1920 - 1)), 0.f);
273 y0 = std::max(std::min(y0,
static_cast<float>(1920 - 1)), 0.f);
274 x1 = std::max(std::min(x1,
static_cast<float>(1920 - 1)), 0.f);
275 y1 = std::max(std::min(y1,
static_cast<float>(1920 - 1)), 0.f);
277 objects[i].rect.x = x0;
278 objects[i].rect.y = y0;
279 objects[i].rect.width = x1 - x0;
280 objects[i].rect.height = y1 - y0;
282 std::vector<float> object_temp;
283 object_temp.push_back(x0);
284 object_temp.push_back(y0);
285 object_temp.push_back(x1 - x0);
286 object_temp.push_back(y1 - y0);
288 object_temp.push_back(objects[i].prob);
289 object_temp.push_back(objects[i].label);
291 objects_out->push_back(object_temp);
299 if (unionsection.
Area() == 0)
return 0.0f;
300 return intersection.
Area() / unionsection.
Area();
304 const int height,
const int image_width,
307 obj->camera_supplement.box.xmin = detect[0];
308 obj->camera_supplement.box.ymin = detect[1];
309 obj->camera_supplement.box.xmax = detect[0] + detect[2];
310 obj->camera_supplement.box.ymax = detect[1] + detect[3];
320 if (base ::ObjectType ::VEHICLE ==
334 }
else if (base ::ObjectType ::PEDESTRIAN ==
339 }
else if (base ::ObjectType ::BICYCLE ==
344 }
else if (base ::ObjectType ::UNKNOWN_UNMOVABLE ==
352 obj->size[0] = obj_l;
353 obj->size[1] = obj_w;
354 obj->size[2] = obj_h;
355 obj->camera_supplement.alpha = detect[8];
360 const std::vector<float> &box2) {
361 const int center_x_index = 0;
362 const int center_y_index = 1;
363 const int width_index = 2;
364 const int height_index = 3;
366 int b1_x1 =
static_cast<int>(box1[center_x_index]) -
367 std::floor(box1[width_index] / 2.0);
368 int b1_y1 =
static_cast<int>(box1[center_y_index]) -
369 std::floor(box1[height_index] / 2.0);
370 int b1_x2 =
static_cast<int>(box1[center_x_index]) +
371 std::floor(box1[width_index] / 2.0);
372 int b1_y2 =
static_cast<int>(box1[center_y_index]) +
373 std::floor(box1[height_index] / 2.0);
375 int b2_x1 =
static_cast<int>(box2[center_x_index]) -
376 std::floor(box2[width_index] / 2.0);
377 int b2_y1 =
static_cast<int>(box2[center_y_index]) -
378 std::floor(box2[height_index] / 2.0);
379 int b2_x2 =
static_cast<int>(box2[center_x_index]) +
380 std::floor(box2[width_index] / 2.0);
381 int b2_y2 =
static_cast<int>(box2[center_y_index]) +
382 std::floor(box2[height_index] / 2.0);
385 int inter_rect_x1 = std::max(b1_x1, b2_x1);
386 int inter_rect_y1 = std::max(b1_y1, b2_y1);
387 int inter_rect_x2 = std::min(b1_x2, b2_x2);
388 int inter_rect_y2 = std::min(b1_y2, b2_y2);
391 float inter_area =
static_cast<float>(
392 Yoloxclamp(inter_rect_x2 - inter_rect_x1 + 1, 0, INT_MAX) *
393 Yoloxclamp(inter_rect_y2 - inter_rect_y1 + 1, 0, INT_MAX));
395 float b1_area = (b1_x2 - b1_x1 + 1) * (b1_y2 - b1_y1 + 1);
396 float b2_area = (b2_x2 - b2_x1 + 1) * (b2_y2 - b2_y1 + 1);
398 float iou = inter_area / (b1_area + b2_area - inter_area + 1e-3);
403 const int image_height) {
404 const float boundary_len = 20.0;
405 float min_x =
static_cast<float>(boundary_len);
406 float min_y =
static_cast<float>(boundary_len);
407 float max_x =
static_cast<float>(image_width - boundary_len);
408 float max_y =
static_cast<float>(image_height - boundary_len);
411 if (obj->camera_supplement.box.xmin <= min_x ||
412 obj->camera_supplement.box.xmax >= max_x ||
413 obj->camera_supplement.box.ymin <= min_y ||
414 obj->camera_supplement.box.ymax >= max_y) {
416 if ((obj->camera_supplement.box.ymin < eps) ||
417 (obj->camera_supplement.box.ymax >= 1.0 - eps)) {
418 obj->camera_supplement.truncated_vertical = 0.5;
420 obj->camera_supplement.truncated_vertical = 0.0;
422 if ((obj->camera_supplement.box.xmin < eps) ||
423 (obj->camera_supplement.box.xmax >= 1.0 - eps)) {
424 obj->camera_supplement.truncated_horizontal = 0.5;
426 obj->camera_supplement.truncated_horizontal = 0.0;
434 const int height,
const int image_width,
435 const int image_height,
436 std::vector<base::ObjectPtr> *objects) {
437 ACHECK(objects_blob !=
nullptr);
438 ACHECK(objects !=
nullptr);
440 const float *detect_data = objects_blob->cpu_data();
441 ACHECK(detect_data !=
nullptr);
443 float scale = std::min(model_param.
resize().
width() / (image_width * 1.0),
446 std::vector<std::vector<float>> detect_objects;
451 for (
const std::vector<float> &detect : detect_objects) {
467 obj->sub_type_probs.assign(
469 obj->type_probs[
static_cast<int>(obj->type)] = detect[
kLabelIndex];
470 obj->sub_type_probs[
static_cast<int>(obj->sub_type)] = detect[
kLabelIndex];
472 YoloxFillBase(detect, width, height, image_width, image_height, obj);
479 objects->push_back(obj);
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
const std::map< ObjectSubType, std::string > kSubType2NameMap
const std::map< ObjectSubType, ObjectType > kSubType2TypeMap
ObjectSubType mapping
std::shared_ptr< Object > ObjectPtr
constexpr int kLabelIndex
void YoloxGetAllObjects(const float *data, const yolox3d::ModelParam &model_param, const float scale, std::vector< std::vector< float > > *objects_out)
Get all objects accoring to confidence
float YoloxBboxIOU(const std::vector< float > &box1, const std::vector< float > &box2)
Computes IoU between bboxes.
constexpr T Yoloxclamp(const T &val, const T &low, const T &high)
Clamp target value between low and high tools for iou
void YoloxGetObjectsCpu(const std::shared_ptr< base::Blob< float > > &objects_blob, const yolox3d::ModelParam &model_param, const yolox3d::NMSParam &nms_param, const int width, const int height, const int image_width, const int image_height, std::vector< base::ObjectPtr > *objects)
Return Yolox Objects
void YoloxFillBase(const std::vector< float > &detect, const int width, const int height, const int image_width, const int image_height, base::ObjectPtr obj)
Get 2dbbox for objects
constexpr int kScoreIndex
float ComputeYoloxOverlap(const base::Rect< float > &a, const base::Rect< float > &b)
constexpr int kClassOfObstacles
void YoloxFillBbox3d(const yolox3d::ModelParam &model_param, const std::vector< float > &detect, base::ObjectPtr obj)
Add 3d bbox values for objects
void YoloxTruncated(base::ObjectPtr obj, const int image_width, const int image_height)
object is truncated or not
const base::ObjectSubType kYoloSubTypeYolox[]
optional float confidence_threshold
optional common::Resize resize
optional ObjTemplate car_template
optional ObjTemplate cyclist_template
optional NMSParam nms_param
optional ObjTemplate ped_template
optional ObjTemplate trafficcone_template