Megvii-BaseDetection / YOLOX

YOLOX is a high-performance anchor-free YOLO, exceeding yolov3~v5 with MegEngine, ONNX, TensorRT, ncnn, and OpenVINO supported. Documentation: https://yolox.readthedocs.io/
Apache License 2.0
9.29k stars 2.18k forks source link

TRT cpp inference后处理时nms不分类别? #1366

Open lufanma opened 2 years ago

lufanma commented 2 years ago

为什么YOLOX/demo/TensorRT/cpp/yolox.cpp中decode后处理时nms不分类别来做呢?我看了下好像是多个类别一起做的么?

static void nms_sorted_bboxes(const std::vector& faceobjects, std::vector& picked, float nms_threshold) { picked.clear(); // 将数组置空

const int n = faceobjects.size();

std::vector<float> areas(n);
for (int i = 0; i < n; i++)
{
    areas[i] = faceobjects[i].rect.area();
}

for (int i = 0; i < n; i++)
{
    const Object& a = faceobjects[i];

    int keep = 1;
    for (int j = 0; j < (int)picked.size(); j++)
    {
        const Object& b = faceobjects[picked[j]];

        // intersection over union
        float inter_area = intersection_area(a, b);
        float union_area = areas[i] + areas[picked[j]] - inter_area;
        // float IoU = inter_area / union_area
        if (inter_area / union_area > nms_threshold)
            keep = 0;
    }

    if (keep)
        picked.push_back(i);
}

}

liqianqi commented 1 year ago

这个应该不用分类类别,他是先按置信度由大到小排序,然后第一轮大循环把最大置信度的目标存放到picked里面,第二轮之后的小循环里面就是将i指向的目标和picked里面每个目标比较IOU,如果IOU值比较大,那么淘汰这个目标,不把他存到picked。也就是picked里面存储的都是互不相交的(说法不太对,就是IOU值比较小,相交程度比较低),所以按照这个逻辑不用分类类别。但是我感觉这一块有个错误,比如:

        if (inter_area / union_area > nms_threshold)
        {    
            keep = 0;
            break;
        }

我的想法是这里应该加个break,一旦这一轮大循环指向的目标和picked里面当中有任何一次的IOU大于阈值,都应该直接被淘汰,也就是keep置0后直接跳过当前小循环。我不知道我这个想法对不对。