首页 > 其他分享 >darknet | darknet之nms do_nms_sort详解

darknet | darknet之nms do_nms_sort详解

时间:2024-03-30 21:59:27浏览次数:12  
标签:sort box nms ++ darknet thresh dets total

在 yolo 模型 inference 执行完成后,会产生很多的冗余结果,此时就需要调用 nms 对冗余结果进行去重

nms 函数在 darknet 框架中是 do_nms_sort 函数,位于 box.c 文件中,源码如下:

void do_nms_sort(detection *dets, int total, int classes, float thresh)
{
    int i, j, k;
    k = total -1;
    for(i = 0; i <= k; ++i)
        {
            if(dets[i].objectness == 0)
            {
                detection swap = dets[i];
                dets[i] = dets[k];
                dets[k] = swap;
                --k;
                --i;
            }
        }
    total = k + 1;

    for(k = 0; k < classes; ++k)
        {
            for(i = 0; i < total; ++i)
                {
                    dets[i].sort_class = k;
                }
            qsort(dets, total, sizeof(detection), nms_comparator);
            for(i = 0; i < total; ++i)
                {
                    if(dets[i].prob[k] == 0) continue;
                    box a = dets[i].bbox;
                    for(j = i + 1; j < total; ++j)
                        {
                            box b = dets[j].bbox;
                            if(box_iou(a, b) > thresh)
                            {
                                dets[j].prob[k] = 0;
                            }
                        }
                }
        }
}

现对 do_nms_sort 过程做详细分解:

for(i=0; i<=k; ++i)
{
  if(dets[i].objectness == 0)
  {
    detection swap = dets[i];
    dets[i] = dets[k];
    dets[k] = swap;
    --k;
    --i;
  }
}

上述循环过程的功能是将没有物体的检测结果由后向前交换,--k 表示最后一个位置向前移动一个位置,--i 后再++i 表示 i 的位置没有改变,之所以采用这一做法的原因是,交换后的检测结果可能同样 objectness 为 0,因此先保持在原位置不变,当检测结果的 objectness 不为 0 时,才移动到下一个物体。

经过上述过程,所有检测结果中不包含物体的全部被移动到了最后,包含物体的检测结果全部被移动到了数组前方。

for(k = 0; k < classes; ++k){
    for(i = 0; i < total; ++i){
        dets[i].sort_class = k;
    }
    qsort(dets, total, sizeof(detection), nms_comparator);
    for(i = 0; i < total; ++i){
        if(dets[i].prob[k] == 0) continue;
        box a = dets[i].bbox;
        for(j = i+1; j < total; ++j){
            box b = dets[j].bbox;
            if (box_iou(a, b) > thresh){
                dets[j].prob[k] = 0;
            }
        }
    }
}

然后按照类别对检测结果进行排序,排序的依据是某个检测结果属于某一类的概率,调用 nms_comparator 函数:

for(i = 0; i < total; ++i){
    if(dets[i].prob[k] == 0) continue;
    box a = dets[i].bbox;
    for(j = i+1; j < total; ++j){
        box b = dets[j].bbox;
        if (box_iou(a, b) > thresh){
            dets[j].prob[k] = 0;
        }
    }
}

最后一个二重循环的作用是,计算两个检测结果之间的iou,若二者之间的iou大于thresh,则将后者直接置0,认为上述两个框是同一个框。此处代码中给出的thresh是0.45。但上述做法实际上产生了一个问题,若两个物体重叠部分大于thresh,则会造成其中一个物体的丢失,进而造成准确率的下降。解决上述问题已有一些方法,但不是本文的重点,此处先暂且不表。

至此do_nms_sort的过程就分析完成了,总结起来就是三个过程:

  • 1)去除没有物体的检测结果。
  • 2)按照检测结果类别排序。
  • 3)计算检测结果之间的iou,若大于thresh,则舍去

标签:sort,box,nms,++,darknet,thresh,dets,total
From: https://blog.csdn.net/m0_57195758/article/details/137063393

相关文章

  • sort函数对vector一维或者二维数组排序
    目录sort对一维数组排序1、sort对一位数组升序排序2、sort对一维数组降序排序sort对二维数组排序1、sort默认对横坐标进行升序排序,如下:2、使用自定义排序对纵坐标进行升序排序:额外知识:对横坐标进行降序排列,当横坐标相同时,对纵坐标进行升序排序sort对一维数组排序......
  • darknet框架训练YOLOv7模型与工业缺陷检测
    1.darkne介绍Darknet是一个开源的深度学习框架,由JosephRedmon(YOLO~YOLOv3作者或参与者)开发,主要用于实现神经网络模型。这个框架最初是为了实现计算机视觉任务而创建的,尤其是目标检测。其中最著名的应用之一就是YOLO(YouOnlyLookOnce)系列目标检测算法。以下是......
  • LeetCode-21 Merge Two Sorted Lists
    21.MergeTwoSortedLists EasyYouaregiventheheadsoftwosortedlinkedlists list1 and list2.Mergethetwolistsintoone sorted list.Thelistshouldbemadebysplicingtogetherthenodesofthefirsttwolists.Return theheadofthemerg......
  • Kruskal最小生成树【详细解释+动图图解】&【sort中的cmp函数】& 【例题:洛谷P3366 【模
    文章目录Kruskal算法简介Kruskal算法前置知识sort中的cmp函数算法思考样例详细示范与解释kruskal模版code↓例题:洛谷P3366【模板】最小生成树code↓完结撒花QWQKruskal算法简介Kr......
  • std::sort 错误"Expression : invalid operator <"
    解决:std::sort的比较函数,切记仅使用小于或大于,不要使用小于等于或大于等于。即所谓的“strictweakordering”,也就是说,如果a==b,则返回的应该是false,如果返回的是true,则会出上面的错这个问题是标准库sort实现导致的参考https://blog.csdn.net/qq_35097289/article/details/1046......
  • 非极大值抑制篇 | YOLOv8更换NMS之DIoU-NMS / CIoU-NMS / EIoU-NMS / GIoU-NMS / GIoU
    前言:Hello大家好,我是小哥谈。YOLOv8中的NMS指非极大值抑制(Non-MaximumSuppression),它是一种用于目标检测算法中的后处理技术。在检测到多个重叠的边界框时,NMS可以帮助选择最佳的边界框。NMS的工作原理是首先根据预测边界框的置信度对它们进行排序,然后从置信度最高的边界框开......
  • 简单介绍NMS的实现方法
    https://www.jb51.net/article/229498.htm #!/usr/bin/envpython3#-*-coding:utf-8-*-"""CreatedonMonMay721:45:372018@author:lps"""importnumpyasnpboxes=np.array([[100,100,210,210,0.72],[250,250......
  • python中sort的key关键字解释
    在Python中,sort() 方法是用于对列表进行排序的函数。sort() 方法可以接受一个关键字参数 key,该参数允许你指定一个函数,用于在排序过程中生成排序的依据。这个关键字参数的作用是告诉 sort() 方法如何理解列表中的元素应该被排序。下面是对 sort() 方法的 key 参数的讲......
  • 快速排序 (Quick Sort)
    publicstaticvoidmain(String[]args){int[]arr={9,5,7,3,1,6,8,4,2};quickSort(arr,0,arr.length-1);}privatestaticvoidquickSort(int[]arr,intleft,intright){if(left>=right){return;}//先排序一遍,再递归......
  • 希尔排序(Shell Sort)
    publicstaticvoidmain(String[]args){int[]arr={9,6,8,4,2,5,7,3,1};int[]arr2={9,6,8,4,2,5,7,3,1};shellSort(arr);System.out.println("=====================");shellSort2(arr2);}/***shell排序,插入排序......