整体流程:
根据分类的概率进行大小排序,先找出概率最大的,遍历这个框之后的框,计算IOU,大于阈值(0.3或其他)则将其从列表中去除。知道走到最后。再进行概率第二大的框。。。以此类推。
struct detect_region{
//定义结构体
detect_region(const float score, Point pos1, Point pos2)
:score(score), pos1(pos1), pos2(pos2) {}
float score;
Point pos1;
Point pos2;
};
bool cmp(detect_region a, detect_region b) {
return (a.score > b.score);
}
void nonmaxsuppression(vector<detect_region> ®ion_list) {
//按照分类概率的大小对输出进行排序
sort(region_list.begin(), region_list .end(), cmp);
vector<float> vArea(region_list.size());
for (int i = 0; i < vArea.size(); i++) {
vArea[i] = (region_list[i].pos2.x - region_list[i].pos1.x)*(region_list[i].pos2.y - region_list[i].pos1.y);
for (int i = 0; i < vArea.size(); i++) {
for (int j = i + 1; j < vArea.size(); j++) {
//计算相交的框的左上角坐标以及右下角坐标
float xx1 = max(region_list[i].pos1.x, region_list[i].pos1.x);
float yy1 = max(region_list[i].pos1.y, region_list[i].pos1.y);
float xx2 = min(region_list[i].pos2.x, region_list[i].pos2.x);
float yy2 = min(region_list[i].pos2.y, region_list[i].pos2.y);
float w = max((float)0, (xx2 - xx1) + 1);
float h = max((float)0, (yy2 - yy1) + 1);
//求出相交面积
float inter = w * h;
//计算IOU
float ovr = inter / (vArea[i] + vArea[j] - inter);
//大于阈值则将其从region_list中删除
if (ovr > 0.1f) {
region_list.erase(region_list.begin() + j);
vArea.erase(vArea.begin() + j);
}
//否则继续
else {
j++;
}
}
}
}
}