在这之前强调下极大值、最大值的区别:在一个函数曲线中,极大值可以有多个,最大值只有一个。所有非极大值抑制是抑制不是极大值的部分,一组数据经过非极大值抑制之后会得到至少一个的返回值。
算法思想:
非极大值抑制的方法是:先假设有6个矩形框,根据分类器的类别分类概率做排序,假设从小到大属于车辆的概率 分别为A、B、C、D、E、F。 (1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值; (2)假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。 (3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。 就这样一直重复,找到所有被保留下来的矩形框。
原文: https://www.cnblogs.com/makefile/p/nms.html © 康行天下
算法实现C++:
1 typedef struct{ 2 Rect box; 3 float confidence; 4 int index; 5 }BBOX; 6 7 static float get_iou_value(Rect rect1,Rect rect2) 8 { 9 int xx1,yy1,xx2,yy2; 10 xx1=max(rect1.x,rect2.x); 11 yy1=max(rect1.y,rect2.y); 12 xx2=min(rect1.x+rext1.width-1,rect2.x+rect2.width-1); 13 yy2=min(rect1.y+rect1.height-1,rect2.y+rect2.height-1); 14 15 int insection_width,insection_height; 16 insection_width=max(0,xx2-xx1+1); 17 insection_height=max(0,yy2-yy1+1); 18 19 float insection_area,uniion_area,iou; 20 insection_area=float(insection_width)*insection_height; 21 union_area=float(rect1.width*rect1.height+rect2.width*rect2.height-insection_area); 22 iou=insection_area/union_area; 23 return iou; 24 } 25 26 void nms_boxes(vector<Rect> &boxes,vector<float>&confidences,float confThreshold,float nmsThreshold,vector<int> &indices) 27 { 28 BBOX bbox; 29 vector<BBOX> bboxes; 30 int i,j; 31 for(i=0;i<boxes.size();i++) 32 { 33 bbox.box=boxes[i]; 34 bbox.confidence=confidences[i]; 35 bbox.index=i; 36 bboxes.push_back(bbox); 37 } 38 sort(bboxes.begin(),bboxes.end());//sort by confidence 39 int updated_size=bboxes.size(); 40 for(i=0;i<updates_size;i++) 41 { 42 if(bboxes[i].confidence<confThreshold) 43 continue; 44 indices.push_back(bboxes[i].index); 45 for(j=i+1;j<updated_size;j++) 46 { 47 float iou=get_iou_value(bboxes[i].box,bboxes[j].box); 48 if(iou>numThreshold) 49 { 50 bboxes.erase(bboxes.begin()+j); 51 updated_size=bboxes.size(); 52 } 53 } 54 } 55 }
希望能够帮到正在疑惑的你!