非极大值抑制NMS在目标检测,定位等领域是一种被广泛使用的方法。对于目标具体位置定位过程,不管是使用sw(sliding Window)还是ss(selective search)方法,都会产生好多的候选区域。实际看到的情形就是好多区域的交叉重叠,难以满足实际的应用。非极大值抑制是一个迭代-遍历-消除的过程。如图所示。
NMS简单来说就是对于有相交的就选取其中置信度最高的一个作为最后结果,对于没相交的就直接保留下来,作为最后结果。(中间有个阈值限定,来判断是否相交)
matlab代码实现:
function pick = nms(boxes, overlap)
%boxes表示目标检测与定位时,产生多少个矩形框,通常是m*n列,m表示为矩形框的个数,n的前4列表示x1,y1,x2,y2,(x1,y1表示左上角坐标,x2,y2表示右下角坐标),后面的n-4列表示有n-4个特征的置信度
%overlap为设定值,来表示是否相交
if isempty(boxes)
pick = [];
else
x1 = boxes(:,1); %所有候选框的左上角顶点x1
y1 = boxes(:,2); %所有候选框的左上角顶点y1
x2 = boxes(:,3); %所有候选框的右下角顶点x2
y2 = boxes(:,4); %所有候选框的右下角顶点y2
s = boxes(:,5); %所有候选框的置信度,可以包含1列或者多列,用于表示不同准则的置信度,在此只考虑一种
area = (x2-x1+1) .* (y2-y1+1);%所有候选框的面积(若对.*不理解,请查看我上一篇博客)
[vals, I] = sort(s); %将所有候选框进行从小到大排序,vals为排序后结果,I为排序后标签
pick = s*0;
count=1;
while ~isempty(I)
last = length(I); %last代表标签I的长度,即最后一个元素的位置,(matlab矩阵从1开始计数)
i = I(last); %所有候选框的中置信度最高的那个的标签赋值给i
pick(count) =i; %将i存入pick中(即将置信度最高的索引值传输到pick)
count+=1
for pos = 1:last-1 %从1到倒数第二个进行循环
j = I(pos); %得到pos位置的标签,赋值给j
xx1 = max(x1(i), x1(j));%左上角最大的x(求两个方框的公共区域)
yy1 = max(y1(i), y1(j));%左上角最大的y
xx2 = min(x2(i), x2(j));%右下角最小的x
yy2 = min(y2(i), y2(j));%右下角最小的y
w = xx2-xx1+1; %公共区域的宽度
h = yy2-yy1+1; %公共区域的高度
if w > 0 && h > 0 %w,h全部>0,证明2个候选框相交
o = w * h / area(j);%计算overlap比值,即交集占候选框j的面积比例
if o<overlap %如果大于设置的阈值就去掉候选框j,因为候选框i的置信度最高
k=1;
I(k)=I(pos);
k+=1;
end
end
end
end
pick=pick(1:count-1)
end