先定义计算IOU的函数
注意:PaddleDetection::ObjectResult的输出tensor为[num_id, score, xmin, ymin, xmax, ymax]
//定义计算iou的函数
float get_iou_value(PaddleDetection::ObjectResult box2_info, PaddleDetection::ObjectResult box1_info) {
float iou_value;
//计算iou_value,先寻找两个框左上角的最大值,再寻找两个框右下角的最小值
float x1 = max(box2_info.rect[0], box1_info.rect[0]);
float y1 = max(box2_info.rect[1], box1_info.rect[1]);
float x2 = min(box2_info.rect[2], box1_info.rect[2]);
float y2 = min(box2_info.rect[3], box1_info.rect[3]);
float w = max(x2 - x1, 0);
float h = max(y2 - y1, 0);
float insection_area = w * h;
float box1_area = (box1_info.rect[2] - box1_info.rect[0])*(box1_info.rect[3] - box1_info.rect[1]);
float box2_area = (box2_info.rect[2] - box2_info.rect[0])*(box2_info.rect[3] - box2_info.rect[1]);
float union_area = box1_area + box2_area - insection_area;
iou_value = insection_area / union_area;
return iou_value;
}
NMS算法实现:
//1.根据置信度,利用冒泡排序算法对检测结果进行排序
int boxes_num = im_result.size();
PaddleDetection::ObjectResult item_;
for (int i = 0; i < boxes_num -1; i++) {
for (int j = 0; j < boxes_num - 1 - i; j++) {
if (im_result[j].confidence < im_result[j + 1].confidence) {
item_ = im_result[j];
im_result[j] = im_result[j+1];
im_result[j + 1] = item_;
}
}
}
//2.依次计算相邻两个box的iou,若iou大于设定阈值,则过滤低置信度的box
float conf_threshold = 0.7;
for (int i = 0; i < boxes_num - 1; ++i) {
for (int j = i+1; j < boxes_num; ++j) {
//计算iou
float iou_value = get_iou_value(im_result[i], im_result[j]);
if (iou_value > conf_threshold) {
im_result.erase(im_result.begin() + j);
--j;
--boxes_num;
}
}
}