20#include <unordered_map>
58static void generate_grids_and_stride(std::vector<int> &strides, std::vector<GridAndStride> &grid_strides) {
59 for (
auto stride : strides) {
60 int num_grid_y = 640 / stride;
61 int num_grid_x = 640 / stride;
62 for (
int g1 = 0; g1 < num_grid_y; g1++) {
63 for (
int g0 = 0; g0 < num_grid_x; g0++) {
70static void generate_yolox3d_proposals(
71 std::vector<GridAndStride> grid_strides,
72 const float *feat_blob,
74 std::vector<Object> &objects) {
75 const int num_anchors = grid_strides.size();
77 for (
int anchor_idx = 0; anchor_idx < num_anchors; anchor_idx++) {
78 const int grid0 = grid_strides[anchor_idx].grid0;
79 const int grid1 = grid_strides[anchor_idx].grid1;
80 const int stride = grid_strides[anchor_idx].stride;
85 float x_center = (feat_blob[basic_pos + 0] + grid0) * stride;
86 float y_center = (feat_blob[basic_pos + 1] + grid1) * stride;
87 float w = exp(feat_blob[basic_pos + 2]) * stride;
88 float h = exp(feat_blob[basic_pos + 3]) * stride;
89 float x0 = x_center - w * 0.5f;
90 float y0 = y_center - h * 0.5f;
92 if (w - 10 < 0 || h - 10 < 0) {
96 std::vector<float> scores;
98 float box_objectness = feat_blob[basic_pos +
kScoreIndex];
100 float box_cls_score = feat_blob[basic_pos +
kLabelIndex + class_idx];
101 float box_prob = box_objectness * box_cls_score;
102 scores.push_back(box_prob);
104 auto max_iter = std::max_element(scores.begin(), scores.end());
105 int max_idx = std::distance(scores.begin(), max_iter);
107 if (*max_iter > prob_threshold) {
114 obj.prob = *max_iter;
115 objects.push_back(obj);
120static inline float intersection_area(
const Object &a,
const Object &b) {
121 cv::Rect_<float> inter = a.rect & b.rect;
125static void nms_sorted_bboxes(
const std::vector<Object> &faceobjects, std::vector<int> &picked,
float nms_threshold) {
128 const int n = faceobjects.size();
130 std::vector<float> areas(n);
131 for (
int i = 0; i < n; i++) {
132 areas[i] = faceobjects[i].rect.area();
135 for (
int i = 0; i < n; i++) {
136 const Object &a = faceobjects[i];
139 for (
int j = 0; j < static_cast<int>(picked.size()); j++) {
140 const Object &b = faceobjects[picked[j]];
143 float inter_area = intersection_area(a, b);
144 float union_area = areas[i] + areas[picked[j]] - inter_area;
146 if (inter_area / union_area > nms_threshold)
155static void qsort_descent_inplace(std::vector<Object> &faceobjects,
int left,
int right) {
158 float p = faceobjects[(left + right) / 2].prob;
161 while (faceobjects[i].prob > p) {
165 while (faceobjects[j].prob < p) {
171 std::swap(faceobjects[i], faceobjects[j]);
178#pragma omp parallel sections
183 qsort_descent_inplace(faceobjects, left, j);
188 qsort_descent_inplace(faceobjects, i, right);
193static void qsort_descent_inplace(std::vector<Object> &objects) {
197 qsort_descent_inplace(objects, 0, objects.size() - 1);
204 std::vector<std::vector<float>> *objects_out) {
205 objects_out->clear();
206 std::vector<Object> objects;
208 std::vector<Object> proposals;
209 std::vector<int> strides = {8, 16, 32};
210 std::vector<GridAndStride> grid_strides;
211 generate_grids_and_stride(strides, grid_strides);
213 qsort_descent_inplace(proposals);
215 std::vector<int> picked;
217 int count = picked.size();
219 objects.resize(count);
220 for (
int i = 0; i < count; i++) {
221 objects[i] = proposals[picked[i]];
224 float x0 = (objects[i].rect.x) / scale;
225 float y0 = (objects[i].rect.y) / scale;
226 float x1 = (objects[i].rect.x + objects[i].rect.width) / scale;
227 float y1 = (objects[i].rect.y + objects[i].rect.height) / scale;
230 x0 = std::max(std::min(x0,
static_cast<float>(1920 - 1)), 0.f);
231 y0 = std::max(std::min(y0,
static_cast<float>(1920 - 1)), 0.f);
232 x1 = std::max(std::min(x1,
static_cast<float>(1920 - 1)), 0.f);
233 y1 = std::max(std::min(y1,
static_cast<float>(1920 - 1)), 0.f);
235 objects[i].rect.x = x0;
236 objects[i].rect.y = y0;
237 objects[i].rect.width = x1 - x0;
238 objects[i].rect.height = y1 - y0;
240 std::vector<float> object_temp;
241 object_temp.push_back(x0);
242 object_temp.push_back(y0);
243 object_temp.push_back(x1 - x0);
244 object_temp.push_back(y1 - y0);
246 object_temp.push_back(objects[i].prob);
247 object_temp.push_back(objects[i].label);
249 objects_out->push_back(object_temp);
256 if (unionsection.
Area() == 0)
258 return intersection.
Area() / unionsection.
Area();
262 const std::vector<float> &detect,
265 const int image_width,
266 const int image_height,
269 obj->camera_supplement.box.xmin = detect[0];
270 obj->camera_supplement.box.ymin = detect[1];
271 obj->camera_supplement.box.xmax = detect[0] + detect[2];
272 obj->camera_supplement.box.ymax = detect[1] + detect[3];
309 obj->size[0] = obj_l;
310 obj->size[1] = obj_w;
311 obj->size[2] = obj_h;
312 obj->camera_supplement.alpha = detect[8];
316float YoloxBboxIOU(
const std::vector<float> &box1,
const std::vector<float> &box2) {
317 const int center_x_index = 0;
318 const int center_y_index = 1;
319 const int width_index = 2;
320 const int height_index = 3;
322 int b1_x1 =
static_cast<int>(box1[center_x_index]) - std::floor(box1[width_index] / 2.0);
323 int b1_y1 =
static_cast<int>(box1[center_y_index]) - std::floor(box1[height_index] / 2.0);
324 int b1_x2 =
static_cast<int>(box1[center_x_index]) + std::floor(box1[width_index] / 2.0);
325 int b1_y2 =
static_cast<int>(box1[center_y_index]) + std::floor(box1[height_index] / 2.0);
327 int b2_x1 =
static_cast<int>(box2[center_x_index]) - std::floor(box2[width_index] / 2.0);
328 int b2_y1 =
static_cast<int>(box2[center_y_index]) - std::floor(box2[height_index] / 2.0);
329 int b2_x2 =
static_cast<int>(box2[center_x_index]) + std::floor(box2[width_index] / 2.0);
330 int b2_y2 =
static_cast<int>(box2[center_y_index]) + std::floor(box2[height_index] / 2.0);
333 int inter_rect_x1 = std::max(b1_x1, b2_x1);
334 int inter_rect_y1 = std::max(b1_y1, b2_y1);
335 int inter_rect_x2 = std::min(b1_x2, b2_x2);
336 int inter_rect_y2 = std::min(b1_y2, b2_y2);
339 float inter_area =
static_cast<float>(
340 Yoloxclamp(inter_rect_x2 - inter_rect_x1 + 1, 0, INT_MAX)
341 *
Yoloxclamp(inter_rect_y2 - inter_rect_y1 + 1, 0, INT_MAX));
343 float b1_area = (b1_x2 - b1_x1 + 1) * (b1_y2 - b1_y1 + 1);
344 float b2_area = (b2_x2 - b2_x1 + 1) * (b2_y2 - b2_y1 + 1);
346 float iou = inter_area / (b1_area + b2_area - inter_area + 1e-3);
351 const float boundary_len = 20.0;
352 float min_x =
static_cast<float>(boundary_len);
353 float min_y =
static_cast<float>(boundary_len);
354 float max_x =
static_cast<float>(image_width - boundary_len);
355 float max_y =
static_cast<float>(image_height - boundary_len);
358 if (obj->camera_supplement.box.xmin <= min_x || obj->camera_supplement.box.xmax >= max_x
359 || obj->camera_supplement.box.ymin <= min_y || obj->camera_supplement.box.ymax >= max_y) {
361 if ((obj->camera_supplement.box.ymin < eps) || (obj->camera_supplement.box.ymax >= 1.0 - eps)) {
362 obj->camera_supplement.truncated_vertical = 0.5;
364 obj->camera_supplement.truncated_vertical = 0.0;
366 if ((obj->camera_supplement.box.xmin < eps) || (obj->camera_supplement.box.xmax >= 1.0 - eps)) {
367 obj->camera_supplement.truncated_horizontal = 0.5;
369 obj->camera_supplement.truncated_horizontal = 0.0;
380 const int image_width,
381 const int image_height,
382 std::vector<base::ObjectPtr> *objects) {
383 ACHECK(objects_blob !=
nullptr);
384 ACHECK(objects !=
nullptr);
386 const float *detect_data = objects_blob->cpu_data();
387 ACHECK(detect_data !=
nullptr);
389 float scale = std::min(
392 std::vector<std::vector<float>> detect_objects;
394 AINFO <<
"Yolox objects after nms is " << detect_objects.size();
398 for (
const std::vector<float> &detect : detect_objects) {
414 obj->type_probs[
static_cast<int>(obj->type)] = detect[
kLabelIndex];
415 obj->sub_type_probs[
static_cast<int>(obj->sub_type)] = detect[
kLabelIndex];
417 YoloxFillBase(detect, width, height, image_width, image_height, obj);
424 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 2d bbox 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