bmcv_nms_ext ============== 该接口是bmcv_nms接口的广义形式,支持Hard_NMS/Soft_NMS/Adaptive_NMS/SSD_NMS,用于消除网络计算得到过多的物体框,并找到最佳物体框。 **处理器型号支持:** 该接口支持BM1684/BM1684X。 **接口形式:** .. code-block:: c bm_status_t bmcv_nms_ext(bm_handle_t handle, bm_device_mem_t input_proposal_addr, int proposal_size, float nms_threshold, bm_device_mem_t output_proposal_addr, int topk, float score_threshold, int nms_alg, float sigma, int weighting_method, float * densities, float eta) **参数说明:** * bm_handle_t handle 输入参数。bm_handle 句柄。 * bm_device_mem_t input_proposal_addr 输入参数。输入物体框数据所在地址,输入物体框数据结构为 face_rect_t,详见下面数据结构说明。需要调用 bm_mem_from_system()将数据地址转化成转化为 bm_device_mem_t 所对应的结构。 * int proposal_size 输入参数。物体框个数。 * float nms_threshold 输入参数。过滤物体框的阈值,分数小于该阈值的物体框将会被过滤掉。 * bm_device_mem_t output_proposal_addr 输出参数。输出物体框数据所在地址,输出物体框数据结构为 nms_proposal_t,详见下面数据结构说明。需要调用 bm_mem_from_system() 将数据地址转化成转化为 bm_device_mem_t 所对应的结构。 * int topk 输入参数。当前未使用,为后续可能的的扩展预留的接口。 * float score_threshold 输入参数。当使用Soft_NMS或者Adaptive_NMS时,最低的score threshold。当score低于该值时,score所对应的框将被过滤掉。 * int nms_alg 输入参数。不同的NMS算法的选择,包括 Hard_NMS/Soft_NMS/Adaptive_NMS/SSD_NMS。 * float sigma 输入参数。当使用Soft_NMS或者Adaptive_NMS时,Gaussian re-score函数的参数。 * int weighting_method 输入参数。当使用Soft_NMS或者Adaptive_NMS时,re-score函数选项:包括线性权值和Gaussian权值。可选参数: .. code-block:: c typedef enum { LINEAR_WEIGHTING = 0, GAUSSIAN_WEIGHTING, MAX_WEIGHTING_TYPE } weighting_method_e; 线性权值表达式如下: .. math:: s_i = \begin{cases} s_i, & {iou(\mathcal{M}, b_i) #include #include #include #include #include #include #include #include #include #include #include "bmcv_api.h" #include "bmcv_internal.h" #include "bmcv_common_bm1684.h" #define MAX_PROPOSAL_NUM (65535) typedef float bm_nms_data_type_t; typedef struct { float x1; float y1; float x2; float y2; float score; } face_rect_t; typedef struct nms_proposal { int size; face_rect_t face_rect[MAX_PROPOSAL_NUM]; int capacity; face_rect_t *begin; face_rect_t *end; } nms_proposal_t; typedef enum { LINEAR_WEIGHTING = 0, GAUSSIAN_WEIGHTING, MAX_WEIGHTING_TYPE } weighting_method_e; template static bool generate_random_buf(std::vector &random_buffer, int random_min, int random_max, int scale) { for (int i = 0; i < scale; i++) { data_type data_val = (data_type)( random_min + (((float)((random_max - random_min) * i)) / scale)); random_buffer.push_back(data_val); } std::random_shuffle(random_buffer.begin(), random_buffer.end()); return false; } int main(int argc, char *argv[]) { unsigned int seed1 = 100; bm_nms_data_type_t nms_threshold = 0.22; bm_nms_data_type_t nms_score_threshold = 0.22; bm_nms_data_type_t sigma = 0.4; int proposal_size = 500; int rand_loop_num = 10; int weighting_method = GAUSSIAN_WEIGHTING; std::function weighting_func; int nms_type = SOFT_NMS; // ADAPTIVE NMS / HARD NMS / SOFT NMS const int soft_nms_total_types = MAX_NMS_TYPE - HARD_NMS - 1; for (int rand_loop_idx = 0;rand_loop_idx < (rand_loop_num * soft_nms_total_types);rand_loop_idx++) { for (int rand_mode = 0; rand_mode < MAX_RAND_MODE; rand_mode++) { std::shared_ptr> proposal_rand = std::make_shared>(MAX_PROPOSAL_NUM); std::shared_ptr output_proposal = std::make_shared(); std::vector proposals_ref; std::vector nms_proposal; std::vector score_random_buf; std::vector density_vec; std::shared_ptr> densities = std::make_shared>(proposal_size); generate_random_buf( score_random_buf, 0, 1, 10000); face_rect_t *proposal_rand_ptr = proposal_rand.get()->data; float eta = ((float)(rand() % 10)) / 10; for (int32_t i = 0; i < proposal_size; i++) { proposal_rand_ptr[i].x1 = ((bm_nms_data_type_t)(rand() % 100)) / 10; proposal_rand_ptr[i].x2 = proposal_rand_ptr[i].x1 + ((bm_nms_data_type_t)(rand() % 100)) / 10; proposal_rand_ptr[i].y1 = ((bm_nms_data_type_t)(rand() % 100)) / 10; proposal_rand_ptr[i].y2 = proposal_rand_ptr[i].y1 + ((bm_nms_data_type_t)(rand() % 100)) / 10; proposal_rand_ptr[i].score = score_random_buf[i]; proposals_ref.push_back(proposal_rand_ptr[i]); densities.get()->data[i] = ((float)(rand() % 100)) / 100; } assert(proposal_size <= MAX_PROPOSAL_NUM); if (weighting_method == LINEAR_WEIGHTING) { weighting_func = linear_weighting; } else if (weighting_method == GAUSSIAN_WEIGHTING) { weighting_func = gaussian_weighting; } else { std::cout << "weighting_method error: " << weighting_method << std::endl; } bmcv_nms_ext(handle, bm_mem_from_system(proposal_rand.get()->data), proposal_size, nms_threshold, bm_mem_from_system(output_proposal.get()), 1, nms_score_threshold, nms_type, sigma, weighting_method, densities.get()->data, eta); } } return 0; } **注意事项:** 该 api 可输入的最大 proposal 数为 1024。