一种非极大值抑制(non_max_suppression, nms)的代码实现方式
目录
- 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的影响,这样就得到检测框在原图中的位置。具体步骤如下:
- 检测框先向上移动t个像素,再向左移动p个像素,其中t、p表示在上方向、左方向padding的像素个数,具体操作将x1 = x1 - p, x2 = x2 - p, y1 = y1 - t, y2 = y2 - t; 这样就得到检测框在没有padding操作下的位置(即以红色框左上角为原点的位置);
- 去除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,即得到原始图像的位置。
- 代码如下:
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)的代码实现方式相关推荐
- 非极大值抑制(NMS)-Yolov4(二)
非极大值抑制 非极大值抑制也属于后处理一部分,单独说可能会清楚一点,之所以要进行这步操作,原因在于很多时候一个目标存在多个预测框,这时我们需要选出最好的那个作为预测结果.怎么选的过程就是非极大值抑制操 ...
- 目标定位和检测系列:交并比(IOU)和非极大值抑制(NMS)的python与C/C++实现
Python实现 交并比(Intersection over Union)和非极大值抑制是(Non-Maximum Suppression)是目标检测任务中非常重要的两个概念.例如在用训练好的模型进行 ...
- 非极大值抑制(NMS)的几种实现优化
因为之前对比了RoI pooling的几种实现,发现python.pytorch的自带工具函数速度确实很慢,所以这里再对Faster-RCNN中另一个速度瓶颈NMS做一个简单对比试验. 这里做了四组对 ...
- 【深度学习】:非极大值抑制(NMS)详解
非极大值抑制(Non-maximum suppression,NMS)是一种去除非极大值的算法,常用于计算机视觉中的边缘检测.物体识别等.Non-Maximum Suppression的翻译是非&qu ...
- 非极大值抑制(NMS)
极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索.这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的 ...
- 数学--数据处理--非极大值抑制(NMS)
在目标检测中应用的多,实际上只要涉及到类似的数据处理问题,都可以用非极大值抑制方法. 一.在基于深度学习(各种CNN)模型的目标检测案例中出现的较多,还涉及到IoU(交并比的概念).参考了这篇博客:h ...
- 【深度学习】非极大值抑制Non-Maximum Suppression(NMS)一文搞定理论+多平台实现...
薰风说 Non-Maximum Suppression的翻译是非"极大值"抑制,而不是非"最大值"抑制.这就说明了这个算法的用处:找到局部极大值,并筛除(抑制) ...
- 下拉多选择框 实现方式_非极大值抑制Non-Maximum Suppression(NMS)一文搞定理论+多平台实现...
这是独立于薰风读论文的投稿,作为目标检测模型的拓展阅读,目的是帮助读者详细了解一些模型细节的实现. 薰风说 Non-Maximum Suppression的翻译是非"极大值"抑制, ...
- NMS(Non-Maximum Suppression)非极大值抑制
非极大值抑制 概述 在目标检测领域,我们经常用到非极大值抑制(NMS),NMS就是在局部范围内抑制不是极大值的目标,只保留极大值. 原理 在检测任务重,我们会得到一批具有置信度S的bbox列表B,首先 ...
最新文章
- 文本框 清空_VBA代码中利用文本框,完成人机对话过程
- VC如何在单文档里显示对话框
- url的关键字不知道是uft-8还是GBK
- ZooKeeper 的工作流程
- 某项目网络实施中的几个关键点解析
- java中sping基础_Java回顾之Spring基础
- Qt4_Shreadsheet电子表应用
- 我的 HTTP/1.1 好慢啊!
- CAD如何导出PDF格式
- UnRaid安装CloudDrive以实现阿里云盘、天翼云盘、115网盘挂载
- python求不规则图形面积_python计算不规则图形面积算法
- 双非本科地信前端面试题目
- 64位windows系统的PatchGuard
- 基于Hi3516DV300rtmp交叉编译移植
- ISIS Neighbor Net Type DIS
- 广东省计算机二级ps操作题题库,广东省计算机二级考试ps选择题.doc
- ROT13 - 维基百科,自由的百科全书
- [31] FatMouse and Cheese
- 中e管家婚后有孩子怎么理财
- 【Linux网络编程】网络基础 和 socket套接字 服务器与客户端 详细案例说明