目的:
完全引用:
在前面的部分中,我们已经建立了一个模型,对于给定的输入图像,输出多个目标检测结果。准确地说,我们的输出是B×10647×85形状的张量。B是一个批量中图像的数量,10647是每个图像预测的边界框的数量,85是边界框属性的数量。
但是,如第1部分所述,我们必须将输出结果根据目标分数阈值和非最大值抑制来获得true检测结果(我将在本文其余部分中使用该名称)。为此,我们将在util.py文件中创建一个名为write_results的函数。
就是筛选工作,不然框太多了.
参考链接:https://zhuanlan.zhihu.com/p/36998818 (这部分都在介绍).
该函数存在于:util.py文件---write_results函数
代码解析:
prediction : 输入预测,已经被处理为三个尺度的输出共同以bbox为基准排列,(x, y, w, h)都是基于416的尺度.
torch.Size([1, 10647, 85]) , 三个尺度,一共10647个anchors(每个cell三个). 85个预测数据.
准确地说,我们的 输出是B×10647×85形状的张量..B是一个批量中图像的数量, 10647是每个图像预测的边界框的数量,85是 边界框属性的数量.
confidence : 值为 0.5 ,置信度(目标分数阈值)
nms_conf :默认为 0.4 ,NMS IoU阈值)
将输入预测,置信度(目标分数阈值),num_classes(在我们的例子中为80)和nms_conf(NMS IoU阈值)作为输入.
完全按照引用的格式,只是增加备注:
def write_results(prediction, confidence, num_classes, nms_conf = 0.4):
这些函数将输入预测,置信度 = 0.5(目标分数阈值),num_classes = 80和nms_conf(NMS IoU阈值)作为输入。
目标置信度阈值
我们的预测张量prediction包含B x 10647个边界框的信息。对于每个具有低于阈值confidence的目标分数的边界框,我们将它的每个属性(边界框的整个行)的值设置为零。
# 各预测框置信度C = prediction[:,:,4] = torch.Size([1, 10647]),
# C > confidence(0.4),这个位置的conf_mask值为1,否则为0,
# 最后unsqueeze(2)增加维度:torch.Size([1, 10647, 1])
conf_mask = (prediction[:,:,4] > confidence).float().unsqueeze(2)
# 相乘,保留满足置信度阈值的C
prediction = prediction*conf_mask
执行非最大值抑制
注意:
1.我假设你已经理解什么是IoU(Intersection over Union)和非最大值抑制.
2.现在的prediction是置信度阈值筛选以后的边界框,属性由中心坐标以及边界框的高度和宽度描述.
3.使用每个框的一对角点的坐标来计算两个框的IoU更容易(xmin,ymin,xmax,ymax).
4.因此,我们将框的(中心x,中心y,高度,宽度)属性转换为(左上角x,左上角y,右下角x,右下角y)。
# 创建一个与prediction相同shape的tensor,初始化值
box_corner = predict