目录

  • 1. 简介
  • 2. 代码
    • 2.1 坐标形式转换
    • 2.2 iou计算
    • 2.3 nms

1. 简介

  • 非极大值抑制,non_max_suppression,简称nms,常用于目标检测的后处理,去除多余的检测框。
  • 流程大致是:根据某个类别,按照检测框的置信度从大到小排序,选择置信度最高的检测框记为A,计算A与剩余的检测框(B1、B2、… BN)的iou值,若iou值大于设置的阈值,则将B1、B2、… BN中对应的检测框去掉,如此重复操作。

2. 代码

  • 结合yolov5模型输出,实现nms的代码。
  • 在yolov5中,模型的输出记为pred,(这里pred是模型的直接输出,还没有经过后处理),pred的shape为:(batch_size, num_bbox, 4 + 1 + num_classes),其中batch_size表示输入的图片数量,num_bbox表示检测到的矩形框数量,4表示4个坐标,1表示检测框的置信度,num_classes表示每个类别的分数。
  • pred的检测框坐标格式为:xywh,即检测框的中心坐标以及它的宽高

2.1 坐标形式转换

# coding=utf-8
import numpy as npdef xywh2xyxy(x):y = np.copy(x)y[..., 0] = x[..., 0] - x[..., 2] / 2  # top left xy[..., 1] = x[..., 1] - x[..., 3] / 2  # top left yy[..., 2] = x[..., 0] + x[..., 2] / 2  # bottom right xy[..., 3] = x[..., 1] + x[..., 3] / 2  # bottom right yreturn y

2.2 iou计算

def cal_iou(det1, det2):det1_x1, det1_y1 = det1[..., 0], det1[..., 1]det1_x2, det1_y2 = det1[..., 2], det1[..., 3]det2_x1, det2_y1 = det2[..., 0], det2[..., 1]det2_x2, det2_y2 = det2[..., 2], det2[..., 3]x1 = np.maximum(det1_x1, det2_x1)y1 = np.maximum(det1_y1, det2_y1)x2 = np.minimum(det1_x2, det2_x2)y2 = np.minimum(det1_y2, det2_y2)area_det1 = (det1_y2 - det1_y1 + 1) * (det1_x2 - det1_x1 + 1)area_det2 = (det2_y2 - det2_y1 + 1) * (det2_x2 - det2_x1 + 1)inter = np.maximum(0, (y2 - y1 + 1)) * np.maximum(0, (x2 - x1 + 1))ious = inter / (area_det1 + area_det2 - inter)return ious

2.3 nms

def nms(detections, conf_thres=0.4, nms_thres=0.5):outputs = []detections = xywh2xyxy(detections)               # 检测框格式转换 xywh -> xyxydetections[..., 5:] *= detections[..., 4:5]      # 类别的分数是用obj_conf * cls_confnum_classes = detections.shape[2] - 5            # detections shape: (batch_size, num_bbox, 4 + 1 + num_classes)candidates = detections[..., 4] > conf_thres     # 用于后续的过滤筛选for img_idx, dets in enumerate(detections):output = []dets = dets[candidates[img_idx]]             # 根据conf_thres过滤indexes = dets[..., 4].argsort()[::-1]       # 根据obj_conf大小排序dets = dets[indexes]classes_dets = dets[..., 5:].argmax(axis=1)  # 每个检测框的类别for cls in range(num_classes):               # 按类别循环遍历dets_cls = dets[classes_dets == cls]     # shape: (num_bbox, 4 + 1 + num_classes)while len(dets_cls):det_select = dets_cls[0]# det_select shape: (x1, y1, x2, y2, score, label)det_select = np.concatenate((det_select[..., :4], [det_select[..., 5:].max(), cls]))output.append(det_select)dets_cls = dets_cls[1:]if len(dets_cls):ious = cal_iou(det_select, dets_cls)indexes = np.where(ious <= nms_thres)[0]dets_cls = dets_cls[indexes]outputs.append(output)return np.array(outputs)

这里得到的outputs还需要映射回原图像,以下图为例:

  • 如图所示,原始图像经过resize之后得到红色框,红色框经过padding得到黑色框,绿色框表示检测框在黑色框中的位置(即以黑色框左上角为原点的位置)。
  • 将检测结果映射回原始图像时,要先去除padding的影响,再去除resize的影响,这样就得到检测框在原图中的位置。具体步骤如下:
  1. 检测框先向上移动t个像素,再向左移动p个像素,其中t、p表示在上方向、左方向padding的像素个数,具体操作将x1 = x1 - p, x2 = x2 - p, y1 = y1 - t, y2 = y2 - t; 这样就得到检测框在没有padding操作下的位置(即以红色框左上角为原点的位置);
  2. 去除resize的影响。只要将坐标除以图像resize后与原图像的的比例gain即可,假设原始图像高、宽为ori_h, ori_w,resize之后的宽高为new_h, new_w,则ratio = min(new_h/ori_h, new_w/ori_w), 然后让x1 = x1/ratio, y1 = y1/ratio, x2 = x2/ratio, y2 = y2/ratio,即得到原始图像的位置。
  3. 代码如下:
def scale_coords(output, ori_shape, ratio=1.0, top_pad=0, left_pad=0):ori_h, ori_w = ori_shapeoutput[:, [0, 2]] -= left_padoutput[:, [1, 3]] -= top_padoutput[:, :4] /= ratiooutput[:, [0, 2]] = output[:, [0, 2]].clip(0, ori_w)  # x1, x2output[:, [1, 3]] = output[:, [1, 3]].clip(0, ori_h)  # y1, y2

完成。

一种非极大值抑制(non_max_suppression, nms)的代码实现方式相关推荐

  1. 非极大值抑制(NMS)-Yolov4(二)

    非极大值抑制 非极大值抑制也属于后处理一部分,单独说可能会清楚一点,之所以要进行这步操作,原因在于很多时候一个目标存在多个预测框,这时我们需要选出最好的那个作为预测结果.怎么选的过程就是非极大值抑制操 ...

  2. 目标定位和检测系列:交并比(IOU)和非极大值抑制(NMS)的python与C/C++实现

    Python实现 交并比(Intersection over Union)和非极大值抑制是(Non-Maximum Suppression)是目标检测任务中非常重要的两个概念.例如在用训练好的模型进行 ...

  3. 非极大值抑制(NMS)的几种实现优化

    因为之前对比了RoI pooling的几种实现,发现python.pytorch的自带工具函数速度确实很慢,所以这里再对Faster-RCNN中另一个速度瓶颈NMS做一个简单对比试验. 这里做了四组对 ...

  4. 【深度学习】:非极大值抑制(NMS)详解

    非极大值抑制(Non-maximum suppression,NMS)是一种去除非极大值的算法,常用于计算机视觉中的边缘检测.物体识别等.Non-Maximum Suppression的翻译是非&qu ...

  5. 非极大值抑制(NMS)

    极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索.这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的 ...

  6. 数学--数据处理--非极大值抑制(NMS)

    在目标检测中应用的多,实际上只要涉及到类似的数据处理问题,都可以用非极大值抑制方法. 一.在基于深度学习(各种CNN)模型的目标检测案例中出现的较多,还涉及到IoU(交并比的概念).参考了这篇博客:h ...

  7. 【深度学习】非极大值抑制Non-Maximum Suppression(NMS)一文搞定理论+多平台实现...

    薰风说 Non-Maximum Suppression的翻译是非"极大值"抑制,而不是非"最大值"抑制.这就说明了这个算法的用处:找到局部极大值,并筛除(抑制) ...

  8. 下拉多选择框 实现方式_非极大值抑制Non-Maximum Suppression(NMS)一文搞定理论+多平台实现...

    这是独立于薰风读论文的投稿,作为目标检测模型的拓展阅读,目的是帮助读者详细了解一些模型细节的实现. 薰风说 Non-Maximum Suppression的翻译是非"极大值"抑制, ...

  9. NMS(Non-Maximum Suppression)非极大值抑制

    非极大值抑制 概述 在目标检测领域,我们经常用到非极大值抑制(NMS),NMS就是在局部范围内抑制不是极大值的目标,只保留极大值. 原理 在检测任务重,我们会得到一批具有置信度S的bbox列表B,首先 ...

最新文章

  1. 文本框 清空_VBA代码中利用文本框,完成人机对话过程
  2. VC如何在单文档里显示对话框
  3. url的关键字不知道是uft-8还是GBK
  4. ZooKeeper 的工作流程
  5. 某项目网络实施中的几个关键点解析
  6. java中sping基础_Java回顾之Spring基础
  7. Qt4_Shreadsheet电子表应用
  8. 我的 HTTP/1.1 好慢啊!
  9. CAD如何导出PDF格式
  10. UnRaid安装CloudDrive以实现阿里云盘、天翼云盘、115网盘挂载
  11. python求不规则图形面积_python计算不规则图形面积算法
  12. 双非本科地信前端面试题目
  13. 64位windows系统的PatchGuard
  14. 基于Hi3516DV300rtmp交叉编译移植
  15. ISIS Neighbor Net Type DIS
  16. 广东省计算机二级ps操作题题库,广东省计算机二级考试ps选择题.doc
  17. ROT13 - 维基百科,自由的百科全书
  18. [31] FatMouse and Cheese
  19. 中e管家婚后有孩子怎么理财
  20. 【Linux网络编程】网络基础 和 socket套接字 服务器与客户端 详细案例说明

热门文章

  1. 《设计模式之禅》中23种设计模式demo汇总
  2. 个人博客如何选择虚拟主机
  3. 测试温度时共模电压的考虑
  4. 服务器怎么装虚拟打印机,虚拟打印机安装不成功的原因
  5. Liunx磁盘管理——LVM
  6. 文件末尾eof_什么是EOF(文件末尾)? PHP,C ++,C,Python,Java的示例
  7. opencv视频采集
  8. Arduino_mega2560+DynamixelShield控制MX-64R舵机
  9. Java参数变量_Java变量参数
  10. 安卓 获取屏幕坐标(点击屏幕获取坐标)