大家好,我是陆砚码。今天我们来聊聊人脸检测中常用的一个算法——非极大值抑制(NMS)。这个算法在边缘检测、目标检测等领域都有广泛应用。接下来,我们就以人脸检测为例,来深入了解一下NMS的工作原理,并看看如何在Matlab和C++中实现它。
人脸检测的一些概念
- 分类器:人脸检测器的核心,用于判断给定图片是否为人脸。
- 检测器:通过在原始图像上生成多个窗口,并resize到固定尺寸,然后送分类器判断,从而实现检测。
由于滑动窗口的存在,同一个人可能被检测出多个框。我们的目标就是通过NMS算法,只保留一个最优的框。
NMS算法原理
NMS算法的核心是一个迭代-遍历-消除的过程:
- 将所有框的得分排序,选中最高分及其对应的框。
- 遍历其余的框,如果与当前最高分框的重叠面积(IOU)大于一定阈值,则删除该框。
- 从未处理的框中继续选一个得分最高的,重复上述过程。
Matlab示例代码
%% NMS:non maximum suppression
function pick = nms(boxes,threshold,type)
% boxes: m x 5,表示有m个框,5列分别是[x1 y1 x2 y2 score]
% threshold: IOU阈值
% type:IOU阈值的定义类型
% 输入为空,则直接返回
if isempty(boxes)
pick = [];
return;
end
% 依次取出左上角和右下角坐标以及分类器得分(置信度)
x1 = boxes(:,1);
y1 = boxes(:,2);
x2 = boxes(:,3);
y2 = boxes(:,4);
s = boxes(:,5);
% 计算每一个框的面积
area = (x2-x1+1) .* (y2-y1+1);
%将得分升序排列
[vals, I] = sort(s);
%初始化
pick = s*0;
counter = 1;
% 循环直至所有框处理完成
while ~isempty(I)
last = length(I); %当前剩余框的数量
i = I(last);%选中最后一个,即得分最高的框
pick(counter) = i;
counter = counter + 1;
%计算相交面积
xx1 = max(x1(i), x1(I(1:last-1)));
yy1 = max(y1(i), y1(I(1:last-1)));
xx2 = min(x2(i), x2(I(1:last-1)));
yy2 = min(y2(i), y2(I(1:last-1)));
w = max(0.0, xx2-xx1+1);
h = max(0.0, yy2-yy1+1);
inter = w.*h;
%不同定义下的IOU
if strcmp(type,'Min')
%重叠面积与最小框面积的比值
o = inter ./ min(area(i),area(I(1:last-1)));
else
%交集/并集
o = inter ./ (area(i) + area(I(1:last-1)) - inter);
end
%保留所有重叠面积小于阈值的框,留作下次处理
I = I(find(o<=threshold));
end
pick = pick(1:(counter-1));
end
小结与拓展
NMS算法是一种简单而有效的目标检测方法,通过迭代消除冗余框,提高检测的准确性。除了人脸检测,NMS算法还可以应用于其他目标检测任务,如物体检测、行人检测等。
如果你对编程技术感兴趣,欢迎关注「思享编程网」(www.sxgpb.com),这里有很多实用的编程技巧和知识等你来发现。
我是陆砚码,我们下期再见!
