Pytorch实现nms (torchvision.ops.nms)和numpy实现nms

9 篇文章 0 订阅
3 篇文章 0 订阅

Pytorch实现nms (torchvision.ops.nms)和numpy实现nms

nms理解起来很简单:

  • 将所有的boxes按照置信度从小到大排序,然后从boxes中删除置信度最大的box
  • 将剩下的boxes与置信度最大的box,分别计算iou,去掉iou大于阈值(iou_threshold)的boxes
  • 重复1,2直到索引为空

pytorch实现

from torch import Tensor
import torch

def box_area(boxes: Tensor) -> Tensor:
    """
    Computes the area of a set of bounding boxes, which are specified by its
    (x1, y1, x2, y2) coordinates.
    Arguments:
        boxes (Tensor[N, 4]): boxes for which the area will be computed. They
            are expected to be in (x1, y1, x2, y2) format
    Returns:
        area (Tensor[N]): area for each box
    """
    return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])
 
 
def box_iou(boxes1: Tensor, boxes2: Tensor) -> Tensor:
    """
    Return intersection-over-union (Jaccard index) of boxes.
    Both sets of boxes are expected to be in (x1, y1, x2, y2) format.
    Arguments:
        boxes1 (Tensor[N, 4])
        boxes2 (Tensor[M, 4])
    Returns:
        iou (Tensor[N, M]): the NxM matrix containing the pairwise IoU values for every element in boxes1 and boxes2
    """
    area1 = box_area(boxes1)  # 每个框的面积 (N,)
    area2 = box_area(boxes2)  # (M,)
 
    lt = torch.max(boxes1[:, None, :2], boxes2[:, :2])  # [N,M,2] # N中一个和M个比较; 所以由N,M 个
    rb = torch.min(boxes1[:, None, 2:], boxes2[:, 2:])  # [N,M,2]
 
    wh = (rb - lt).clamp(min=0)  # [N,M,2]  #小于0的为0  clamp 钳;夹钳;
    inter = wh[:, :, 0] * wh[:, :, 1]  # [N,M]  
 
    iou = inter / (area1[:, None] + area2 - inter)
    return iou  # NxM, boxes1中每个框和boxes2中每个框的IoU值;
 
 
def nms(boxes: Tensor, scores: Tensor, iou_threshold: float):
    """
    :param boxes: [N, 4], 此处传进来的框,是经过筛选(NMS之前选取过得分TopK)之后, 在传入之前处理好的;
    :param scores: [N]
    :param iou_threshold: 0.7
    :return:
    """
    keep = []  # 最终保留的结果, 在boxes中对应的索引;
    idxs = scores.argsort()  # 值从小到大的 索引
    while idxs.numel() > 0:  # 循环直到null; numel(): 数组元素个数
        # 得分最大框对应的索引, 以及对应的坐标
        max_score_index = idxs[-1]
        max_score_box = boxes[max_score_index][None, :]  # [1, 4]
        keep.append(max_score_index)
        if idxs.size(0) == 1:  # 就剩余一个框了;
            break
        idxs = idxs[:-1]  # 将得分最大框 从索引中删除; 剩余索引对应的框 和 得分最大框 计算IoU;
        other_boxes = boxes[idxs]  # [?, 4]
        ious = box_iou(max_score_box, other_boxes)  # 一个框和其余框比较 1XM
        idxs = idxs[ious[0] <= iou_threshold]
 
    keep = idxs.new(keep)  # Tensor
    return keep
 
 
box =  torch.tensor([[2,3.1,7,5],[3,4,8,4.8],[4,4,5.6,7],[0.1,0,8,1]]) 
score = torch.tensor([0.5, 0.3, 0.2, 0.4])
 
output = nms(boxes=box, scores=score, iou_threshold=0.3)
print(output)

numpy 实现

import numpy as np
from numpy import array

def box_area(boxes :array):
    """
    :param boxes: [N, 4]
    :return: [N]
    """
    return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])

def box_iou(box1 :array, box2: array):
    """
    :param box1: [N, 4]
    :param box2: [M, 4]
    :return: [N, M]
    """
    area1 = box_area(box1)  # N
    area2 = box_area(box2)  # M
    # broadcasting, 两个数组各维度大小 从后往前对比一致, 或者 有一维度值为1;
    lt = np.maximum(box1[:, np.newaxis, :2], box2[:, :2])
    rb = np.minimum(box1[:, np.newaxis, 2:], box2[:, 2:])
    wh = rb - lt
    wh = np.maximum(0, wh) # [N, M, 2]
    inter = wh[:, :, 0] * wh[:, :, 1]
    iou = inter / (area1[:, np.newaxis] + area2 - inter)
    return iou  # NxM

def numpy_nms(boxes :array, scores :array, iou_threshold :float):

    idxs = scores.argsort()  # 按分数 降序排列的索引 [N]
    keep = []
    while idxs.size > 0:  # 统计数组中元素的个数
        max_score_index = idxs[-1]
        max_score_box = boxes[max_score_index][None, :]
        keep.append(max_score_index)

        if idxs.size == 1:
            break
        idxs = idxs[:-1]  # 将得分最大框 从索引中删除; 剩余索引对应的框 和 得分最大框 计算IoU;
        other_boxes = boxes[idxs]  # [?, 4]
        ious = box_iou(max_score_box, other_boxes)  # 一个框和其余框比较 1XM
        idxs = idxs[ious[0] <= iou_threshold]

    keep = np.array(keep)  
    return keep
 
box =  np.array([[2,3.1,7,5],[3,4,8,4.8],[4,4,5.6,7],[0.1,0,8,1]]) 
score = np.array([0.5, 0.3, 0.2, 0.4])
 
output = numpy_nms(boxes=box, scores=score, iou_threshold=0.3)
print(output)
  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: 你好,以下是在 PyTorch 中调用 torchvision.models.ConvNeXt 的代码,使 pretrained=False: ```python import torchvision.models as models model = models.ConvNeXt50(pretrained=False) ``` 你可以通过将 `pretrained` 参数设置为 `False` 来加载未经过预训练的 ConvNeXt 模型。 ### 回答2: 在PyTorch中调用torchvision.models.ConvNeXt并设置pretrained=False的代码如下: ```python import torch import torchvision.models as models # 定义ConvNeXt模型 model = models.convnet(ConvNeXt=True, pretrained=False) # 使用预训练的参数 pretrained_model = models.convnet(ConvNeXt=True, pretrained=True) # 打印模型结构 print(model) ``` 上述代码中,首先导入了PyTorch库和torchvision.models模块。 然后,通过调用models.convnet(ConvNeXt=True, pretrained=False)函数来创建一个没有预训练参数的ConvNeXt模型。我们可以根据自己的需求自定义该模型的各种参数,例如输入图片的尺寸、输入通道的数量等等。 如果需要使用预训练的参数,则可以通过调用models.convnet(ConvNeXt=True, pretrained=True)函数创建一个包含预训练参数的ConvNeXt模型。 最后,通过print(model)语句打印出该ConvNeXt模型的结构信息。 通过以上代码,我们可以实现PyTorch中调用torchvision.models.ConvNeXt,并设置pretrained=False。 ### 回答3: 要在PyTorch中调用torchvision.models.ConvNeXt,并将pretrained设置为False,可以按照以下步骤进行操作: 首先,需要导入相关的库和模块: ```python import torchvision.models as models ``` 接下来,可以通过调用ConvNeXt模型来创建一个实例,并将pretrained设置为False: ```python model = models.convnet.ConvNeXt(pretrained=False) ``` 通过这个实例,你可以开始使用模型进行推理或训练。 完整的代码示例如下: ```python import torchvision.models as models model = models.convnet.ConvNeXt(pretrained=False) # 进行推理或训练的代码 ``` 以上代码可以创建一个没有预训练权重的ConvNeXt模型实例,你可以根据自己的需求在模型上进行进一步的操作。注意,ConvNeXt模型需要PyTorch的1.7.0版本或更高版本以及Torchvision的0.8.0版本或更高版本。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值