目标检测系列之一(候选框、IOU、NMS)
目前计算机视觉(CV,Computer Vision)与自然语言处理(NLP,Natural Language Process)是深度学习的主要研究领域。而计算机视觉的三大任务是图像分类、目标检测和目标分割。
图像分类就是给定一些包含不同目标的图像,通过深度学习技术将图像结构化为某一个类别的信息,比如猫、狗、桌子、汽车、树木等等,学习任务的重点是图像的整体。 目标检测则关注的是图像中的特定物体目标,并给出该目标的类别信息(Classification,类别概率表示)和位置信息(Localization,矩形框的坐标表示)。 目标分割是对图像的像素级描述,相当于给图像的每个像素都进行像素级的分类。语义分割(Semantic Segmentation)是对图像中不同语义的目标进行分割,从而分离出不同的目标和背景。实例分割(Instance Segmentation)是目标检测任务的精细化,需要描绘出不同目标的轮廓。
内容目录
1 目标检测概述2 目标候选框(Instance Bounding Boxes)2.1 滑窗法(Sliding Window)2.2 选择性搜索(Selective Search)3 IOU交并比4 NMS非极大值抑制
1 目标检测概述
目标检测需要同时解决分类和定位两个任务。 分类任务需要通过卷积神经网络 Softmax判断目标类别(ClassNum = 目标个数 背景)。 定位任务需要通过卷积神经网络回归输出四个数值来代表围绕目标的边界框的位置(如中心点坐标、边界框的长宽)。
目标检测的方法主要分为两类: 两阶段(Two Stages):第一阶段由卷积神经网络基于输入图像生成一系列目标候选框,第二阶段对这些候选框进行分类。常见的算法有R-CNN、Fast R-CNN和Faster R-CNN等。 一阶段(One Stage):只有一个阶段,不需要生成候选框了,直接对图像中的目标进行回归,生成目标对应的类别、边界框的位置信息。常见的算法有YOLO和SSD等。 基于候选区域的两阶段算法在检测准确性和定位精度上有优势,而一阶段算法在运算速度上占优势。
我们首先介绍一些目标检测涉及到的名词理解,如候选框、IOU交并比、NMS非极大值抑制等。
2 目标候选框(Instance Bounding Boxes)
两阶段目标检测算法需要首先对图像中的目标进行候选框生成,主要有两种方法,滑窗法和选择性搜索。
2.1 滑窗法(Sliding Window)
滑窗法是采用不同大小和长宽比的窗口在图像上进行从左到右、从上到下的滑动搜索,并对这些窗口进行分类,实现对整张图像的候选框查找。这个方法有一个缺点,因为我不知道目标的大小,设置不同大小的窗口对候选框查找结果有很大的影响,而且滑动窗的步长太小会产生过多的候选框,带来很大的计算量,步长太大又容易错过精确的目标候选框,对于实时性和速度要求较高时不推荐使用滑窗法。
2.2 选择性搜索(Selective Search)
选择性搜索对图像中最有可能包含目标的区域进行搜索以提高效率,首先对输入图像进行分割产生很多小区域(如2000个),根据这些小区域的相似性(颜色、纹理、大小等)采用子区域合并的方法进行区域迭代合并,生成外切矩形,也就是候选框。选择性搜索既提高了运算效率,又可以包含各种大小的候选框。
3 IOU交并比
为了计算算法提出的候选框的准确性,我们引入了IOU(Intersection Over Union)指标来计算候选框和目标实际标注边界框的重合度。假如我们要计算两个矩形框A和B的IOU,就是它们的交集与并集之比。
IOU 为 0 时,两个框不重叠,没有交集。 IOU 为 1 时,两个框完全重叠。 IOU 取值为 0 ~ 1 之间的值时,代表了两个框的重叠程度,数值越高,重叠程度越高。 A和B的面积都容易求得,而AB交集的面积需要根据A和B的相对位置得到边长,我们用W代表横轴的边长,H代表纵轴的边长,
Python代码:
代码语言:javascript复制def iou(box1, box2):
'''
两个框(二维)的 iou 计算
注意:边框以左上为原点
box:[top, left, bottom, right]
'''
in_h = min(box1[2], box2[2]) - max(box1[0], box2[0])
in_w = min(box1[3], box2[3]) - max(box1[1], box2[1])
inter = 0 if in_h<0 or in_w<0 else in_h*in_w
union = (box1[2] - box1[0]) * (box1[3] - box1[1])
(box2[2] - box2[0]) * (box2[3] - box2[1]) - inter
iou = inter / union
return iou
4 NMS非极大值抑制
NMS(Non-Maximun Suppression)非极大值抑制就是抑制不是极大值的元素。该方法主要是为了降低候选框数量,我们在之前提取出目标的候选框数量非常多(几千个),每个候选框经过分类器会有一个属于某个类别的概率值,我们需要NMS方法来去掉多余的候选框。
假设我们的目标分类任务有6类,在第一阶段得到2000个候选框,输出向量为2000*6,每列对应一类,每行是各个建议框的得分,有2000个,NMS算法步骤如下: 1)对2000×6维矩阵中的每列按从大到小进行排序(概率值越大排名越靠前); 2)从每列最大的得分候选框开始,分别与该列后面的候选框进行IOU计算,若IOU>给定阈值(如0.5),则剔除得分较小的候选框,剩余多个候选框我们认为图像中可能存在多个该类目标; 3)依次对得分越来越小的候选框重复步骤②,同样剔除IOU得分较小的候选框; 4)重复步骤③直到遍历完该列所有建议框; 5)遍历完2000×20维矩阵所有列,即所有物体种类都做一遍非极大值抑制;
Python代码,来自知乎用户HunterKun,在文章中他还给出了多种实现方法。
代码语言:javascript复制import numpy as np
def nms(dets, thresh):
"""Pure Python NMS baseline."""
x1 = dets[:, 0]
y1 = dets[:, 1]
x2 = dets[:, 2]
y2 = dets[:, 3]
scores = dets[:, 4]
areas = (x2 - x1 1) * (y2 - y1 1)
order = scores.argsort()[::-1]
keep = []
while order.size > 0:
i = order[0]
keep.append(i)
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
ovr = inter / (areas[i] areas[order[1:]] - inter)
inds = np.where(ovr <= thresh)[0]
order = order[inds 1]
return keep
参考: https://blog.csdn.net/u014061630/java/article/details/82818112 https://zhuanlan.zhihu.com/p/64423753 https://www.cnblogs.com/xiaoboge/p/10544336.html