opencv目标检测(object detection)

最近在做移动端的视频流目标检测,配置opencv4Android,这一块在opencv官方文档上有些说明文档,另外learning opencv3的章节object detection也值得一看。

前言

目标检测,就是判断图片中是否包含特定物体以及物体在像素空间上的位置。这里,我们关注几种机器学习技术的目标检测手段。

1.基于树的目标检测技术

在当前的opencv库里有两种检测器,cascade classifier,源自Viola 和 Jones在人脸检测上非常成功的算法,详见Viola, Paul, and Michael Jones. “Rapid object detection using a boosted cascade of simple features.” Computer Vision and Pattern Recognition, 2001. CVPR 2001. Proceedings of the 2001 IEEE Computer Society Conference on. Vol. 1. IEEE,2001.第二种是soft cascade,一种提供了新途径的演化的算法,并在大多实例上比cascade classifier有更健壮的分类。两种算法都可以用到多目标检测上,一般而言,具有严格结构和丰富纹理的物体(刚性物体)响应更好。
这些算法不仅封装了基学习器的函数,还包含了学习器的输入或是输出的预处理的方法。当然,这些算法不像是opencv中的基学习器,有统一的接口。它建立了boost筛选式级联分类器。它与ML库中其他部分相比,有不同的格局,因为它是在早期开发的,并完全可用于人脸检测。通常由算法的发明者提供给opencv,因此接口更像是算法的原始实现。

1.1 Cascade Classifiers

Cascade Classifier由一个重要的概念构建,boosted rejection cascade。它在opencv库里有不同的格式,因为它一开始是由一个成熟的人脸检测的应用发展而来, 随后才演化的更普遍。这里我们介绍它的详细原理和怎样应用到人脸检测和其他物体上。

计算机视觉是一个涉及广泛而又发展迅速的领域,所以opencv中某个特定技术很容易发展过时,之前的人脸检测器(Haar classifier)就是这样,但人脸检测又有巨大的需求,因此需要一个不错的基线技术供使用,而且人脸检测是建立在最经常使用的分类器boosting上,因此更加通用。事实上,一些公司使用了opencv中的“人脸”检测器来检测“基本刚性的”物体(脸,汽车,自行车,人体)。通过成千上万的物体的各个角度的训练图像,训练出新的分类器,这个技术被用来设计目前最优的检测算法。因此,对于此类识别任务,Haar分类器是一个有用的工具。

cascade classifier,又被称为Viola-Jones detector,最开始,这种算法和他的opencv实现仅支持Haar小波这种特定的特征。之后,由Rainer Lienhart 和 Jochen Maydt扩展,详见Lienhart, Rainer, and Jochen Maydt. “An extended set of haar-like features for rapid object detection.” Proceedings 2002 International Conference on Image Processing. Vol. 1. IEEE, 2002.使用对角特征,更普遍地,称为“Haar-like” 特征,在opencv3.x中,又发展成使用local binary patterns(LBP)。
opencv的cascade classifier实现有两层,第一层是特征检测,封装了特征计算,第二层是boosted cascade,计算得到的特征的矩形区域的和与差,boosting分类器与特征的计算层无关。

1.1.1 Haar-like features

类Haar特征描述如下图,
opencv目标检测(object detection)_第1张图片
类Haar特征(矩形和旋转矩形特征都很容易从积分图中算出)

在所有缩放尺度下,这些特征组成了boosting分类器使用的全部“原材料”。他们从原始灰度图像的积分图中快速计算得出。

opencv可以使用cv::integral()函数轻松计算积分图,积分图是一种数据结构,可以实现子区域的快速求和。这样的求和在很多应用中是有用的,最显著的是人脸识别和相关算法的Haar小波。
opencv支持积分图的三种变化。分别是sum, square-sum, tilted-sum.每一种的输出和输入图像尺寸一致。利用这些积分图,可以计算图像的任意直立或倾斜的矩形区域的和,均值和标准差。在这种方式下,就可能进行快速模糊、梯度估计、计算均值和标准差,甚至为各种窗口大小执行快速的可变窗块相关计算。


积分图的计算

三种不同的积分图在C++ API中仅以他们的参数加以区分。


Standard Summation Integral

opencv目标检测(object detection)_第2张图片
Squared Summation Integral

如果输入图片的尺寸是W*H,那么输出则是(W+1)*(H+1)。
当前,opencv中仅支持两种特征。原始的Haar小波(包含对角特征)和LBP。
1.1.2 Local binary pattern features

LBP是一种用来描述图像局部纹理特征的算子,被用于Viola-Jones检测器,回想Haar小波,它是在一小块邻域上通过小波变换的特征向量,而LBP在构造特征向量与此不同,在一个长宽都为3的倍数的矩形上,将它分割成不相重叠的3*3的小块,在每一个小块上,用积分图计算像素和,然后将中心点像素与周围8个像素点比较得到一个8位的特征值,用来描述相应矩形的特征。
opencv目标检测(object detection)_第3张图片
image.png
1.1.3 Training and pretrained detectors

opencv提供了一套预训练目标识别的文件,也有代码允许你训练存储新的检测器的目标模型。如果不够用,在opencv存储目录里apps文件夹下还有traincascade的应用,你可以用它来训练任何刚性物体的检测器,但稳定性因物变化。
预训练目标的文件在.../opencv/data/haarcascades和.../opencv/data/lbpcascades下面,其中正面人脸识别效果最好的是haarcascade_frontalface_alt2.xml,而侧脸却难以用该方法获得准确的检测结果。

1.2 监督学习和Boosting理论

opencv中的cascade分类器是一种监督学习,Viola-Jones检测器使用adaboost,也叫作rejection cascade,cascade是一系列的节点,每一个节点是独立的adaboost分类树,图像上的一个子窗口以一种特定顺序在所有cascade上测试,只有通过了所有分类器的窗口才被视作是目标。
每一个节点都被设计成为有高检测率(99.9%)和低假正率(大致50%),每一个节点里,得到没有在图片里的结果就可以结束计算,然后最终宣称图片上没有目标。

1.2.1 Boosting in the Haar cascade

对于Viola-Jones rejection cascade,每一个节点都是组合的弱学习器,然后通过boosting,组成一个强学习器。这些独立的弱学习器通常是深度为1的决策树,即单层决策树。单层决策树通常只做一个决定,按照以下格式:特征h里的值v,是大于阈值t,还是小于?“yes”表示物体的存在,“no”表示没有。

opencv目标检测(object detection)_第4张图片
单层决策树

Viola-Jones分类器的Haar特征或LBP特征的数量在每一层节点都可以设置,但大多通常是单一特征的决策,有些场景最多三个特征。然后通过迭代提升将这些弱学习器进行加权组合。
boosting

在训练一开始,需要设置在每个节点上能最优化分输入的阈值t w,然后用累积误差来计算权重参数α w。在传统的adaboost里,每一个特征向量(数据点)每次迭代时也需要重新分配权重。

1.2.2 Rejection cascades.

下图展示了Rejection cascades的流程,由许多的boosted分类器组成,每个节点Fj包含了整个决策树桩的集合,每个节点都有个很高的检测率(99.9%),但可能也有50%的非目标检测失误,但这不影响,想象20个节点后,检测率为0.99920 ≈ 98%,而假正率仅为0.520 ≈ 0.0001%!

opencv目标检测(object detection)_第5张图片
Rejection cascades

像之前提及的,这个技术实现了人脸检测但不限于人脸,在大多数刚性物体上都表现的很好,但侧脸或者说是车的角落位置则不然。

1.2.3 The cv::CascadeClassifer object

cascade分类器在opencv中作为一个对象,即cv::CascadeClassifer。


CascadeClassifer

这个构造函数只有一个参数,即你存储的cascade的文件,如果你想要稍后加载,也可以用load函数。

1.2.4 Searching an image with detectMultiScale()

实现cascade分类的函数是cv::CascadeClassifer对象中的detectMultiScale()方法。


opencv目标检测(object detection)_第6张图片

首先输入类型为CV_8U的灰度图片,然后该函数浏览输入图片的所有尺度定位目标并返回到objects参数中,设置scaleFactor决定尺度间的宽度,越大表明计算速度的提高,但可能会丢失目标,minNeighbors参数是对错误判断的控制,因为好的目标检测会在相邻空间碰撞因为周边的像素会暗示该目标的存在。
未完待续。。。

你可能感兴趣的:(opencv目标检测(object detection))