【目标检测】锚框

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

【个人学习笔记记录,如有错误,请指正!】


一、锚框


理解锚框之前,我们需要理解当前主流的目标检测算法,目前主流的目标检测算法都是基于【锚框】的。

那么为什么目标检测算法需要基于【锚框】?
个人理解:在一个图像中,被检测的目标的位置和大小是【不确定的】,所以在图像中找到目标就类似大海捞针,而只能通过对整个图像进行地毯式的搜索。就在特征图上基于每个像素分配不同尺度的【锚框】,以便于匹配不同尺度和位置的目标。
那么什么是【锚框】?
其实【锚框】就是【框】而已,就是不同大小尺度的框。

【anchors (锚框)生成】
锚框的生成一般步骤都是:
第一步:求得需要生成的 anchors 的高宽,然后基于原点生成出锚框(这里基于原点生成三种尺度和三种比例的anchors,(1:1)(1:2), (2:1))。
在这里插入图片描述
第二步:将生成的 anchors 移到每个特征图中每一个像素的中心点上。
这里假设特征图的大小为 3x3 ,且没有考虑原图和特征图的步距
在这里插入图片描述

二、代码

这里给出的代码是,李沐大神给出的锚框代码,大神在 某站 有学习视频。
这里的代码和上面的锚框示意图是不一样的!


![在这里插入图片描述](https://img-blog.csdnimg.cn/9294f6f3b666426680b451ee559621ef.png)
def multibox_prior(data, sizes, ratios):
	"""
	data : 特征图
	size : anchors 的大小
	ratios : 高宽比
	"""
    # 获取数据的高宽
    in_height, in_width = data.shape[-2:]
    print('in_height: ', in_height)
    print('in_width: ', in_width)
    device, num_sizes, num_ratios = data.device, len(sizes), len(ratios)
    # 每个像素生成 anchors 的个数
    boxes_per_pixel = (num_sizes + num_ratios - 1)
    # 将 size 和 比例转化为 tensor
    size_tensor = torch.tensor(sizes, device=device)
    ratio_tensor = torch.tensor(ratios, device=device)
    
    # 高宽的偏移基准(因为像素是(1,1),中心点就应该是(0.5, 0.5))
    offset_h, offset_w = 0.5, 0.5
    # 将图像的高宽缩放到 1,然后求得每个像素的高宽
    steps_h = 1.0 / in_height
    steps_w = 1.0 / in_width
    print('steps_h: ', steps_h)
    print('steps_w: ', steps_w)
    # 基于缩放后的高宽,生成中心点的横纵坐标,这里生成的是 一行和一列
    center_h = (torch.arange(in_height, device=device) + offset_h) * steps_h
    center_w = (torch.arange(in_width, device=device) + offset_w) * steps_w
    print('center_h shape: ', center_h.shape)
    print('center_w shape: ', center_w.shape)
    # 将一行和一列生成一个图像大小的矩阵
    shift_y, shift_x = torch.meshgrid(center_h, center_w)
    shift_y, shift_x = shift_y.reshape(-1), shift_x.reshape(-1)
    # 生成锚框的 宽度和高度
    w = torch.cat((size_tensor * torch.sqrt(ratio_tensor[0]),
                   sizes[0] * torch.sqrt(ratio_tensor[1:])))\
                   * in_height / in_width
    h = torch.cat((size_tensor * torch.sqrt(ratio_tensor[0]),
                   sizes[0] / torch.sqrt(ratio_tensor[1:])))
    # 基于每个像素 生成五个 anchors 的高宽
    anchor_manipulations = torch.stack(
        (-w, -h, w, h)).T.repeat(in_height * in_width, 1) / 2
    print('anchor_manipulations: ', anchor_manipulations[:10, :])
    print('anchor_manipulations shape: ', anchor_manipulations.shape)
    # 基于每一个像素,求得每个 anchors 的偏移
    out_grid = torch.stack([shift_x, shift_y, shift_x, shift_y],
                           dim=1).repeat_interleave(boxes_per_pixel, dim=0)
    print('out_grid: ', out_grid[:10, :])
    print('out_grid shape: ', out_grid.shape)
    # 将每个像素的 anchors 的高宽 和 偏移 相加,构成每个像素的 anchors
    output = out_grid + anchor_manipulations
    return output.unsqueeze(0)

总结

这里对锚框的介绍只是介绍了最常见的生成方法。基本上所有的基于锚框的目标检测方法都是这样的流程。不同的是特征图的尺寸锚框的高宽比锚框的高宽

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在YOLO中,锚框的大小是通过k-means聚类方法确定的。在YOLOV3中,作者使用k-means聚类方法计算锚框的大小,而在YOLOV5中,作者在基于k-means聚类方法的结果之后,进一步采用了遗传算法来得到效果更好的锚框。 具体来说,使用k-means聚类方法生成锚框的步骤如下: 1. 首先,准备训练集。一般使用VOC格式的训练集作为例子。 2. 将训练集中的bbox的宽度和高度提取出来作为聚类的输入数据。 3. 选择聚类的数目k,即确定要生成的锚框的个数。 4. 随机选择k个中心点,可以使用随机选取的方式或者其他方法来选择初始的中心点。 5. 计算每个bbox与k个中心点之间的距离,并将每个bbox分配到与其最近的中心点所代表的聚类中心。 6. 更新聚类中心,将每个聚类中心的坐标更新为该聚类中所有bbox坐标的平均值。 7. 重复第5和第6步,直到聚类中心不再更新或达到预定的迭代次数。 8. 最终得到k个聚类中心,每个聚类中心代表一个锚框,它们的大小即为生成的锚框的大小。 需要注意的是,使用k-means聚类方法生成锚框时,输入数据一般是bbox的宽度和高度,而不是像素点的坐标。这是因为锚框的大小不是像素点的绝对值,而是相对于特征图的比例。 以上就是关于锚框k-means聚类的简要介绍。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Pytorch机器学习(十)—— 目标检测中k-means聚类方法生成锚框anchor](https://blog.csdn.net/lzzzzzzm/article/details/120765117)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值