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

先放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
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RCNN系列算法 SSD算法 YOLO系列算法 8.3 8.1 8.2 第八章 目标检测 人工智能-第八章全文共18页,当前为第1页。 区域选择 分类器 目标检测 三个阶段 遍历图像确定可能存在目标的候选区域 提取候选区域相关的视觉特征 对选取的目标进行识别 rcnn系列算法 特征提取 人工智能-第八章全文共18页,当前为第2页。 R-CNN是一种基于卷积神经网络的目标检测算法,它在卷积神经网络上应用区域推荐的策略,形成自底向上的目标定位模型,摒弃了传统的滑动窗口(通过多尺度滑动窗口确定所有可能的目标区域)和人工选取特征的方法,将候选区域算法和卷积神经网络相结合,使得检测速度和精度明显提升。 RCNN fast-RCNN faster-RCNN rcnn系列算法 人工智能-第八章全文共18页,当前为第3页。 R-CNN 利用选择性搜索算法在图像中提取2000个左右的候选框; 把所有候选框缩放成固定大小(227*227),并进行归一化后输入CNN(AlexNet)网络,提取特征; 提取到的CNN特征使用SVM来分类,用线性回归来微调边框位置与大小,其中每个类别单独训练一个边框回归器; 非极大值值抑制(NMS)来滤除重叠的候选框 存在问题 训练时间长 测试时间长 占用磁盘空间大 卷积出来的特征数据还需要单独保存 rcnn算法 人工智能-第八章全文共18页,当前为第4页。 R-CNN Fast R-CNN 1.输入为整张图像并提取特征图。 2. RoI池化层从特征图中提取固定长度的特征向量。 3.使用多任务损失函数,分别进行softmax分类和边框回归。 fast-rcnn算法 人工智能-第八章全文共18页,当前为第5页。 faster-rcnn模型结构 1 2 3 特征提取 粗分类+定位 NMS去重 精分类+定位 NMS去重 faster-rcnn算法 人工智能-第八章全文共18页,当前为第6页。 anchor框 特征图的每个像素点生成三种不同尺度大小的anchor框,每种框的宽高比分别为:1:1,2:1,1:2,即特征图上的每个像素点共生成9个不同大小的anchor框。 特征图 faster-rcnn算法 人工智能-第八章全文共18页,当前为第7页。 RPN网络 遍历特征图上的每个像素点,然后根据不同位置和宽高的anchor框从原图上生成候选框。 faster-rcnn算法 特征图 人工智能-第八章全文共18页,当前为第8页。 1.第一阶段 CNN网络提取特征 2.第二阶段(RPN网络) 使用锚框生成候选框,初步实现目标的粗分类和边框回归 3.第三阶段 实现目标的精分类和边框回归 faster-rcnn算法 faster-rcnn 人工智能-第八章全文共18页,当前为第9页。 YOLO 结构简单,属于单阶段的检测方法 速度快、资源消耗少 精度较高 YOLO(You Only Look Once):创造性地将目标区域推荐和识别这两个阶段合二为一,同时完成目标定位和分类。 YOLO系列算法 人工智能-第八章全文共18页,当前为第10页。 YOLOv1算法 YOLOv1的模型结构比较简单,与常规的CNN分类模型最大的差异是最后输出层用线性函数做激活函数,从而实现预测bounding box的位置。 人工智能-第八章全文共18页,当前为第11页。 每个点的维度: 类别概率: 置信度: 边框信息: YOLOv1算法 人工智能-第八章全文共18页,当前为第12页。 损失函数 YOLOv1算法 人工智能-第八章全文共18页,当前为第13页。 使用聚类生成的锚点代替手工设计的锚点; 在高分辨率图像上进行迁移学习,提升网络对高分辨图像的响应能力 训练过程图像尺寸不再固定,提升网络对不同训练数据的泛化能力 YOLOv2 YOLOv2算法 人工智能-第八章全文共18页,当前为第14页。 yolov3改进策略 1.使用Darknet-53主干网络 2.使用k-means聚类9种尺度的先验框 3.多尺度特征进行目标检测 YOLOv3算法 人工智能-第八章全文共18页,当前为第15页。 SSD采用VGG作为主干网络,输入图像大小为300*300,采用了特征金字塔结构进行检测,即分别在6个不同大小的特征图上生成目标候选框。 SSD算法 人工智能-第八章全文共18页,当前为第16页。 1.以特征图上每个点的中心为中心(偏移量为0.5)生成一系列同心的prior box 。 2.正方形prior box最小边长为min_size ,最大边长为min_size max_size。 3.每设置一个aspect_ratio,会生成1个长宽为aspect_ratio minsize和1aspect_ minsize的长方形。 SSD算法 人工智能-第八章全文共18页,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kira_Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值