前言
之前对目标检测(Object Dectection)的理解一直不是什么深入,且没有做过相关的代码实践,最近看到DataWhale在12月份的组队学习中有关于目标检测的学习内容,因此报名了该学习小组,希望能够深入了解一下目标检测的具体实现,并在次记录关于此次学习的相关笔记。
目标检测基础知识
定义
简单来说,目标检测就是分类+定位。
分类:判断图像中是否存在相关的感兴趣物体
定位:在以上分类的基础上,进一步对物体的位置,即边界框(Bounding-Box)信息,进行预估
求解思路
通常图像中可能存在多个感兴趣区域,实际进行目标检测时需要先获取一些可能存在目标的区域(候选区域),再对这些候选区域进行分类与边界框信息的微调。
目标框定义
在目标检测中,训练样本包含图像及其标签信息(也就是目标框),训练集中标注好的标签信息也通常称为GT(GroundTruth)。具体来说,目标检测的标签信息除了类别label以外,需要同时包含目标的位置信息,也就是目标的外接矩形框bounding box。
如图,用来表达bbox的格式通常有两种,(x1, y1, x2, y2) 和 (c_x, c_y, w, h)。
交并比(IoU)
交并比在目标检测中可以用于衡量两个目标框的重叠程度,表示两个目标框的交集占其并集的比例。
图中可以看到,分子中黄色区域为红bbox和绿bbox的交集,分母中黄+红+绿区域为红bbox和绿bbox的并集,两者之比即为iou。
计算流程:
1.首先获取两个框的坐标,红框坐标: 左上(red_x1, red_y1), 右下(red_x2, red_y2),绿框坐标: 左上(green_x1, green_y1),右下(green_x2, green_y2)
2.计算两个框左上点的坐标最大值:(max(red_x1, green_x1), max(red_y1, green_y1)), 和右下点坐标最小值:(min(red_x2, green_x2), min(red_y2, green_y2))
3.利用2算出的信息计算黄框面积:yellow_area
4.计算红绿框的面积:red_area 和 green_area
5.iou = yellow_area / (red_area + green_area - yellow_area)
代码实现
def find_intersection(set_1, set_2):
"""
Find the intersection of every box combination between two sets of boxes that are in boundary coordinates.
:param set_1: set 1, a tensor of dimensions (n1, 4)
:param set_2: set 2, a tensor of dimensions (n2, 4)
:return: intersection of each of the boxes in set 1 with respect to each of the boxes in set 2, a tensor of dimensions (n1, n2)
"""
# PyTorch auto-broadcasts singleton dimensions
lower_bounds = torch.max(set_1[:, :2].unsqueeze(1), set_2[:, :2].unsqueeze(0)) # (n1, n2, 2)
upper_bounds = torch.min(set_1[:, 2:].unsqueeze(1), set_2[:, 2:].unsqueeze(0)) # (n1, n2, 2)
intersection_dims = torch.clamp(upper_bounds - lower_bounds, min=0) # (n1, n2, 2)
return intersection_dims[:, :, 0] * intersection_dims[:, :, 1] # (n1, n2)
def find_jaccard_overlap(set_1, set_2):
"""
Find the Jaccard Overlap (IoU) of every box combination between two sets of boxes that are in boundary coordinates.
:param set_1: set 1, a tensor of dimensions (n1, 4)
:param set_2: set 2, a tensor of dimensions (n2, 4)
:return: Jaccard Overlap of each of the boxes in set 1 with respect to each of the boxes in set 2, a tensor of dimensions (n1, n2)
"""
# Find intersections
intersection = find_intersection(set_1, set_2) # (n1, n2)
# Find areas of each box in both sets
areas_set_1 = (set_1[:, 2] - set_1[:, 0]) * (set_1[:, 3] - set_1[:, 1]) # (n1)
areas_set_2 = (set_2[:, 2] - set_2[:, 0]) * (set_2[:, 3] - set_2[:, 1]) # (n2)
# Find the union
# PyTorch auto-broadcasts singleton dimensions
union = areas_set_1.unsqueeze(1) + areas_set_2.unsqueeze(0) - intersection # (n1, n2)
return intersection / union # (n1, n2)
目标检测数据集VOC
介绍内容与VOC数据集介绍中的一致,直接复制过来了。
VOC数据集包含4大类,20小类:
Vehicles: Car、Bus、Bicycle、Motorbike、Aeroplane、Boat、Train
Household: Chair、Sofa、Dining table 、TVmonitor、Bottle、Potted plant
Animals: Cat、Dog、Cow、Horse、Sheep、Bird
Persion: Persion
数据集说明
VOC数据集不仅被拿来做目标检测,也可以拿来做分割等任务,因此除了目标检测所需的文件之外,还包含分割任务所需的文件,比如SegmentationClass,SegmentationObject,这里,我们主要对目标检测任务涉及到的文件进行介绍。
1.JPEGImages
这个文件夹中存放所有的图片,包括训练验证测试用到的所有图片。
2.ImageSets
这个文件夹中包含三个子文件夹,Layout、Main、Segmentation
Layout文件夹中存放的是train,valid,test和train+valid数据集的文件名
Segmentation文件夹中存放的是分割所用train,valid,test和train+valid数据集的文件名
Main文件夹中存放的是各个类别所在图片的文件名,比如cow_val,表示valid数据集中,包含有cow类别目标的图片名称。
3.Annotations
Annotation文件夹中存放着每张图片相关的标注信息,以xml格式的文件存储,可以通过记事本或者浏览器打开,我们以000001.jpg这张图片为例说明标注文件中各个属性的含义。
主要看红框中的信息:
- filename:图片名称
- size:图片宽高,
- depth表示图片通道数
- object:表示目标,包含下面两部分内容。首先是目标类别name为dog。pose表示目标姿势为left,truncated表示是否是一个被截断的目标,1表示是,0表示不是,在这个例子中,只露出狗头部分,所以truncated为1。difficult为0表示此目标不是一个难以识别的目标。然后就是目标的bbox信息,可以看到,这里是以[xmin,ymin,xmax,ymax]格式进行标注的,分别表示dog目标的左上角和右下角坐标。
- 一张图片中有多少需要识别的目标,其xml文件中就有多少个object。上面的例子中有两个object,分别对应人和狗。