深度学习_NMS代码详解YOLOv3及Fast R-CNN例子

2023-05-16

先放Fast R-CNN的NMS代码

这部分是关于 nms 实现的代码。后续再加下其他的版本。
流程:首先对检测结果的 score 取出最大的元素,然后将置信度最高的框与其他框取交集,计算 iou,将大于 iou 的筛去。然后对剩余的框进行如上操作。

import numpy as np
#这里的NMS是单类别的!多类别则只需要在外加一个for循环遍历每个种类即可
def py_cpu_nms(dets, thresh):
    """Pure Python NMS baseline."""
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    scores = dets[:, 4]# 取出框的坐标和score

    areas = (x2 - x1 + 1) * (y2 - y1 + 1)# 计算面积
    order = scores.argsort()[::-1] # 用argsort升序,返回的是对应的索引。[::-1]这个呢。
	# a[-1] 取a的最后一个元素  a[:-1] 取除a的最后一个的所有元素
	# a[::-1] 取从后往前的元素。其实就是把scores的索引从大到小排了。
	# a[2::-1] 取a[2]及之前的所有元素,并从a[2]开始返回->a[1]->a[0]

    keep = []
    while order.size > 0:
        i = order[0] # i取最大score的索引

        keep.append(i)
		# 置信度高的预测框即当前框与其他框的交集
		# 选择的区域就是取最大的x1, y1和最小的 x2, y2
        xx1 = np.maximum(x1[i], x1[order[1:]])# 这个就是较差区域的左上角的坐标,下面以此类推
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])
		# 计算交叉区域的面积
        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h
		# 计算IOU,  相交区域 / (当前区域 + 某区域面积 - 相交区域面积)
        ovr = inter / (areas[i] + areas[order[1:]] - inter)
		# 保留IOU小于阈值的框
        inds = np.where(ovr <= thresh)[0]
		# #因为ovr数组的长度比order数组少一个,所以这里要将所有下标后移一位
        order = order[inds + 1]

    return keep

下面是YOLOv3的NMS代码:

def non_max_suppression(prediction, conf_thres=0.4, nms_thres=0.5):
    """
    Removes detections with lower object confidence score than 'conf_thres' and performs
    Non-Maximum Suppression to further filter detections.
    :param prediction: shape为 (batch_size, total_num_bbox, 85)
    :param conf_thres:
    :param nms_thres:
    :return:
    Returns detections with shape:
        (x1, y1, x2, y2, object_conf, class_score, class_pred)
    """
 
    # 把xywh转为x1y1x2y2
    prediction[..., :4] = xywh2xyxy(prediction[..., :4])
 
    # 把output输出化,初始化的结果就是batch_size大小
    output = [None for _ in range(len(prediction))]
 
    # 以每个图片进行处理
    for image_i, image_pred in enumerate(prediction):
        # 把置信度低于阈值的框过滤掉
        image_pred = image_pred[image_pred[:, 4] >= conf_thres]
 
        # 如果过滤后没有剩余的框则直接continue
        if not image_pred.size(0):
            continue
 
        # 计算每个框的置信度:是物体的置信度 乘以 类别预测置信度的最大值
        # prediction的shape为[batch_size x 10647 x 85]
		#10647个预测框,85指 xywh,score,以及80类别
        # img_pred[:, 5:].max(1)[0] 为取出每个框里面类别概率最大的值与置信度相乘
        score = image_pred[:, 4] * image_pred[:, 5:].max(1)[0]
        # 按照score降序
        image_pred = image_pred[(-score).argsort()]
 
        # 得到每一行类别最大的概率与类别代号,keepdim=True:输出的维度和输入维度相同
        # class_confs表示每个框类别置信度的最大值,class_preds表示该最大值对应的序号idx(即类别)
        class_confs, class_preds = image_pred[:, 5:].max(1, keepdim=True)
 
        # cat函数就是按某个维度进行拼接
		#detections:[x1,y1,x2,y2,conf,cls_conf,cls_idx]
		#其中0:3为x1y1x2y2,4为物体置信度score(detections按照score排序)
        # 5为该框中类别置信度的最大值,6为该最大值对应的类别索引
        detections = torch.cat((image_pred[:, :5], class_confs.float(), class_preds.float()), 1)
 
 		# 非极大值抑制
        keep_boxes = []
        while detections.size(0):
            # 看当前列表中的第一个框(即置信度最大的框)和所有剩余框的iou是否大于阀值,如果大于阀值需要考虑是否被丢弃
            # 这里的large_overlap表示重叠overlap过大的索引,这些索引的框可能会被丢弃,这里的阀值取的0.5
			#score最大的框(第一个框)和其他框做交并比,并把大于nms_thres的取出存入large_overlap
            large_overlap = bbox_iou(detections[0, :4].unsqueeze(0), detections[:, :4]) > nms_thres
 
            # 查看是否和第一个框预测的同一个类别标签,如果和第一个框预测的同样类别标签,则考虑是否被丢弃
            label_match = detections[0, -1] == detections[:, -1]
 
            # Indices of boxes with lower confidence scores, large IOUs and matching labels
            # 即同时满足 和第一个框iou大于阀值和类别相同,才丢弃这个框
            invalid = large_overlap & label_match
            weights = detections[invalid, 4:5]  # 要丢弃的框的物体置信度值
            # Merge overlapping bboxes by order of confidence
            # 满足上面条件的框,通过目标置信度对bbox做加权平均处理,用来计算平均框的位置。加权平均合并
            detections[0, :4] = (weights * detections[invalid, :4]).sum(0) / weights.sum()
			# 添加加权平均的detection
            keep_boxes += [detections[0]]
            detections = detections[~invalid] # 取剩余部分的预测值
        if keep_boxes:
		# torch.stack()沿着一个新维度对输入张量序列进行连接。 序列中所有的张量都应该为相同形状。
            output[image_i] = torch.stack(keep_boxes)# 非极大值抑制的结果
 
    return output
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度学习_NMS代码详解YOLOv3及Fast R-CNN例子 的相关文章

  • C语言中数的二进制、八进制、十进制以及十六进制表示及输出

    以十进制数163为例 xff1a 二进制的英文是Binary xff0c 简写为B或BIN xff0c 所以163 61 0b10100011 xff08 前面加上 0b 或 0B xff09 八进制的英文是Octal xff0c 简写为O
  • java-字符串数组排序

    问题 43 代码 xff1a 创建一个长度是8的字符串数组 使用8个长度是5的随机字符串初始化这个数组 对这个数组进行排序 xff0c 按照每个字符串的首字母排序 无视大小写 注1 xff1a 不能使用Arrays sort 要自己写 注2
  • python 装饰器

    1 装饰器 装饰器 Decorators 是Python的一个重要部分 简单地说 xff1a 他们是修改其他函数的功能的函数 他们有助于让我们的代码更简短 xff0c 也更Pythonic xff08 Python范儿 xff09 大多数初

随机推荐

  • Java的俩个list之间比较,判断是否一致的方法

    前文 我看了一篇博客 xff0c 是关于判断俩个list的 看完之后我觉得可能并不是很好 结合他的思路 xff0c 我重新整理了一下代码 同时也看了看String中的equals的实现 原文是 xff1a https blog csdn n
  • ARP地址解析过程(同一子网和不同子网)

    人们最熟悉的网络可以说是以太网 xff0c 而且人们都知道 xff0c 每块网卡都有一个编号 xff0c 也就是网卡地址 xff08 称为MAC地址 xff09 xff0c 代表计算机的物理地址 另外 xff0c 网络中的每一台计算机都分配
  • (2)树莓派3B连接隐藏wifi网络

    连接隐藏wifi可以使用nano编辑器打开wpa supplicant配置文件 xff1a sudo nano etc wpa supplicant wpa supplicant conf 在文件底部添加 xff1a network 61
  • 获取本地外网ip的api接口

    开发时偶尔会需要前端传客户端的ip地址 xff0c 以下方法可以获取客户端外网ip 1 新增加载js方法 export const loadScript 61 src 61 gt return new Promise resolve rej
  • Ubuntu 18.04 配置ibus中文拼音输入法

    Ubuntu 18 04系统想安装中文输入法 xff08 利用ibus输入法配置 xff09 只要三步 注意 xff1a 你的Ubuntu需要可以上网 xff01 xff01 xff01 因为要下载一系列安装包 第一步 xff1a 首先需要
  • VMware安装Kali后黑屏 只有左上角光标

    在安装过程中选择安装GRUB引导程序 xff0c 默认是否 xff0c 我们需要选择是
  • vCenter Server目录/storage/core,/storage/log 空间不足问题解决

    概述 xff1a VC是7 0的 xff0c 存储警告 storage core及 storage log目录空间不足 xff1b 且出现VC web管理页面运行缓慢 xff1b 用途概述 storage core xff1a 存储来自vC
  • C#反编译利器--dotPeek

    在开发项目的时候 xff0c 当项目数量变大 xff0c 源代码管理也是一件非常头疼的事 xff0c 如果没有专门的人员来管理代码 xff0c 没有code review机制的话 xff0c 代码很容易乱 xff0c 这就会导致现场的代码与
  • C/C++调用Rust编写的动态库

    目录 C C 43 43 调用Rust编写的动态库一 背景二 解决方案三 测试3 1 正确性检验3 2 内存安全检验 C C 43 43 调用Rust编写的动态库 一 背景 Rust通过大量的编译期检查能够有效避免程序运行时出现的各种内存问
  • 计蒜客习题-班长竞选 最小割 “二选一 方案不同有额外开销”模型

    设源点S xff0c 汇点T 对于所有赞成的人 从S连一条边到他们对应的点上 容量设为1 对于所有反对的人 从他们对应的点上连一条边到T 容量为1 对于所有有朋友 关系的a和b 在他们之间连一条无向边 容量为1 最小割可以用dinic跑出来
  • 百度之星2020 初赛第三场

    Discount Accepts 1432 Submissions 2728 Time Limit 2000 1000 MS Java Others Memory Limit 65536 65536 K Java Others Proble
  • 快速幂取模_C++

    一 题目背景 已知底数a xff0c 指数b和模数mo xff0c 求ans 61 ab mo 二 朴素算法 就是暴力啦 1 void power int a int b int mo 2 long long ans 61 1 3 for
  • python抓取Windows系统内存和CPU占用率

    python抓取Windows系统内存和CPU占用率 主要参考来源 xff1a https www jianshu com p 23c2a518019a 1 源代码 cpuget py from time import sleep strf
  • 汇编语言(十)——条件判断指令

    首先了解按位指令 xff0c 这里使用的技术也可以用于操作硬件设备控制位 xff0c 实现通信协议以及加密数据 xff0c 操作说明AND源操作数和目的操作数进行逻辑与操作OR源操作数和目的操作数进行逻辑或操作XOR源操作数和目的操作数进行
  • [Altium Designer] AD PCB中相同模块的布局布线方法(Room Copy方法)

    最近画的一个板子 xff0c 有12路4 20mA采集电路 xff0c 每一路的元件都是一样的 xff0c 恰好板子空间也够 xff0c 就想着能不能画好一个之后其他的可以 照抄 xff0c 网上查了一圈还真有 xff0c 那就是 Room
  • 【实用教程】VSPD虚拟串口工具——从此告别硬件串口调试

    modbus测试工具链接 xff1a https blog csdn net byxdaz article details 77979114 1 下载VSPD工具 VSPD下载链接 xff0c 点击这里直接下载 2 安装 解压后的安装包是这
  • PageHelper自定义count

    使用场景 web页面的查询功能太复杂 xff0c pageHelper自动生成的count语句相当于在查询语句外包一层count xff0c 查询速度比较慢 需要优化count语句 xff0c 所以才想起来自定义count语句 版本要求 5
  • angular 报错Can't bind to 'nzData' since it isn't a known property of 'nz-table'.

    在angular里添加了一个新的module后 xff0c 点击会报错 xff0c 无法加载 模块的路由 xff0c 并展示以下错误 解决办法 xff1a 检查是否有 import NgZorroAntdModule from 39 ng
  • python爬取b站数据

    爬取B站弹幕数据的API xff1a 96 https api bilibili com x v1 dm list so oid 61 XXX 96 我们要想知道这个oid是什么 xff0c 首先要获取到cid 弹幕数据的接口我们虽然找不到
  • 深度学习_NMS代码详解YOLOv3及Fast R-CNN例子

    先放Fast R CNN的NMS代码 这部分是关于 nms 实现的代码 后续再加下其他的版本 流程 xff1a 首先对检测结果的 score 取出最大的元素 xff0c 然后将置信度最高的框与其他框取交集 xff0c 计算 iou xff0