非极大值抑制算法

1. 算法原理

  非极大值抑制算法(Non-maximum suppression, NMS)的本质是搜索局部极大值,抑制非极大值元素。

2. 3邻域情况下NMS的实现

  3邻域情况下的NMS即判断一维数组I[W]的元素I[i](2<=i<=W-1)是否大于其左邻元素I[i-1]和右邻元素I[i+1],算法流程如下图所示:

  

  a. 算法流程3-5行判断当前元素是否大于其左邻与右邻元素,如符合条件,该元素即为极大值点。对于极大值点I[i],已知I[i]>I[i+1],故无需对i+1位置元素做进一步处理,直接跳至i+2位置,对应算法流程第12行。

    

  b. 若元素I[i]不满足算法流程第3行判断条件,将其右邻I[i+1]作为极大值候选,对应算法流程第7行。采用单调递增的方式向右查找,直至找到满足I[i]>I[i+1]的元素,若i<=W-1,该点即为极大值点,对应算法流程第10-11行。

    

3. NMS在物体检测中的应用

  物体检测中应用NMS算法的主要目的是消除多余(交叉重复)的窗口,找到最佳物体检测位置。

  

  如上图所示,人脸检测中,虽然每个窗口均检测到人脸,但仅需给出一个最有可能表征人脸的窗口。

4. 算法程序

function pickLocate = nms(boxes, overlap)

% Non-maximum suppression.

% In object detect algorithm, select high score detections and skip windows

% covered by a previously selected detection.

%

% input – boxes : object detect windows.

%                 xMin yMin xMax yMax score.

%         overlap : suppression threshold.

% output – pickLocate : number of local maximum score.

boxes = double(boxes);

if isempty(boxes)

    pickLocate = [];

else

    xMin = boxes(:, 1);

    yMin = boxes(:, 2);

    xMax = boxes(:, 3);

    yMax = boxes(:, 4);

    

    s = boxes(:, end);

    

    % area of every detected windows.

    area = (xMax – xMin + 1) .* (yMax – yMin + 1);

    

    % sort detected windows based on the score.

    [vals, I] = sort(s);

    

    pickLocate = [];

    while ~isempty(I)

        last = length(I);

        i = I(last);

        

        pickLocate = [pickLocate; i];

        suppress = [last];

        

        for pos = 1 : last – 1

            j = I(pos);  

            

            % covered area.

            xx1 = max(xMin(i), xMin(j));

            yy1 = max(yMin(i), yMin(j));

            xx2 = min(xMax(i), xMax(j));

            yy2 = min(yMax(i), yMax(j));

            

            w = xx2 – xx1 + 1;

            h = yy2 – yy1 + 1;

            

            if ((w > 0) && (h > 0))

                % compute overlap.

                o = w * h / min(area(i), area(j));

                

                if (o > overlap)

                    suppress = [suppress; pos];

                end

            end

            

            % 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;

            % o = inter ./ (area(i) + area(I(1:last-1)) – inter);

            

            % saving the windows which o less than threshold.

            % I = I(o <= overlap);

        end

        I(suppress) = [];

    end

end