SyGoing / LFFD-with-ncnn

A C++ API of the LFFD with ncnn
99 stars 25 forks source link

about nms #10

Closed vicwer closed 4 years ago

vicwer commented 4 years ago

different nms lead to different results.

SyGoing commented 4 years ago

hello,@vicwer, so when using another nms ,the results is better or worse? , could you please provide more details?

vicwer commented 4 years ago

better nms

SyGoing commented 4 years ago

thank you , I will reimplement it

vicwer commented 4 years ago
score = inner_area / area1;

instead of

if(type == NMS_UNION)
{
    score = ...
}
else
{
    float min_area = ...
    score = ...
}
SyGoing commented 4 years ago

thank you

SyGoing commented 4 years ago

I have fixed it

SyGoing commented 4 years ago

type = NMS_MIN may be more correct

vicwer commented 4 years ago

实际上,既没有用NMS_MIN,也没有用NMS_UNION,作者保留当前得分最高的box,然后用剩余box和得分最高box取交集,使用交集依次和第二大的box做overlap,再使用阈值筛选。我用几张人脸多的图试了一下,这样nms合并的结果的确更好,其他两个方式会有几个box不能合并。代码在你之前一版nms改的化,只需要改一下求score的方式就可以,我把nms后的结果和原版做了对比,结果是一样的。

void nms(std::vector<FaceInfo>& input, std::vector<FaceInfo>& output, float threshold, int type)
{
    int box_num = input.size();
    std::vector<int> merged(box_num, 0);

    for(int i = 0; i < box_num; i++)
    {
        if(merged[i])
        {
            continue;
        }

        output.push_back(input[i]);

        float h0 = input[i].y2 - input[i].y1;
        float w0 = input[i].x2 - input[i].x1;

        for(int j = i + 1; j < box_num; j++)
        {
            if(merged[j])
            {
                continue;
            }

            float inner_x0 = input[i].x1 > input[j].x1 ? input[i].x1 : input[j].x1;
            float inner_y0 = input[i].y1 > input[j].y1 ? input[i].y1 : input[j].y1;
            float inner_x1 = input[i].x2 < input[j].x2 ? input[i].x2 : input[j].x2;
            float inner_y1 = input[i].y2 < input[j].y2 ? input[i].y2 : input[j].y2;

            float inner_h = inner_y1 - inner_y0 + 1;
            float inner_w = inner_x1 - inner_x0 + 1;

            inner_h = inner_h > 0 ? inner_h : 0;
            inner_w = inner_w > 0 ? inner_w : 0;

            float inner_area = inner_h * inner_w;

            float h1 = input[j].y2 - input[j].y1 + 1;
            float w1 = input[j].x2 - input[j].x1 + 1;

            float area1 = h1 * w1;

            float score = inner_area / area1;

            if(score > threshold)
            {
                merged[j] = 1;
            }
        }
    }
}
SyGoing commented 4 years ago

好的,你看代码很仔细,我马上改一下

vicwer commented 4 years ago

因为c和python结果不一致,迫不得已追原因,感谢你的工作!

SyGoing commented 4 years ago

这个当时也没太注意,nms我就用现有的,没有看作者的nms,谢谢你了,这下结果能够对上了,其他的几个实现我也改过来了