参考文章
【特征检测】HOG特征算法
第二十九节,目标检测算法之R-CNN算法详解
目标检测:SPP-net
一文读懂Faster RCNN
目标检测|YOLO原理与实现
目标检测:利用神经网络进行目标识别,同样的目标变为坐标值
回归是将目标的位置作为变量,特点是算的比较快,但是没有那么准确。
分类是将目标进行分块。对分块后的图片进行识别,问题主要在于分类框的选择,选的好的话识别率会很高。
小结:
HOG(Histogram of Oriented Gridients的简写)特征检测算法,主要思想是:在边缘具体位置未知的情况下,边缘方向的分布也可以很好的表示行人目标的外形轮廓。
HOG特征检测算法的几个步骤:
1、颜色空间归一化
避免因为颜色和光照影响图像识别的效果;一般通过两个步骤进行修改
图像灰度化:
Gamma校正:将图像中的整体亮度提高或者减低。
2、梯度计算
计算图像横坐标和纵坐标方向的梯度,并据此计算每个像素位置的梯度方向值;求导操作不仅能够捕获轮廓,人影和一些纹理信息,还能进一步弱化光照的影响。其思想可以理解为计算每个像素点的变化方向,找到最大比变化的方向,这些方向也就是边缘点。
最常用的方法是: 首先用[-1,0,1]梯度算子对原图像做卷积运算,得到x方向(水平方向,以向右为正方向)的梯度分量gradscalx,然后用[1,0,-1]T梯度算子对原图像做卷积运算,得到y方向(竖直方向,以向上为正方向)的梯度分量gradscaly。然后再用以上公式计算该像素点的梯度大小和方向。
3、梯度方向直方图
将图像划分成若干个cells(单元),8x8=64个像素为一个cell,相邻的cell之间不重叠。在每个cell内统计梯度方向直方图,将所有梯度方向划分为9个bin(即9维特征向量),作为直方图的横轴,角度范围所对应的梯度值累加值作为直方图纵轴,每个bin的角度范围如下。
4、重叠块直方图归一化
将cell组合为block进行图像的分割,这样是为了增加在环境和背景情况下的图像识别率。
假设有一幅图像大小为220x310,将其划分成若干个8x8的cells,显然220÷8=27.5、310÷8=38.75不是整数,也就是说划分之后依然还有多余像素不能构成cell。处理办法是将图像缩放成能被8整除的长宽(如216x304),再划分。216÷8=27,304÷8=38,因此,216x304的图像可以得到27x38个cells,没有重叠。
以上述缩放后的图像为例,共得到27x38个cell,也就是将图像划分成了27x38个单元;将上下左右相邻的2x2个cells当做一个block整体,如下所示(为方便观察,每个颜色框故意错开了一点),黑色的8x8像素为一个cell,红、蓝、黄、粉红、绿框都是一个block,即每个框内2x2的cell组成一个block。故27x38个cell可划分成26x37个block,每个block为16x16像素。相邻block之间是有重叠的,这样有效的利用了相邻像素信息,对检测结果有很大的帮助。
接下分别对每个block进行标准化,一个block内有4个cell,每个cell含9维特征向量,故每个block就由4x9=36维特征向量来表征。
经过上述对有重叠部分block的直方图归一化之后,将所有block的特征向量都组合起来,则形成26x37x36=34632维特征向量,这就是HOG特征,这个特征向量就可以用来表征整个图像了。
实际上,在运用的时候,我们通常是选取一幅图像中的一个窗口来进行特征提取,依然以上述220X310大小图像为例,经过缩放处理后为216x304,但并不直接提取整个图像的HOG特征,而是用一个固定大小的窗口在图像上滑动,滑动的间隔为8个像素,opencv中默认的窗口大小为128x64(高128,宽64),即有(128÷8)x(64÷8)=16x8个cell,也即有15x7个block,这样一来一幅图像就可以取到(27-15)x(38-7)=12x31=372个窗口。现在提取每个窗口的HOG特征,则可得到105x36=3780维HOG特征向量。
将这330个3780维的HOG特征当做测试样本,用支持向量机(SVM)分类器来判别出,这些窗口的HOG特征是否有行人,有行人的用矩形框标记起来。HOG行人特征及所对应的SVM分类器的参数,在opencv中已经训练好了,我们只需要得到HOG特征,然后调用SVM即可得到判别结果。
基本思想:提取图像特征,制作激励模板,在原始图像滑动计算,得到激励效果图,根据激励分布确定目标位置。
人为设计一个卷积核,使用卷积核对原图像进行卷积运算计算得到一个特征图,通过特征图来判断是否为所需要的识别的物体,但是由于存在方向或者姿态等影响到我们图像识别的因素,我们在进行识别时可以采用局部识别的方式,例如不去识别一个人的整体而是通过识别一个模板,例如,头,胳膊,腿等方式进行识别。
DPM算法的步骤:
1、产生多个模板,整体模板以及不同的局部模板;
2、拿这些不同的模板同输入图像“卷积”产生特征图;
3、将这些特征图组合形成融合特征;
4、对融合特征进行传统分类,回归得到目标位置。
DPM算法优点:
1、方法直观简单;
2、运算速度块;
2、适应动物变形;
通过分割多个位置,不同尺寸的图片,用卷积神经网络判断图片是否为某物。
RCNN的基本还是按照提取框,对每个框提取特征、图像分类、非极大值抑制等步骤进行识别的。只是在一些小部分上进行了改进。
在训练时使用两个数据库:
使用识别库(ImageNet)进行预训练,而后用检测库(VOC fine-tuning)调优参数。最后在检测库上评测。
RCNN算法简述
数据集采用pascal VOC,这个数据集的object一共有20个类别。
首先用selective search方法在每张图像上选取约2000个region proposal,region proposal就是object有可能出现的位置。
然后根据这些region proposal构造训练和测试样本,注意这些region proposal的大小不一,另外样本的类别是21个(包括了背景)。
然后是预训练,即在ImageNet数据集下,用AlexNet进行训练。然后再在我们的数据集上fine-tuning,网络结构不变(除了最后一层输出由1000改为21),输入是前面的region proposal进行尺寸变换到一个统一尺寸227×227,保留f7的输出特征2000×4096维。
针对每个类别(一共20类)训练一个SVM分类器,以f7层的输出作为输入,训练SVM的权重4096×20维,所以测试时候会得到2000×20的得分输出,且测试的时候会对这个得分输出做NMS(non-maximun suppression),简单讲就是去掉重复框的过程。同时针对每个类别(一共20类)训练一个回归器,输入是pool5的特征和每个样本对的坐标即长宽。
在R-CNN中,候选区域需要进过变形缩放,以此适应CNN输入,那么能不能修改网络结构,使得任意大小的图片都能输入到CNN中呢?作者提出了spatial pyramid pooling结构来适应任何大小的图片输入。
由于FC层的存在,普通的CNN通过固定输入图片的大小来使得全连接层输入固定。作者不这样思考,既然卷积层可以适应任何尺寸,那么只需要在卷积层的最后加入某种结构,使得后面全连接层得到的输入为固定长度就可以了。
在最后的卷积层和全连接层之间加入SPP层。具体做法是,在conv5层得到的特征图是256层,每层都做一次spatial pyramid pooling。先把每个特征图分割成多个不同尺寸的网格,比如网格分别为4×4、2×2、1×1,然后每个网格做max pooling,这样256层特征图就形成了16×256,4×256,1×256维特征,他们连起来就形成了一个固定长度的特征向量(16+4+1),将这个向量输入到后面的全连接层。
Fast-cnn可以看做是针对SPP-net与RCNN的增强版,针对两个方法中存在的问题提出了以下的解决方案:
针对以上的问题,fastcnn有以下的贡献
经过R-CNN和Fast RCNN的积淀,Ross B. Girshick在2016年提出了新的Faster RCNN,在结构上,Faster RCNN已经将特征抽取(feature extraction),proposal提取,bounding box regression(rect refine),classification都整合在了一个网络中,使得综合性能有较大提高,在检测速度方面尤为明显。
Faster RCNN其实可以分为4个主要内容:
对于一个输入的
由于对于CNN网络已经比较了解,这里不再叙述feature map的生成过程目前只需要了解这个feature map是由ROI Pooling和RPN共享的。之后主要描述RPN网络以及RoI pooling两个部分。
所谓anchors,实际上就是一组由rpn/generate_anchors.py生成的矩形。直接运行作者demo中的generate_anchors.py可以得到以下输出:
[[ -84. -40. 99. 55.]
[-176. -88. 191. 103.]
[-360. -184. 375. 199.]
[ -56. -56. 71. 71.]
[-120. -120. 135. 135.]
[-248. -248. 263. 263.]
[ -36. -80. 51. 95.]
[ -80. -168. 95. 183.]
[-168. -344. 183. 359.]]
其中每行的4个值 ( x 1 , y 1 , x 2 , y 2 ) (x_1,y_1,x_2,y_2) (x1,y1,x2,y2) 表矩形左上和右下角点坐标。9个矩形共有3种形状,长宽比为大约为 w i d t h : h e i g h t ∈ { 1 : 1 , 1 : 2 , 2 : 1 } width:height \in \left\{ {1:1,1:2,2:1} \right\} width:height∈{1:1,1:2,2:1}三种,如图6。实际上通过anchors就引入了检测中常用到的多尺度方法。
遍历Conv layers计算获得的feature maps,为每一个点都配备这9种anchors作为初始的检测框。 这样做获得检测框很不准确,不用担心,后面还有2次bounding box regression可以修正检测框位置。
其实RPN最终就是在原图尺度上,设置了密密麻麻的候选Anchor。然后用cnn去判断哪些Anchor是里面有目标的positive anchor,哪些是没目标的negative anchor。所以,仅仅是个二分类而已!
所示绿色框为飞机的Ground Truth(GT),红色为提取的positive anchors,即便红色的框被分类器识别为飞机,但是由于红色的框定位不准,这张图相当于没有正确的检测出飞机。所以我们希望采用一种方法对红色的框进行微调,使得positive anchors和GT更加接近。
针对红框变为绿框中需要进行的变化为平移以及拉伸,对于长宽分别需要两个数字表示,因此共需要4个元素进行变换。
针对这个要求得到对应的损失函数为
在了解bounding box regression后,再回头来看RPN网络第二条线路
Proposal Layer负责综合所有 [ d x ( A ) , d y ( A ) , d w ( A ) , d h ( A ) ] [d_x(A),d_y(A),d_w(A),d_h(A)] [dx(A),dy(A),dw(A),dh(A)] 变换量和positive anchors,计算出精准的proposal,送入后续RoI Pooling Layer。
RPN网络结构就介绍到这里,总结起来就是:
生成anchors -> softmax分类器提取positvie anchors -> bbox reg回归positive anchors -> Proposal Layer生成proposals
ROI层的特点已经在上面说通过不同的输入图像,提取出特定相同大小的特征图方便特征的计算。
Classification部分利用已经获得的proposal feature maps,通过full connect层与softmax计算每个proposal具体属于那个类别(如人,车,电视等),输出cls_prob概率向量;同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred,用于回归更加精确的目标检测框。Classification部分网络结构如下图。
在分类中我们最后在fasterRCNN中使用了proposal进行了特征框的提取。那能否在特征框的提取中进行目标的检测呢?
YoLo的主要分为两步走:
为了减少滑动窗口的计算量,对于图片的计算中是直接进行图片的分割(已经resize成一个固定大小的输入),例如一个256×256大小的一个图片,分割成一个S×S大小的网络,每个单元格中会预测B个边界框,以及每个边界框的置信度。
每个边框的置信度包括两个方面,边框含有目标的可能性 P r ( O b j e c t ) Pr(Object) Pr(Object)(是否为背景,如果为背景则为0)以及IOU交并比。其实置信度的定义为两个相乘:
在置信度之后还要给出每个分类的预测值C。
总结一下
每个单元格需要预测 ( B ∗ 5 + C ) (B*5+C) (B∗5+C) 个值。如果将输入图片划分为 S × S S×S S×S 网格,那么最终预测值为 S × S × ( B ∗ 5 + C ) S×S×(B*5+C) S×S×(B∗5+C)大小的张量。整个模型的预测值结构如下图所示。对于PASCAL VOC数据,其共有20个类别,如果使用 S = 7 , B = 2 S=7,B=2 S=7,B=2 ,那么最终的预测结果就是 7 × 7 × 30 7×7×30 7×7×30大小的张量。每个单元格的预测值的分布位置为(20个类别的概率+两个预测框的可信度+两个4维的预测框的偏移量)。
Yolo算法将目标检测看成回归问题,所以采用的是均方差损失函数。但是对不同的部分采用了不同的权重值。
损失函数如下:
第一项是边界框中心坐标的误差项,第二项是边界框的高与宽的误差项,第三项是包含目标的边界框的置信度误差项,四项是不包含目标的边界框的置信度误差项。
待续