DenseSift+BOW+SVM制作的目标识别程序


大家好,今天来跟大家分享一下最近做的一个目标识别的小程序。采用的方法是DenseSift+BOW词袋模型+SVM支持向量机。
1. 问题描述
目标识别,即给定一张图片,能够识别并标出图中的物体,是数字图像处理中一个经典内容。
pic1.JPG

目前的目标识别大部分利用的是有监督的训练方法。这里采用的训练集为PASCAL VOC2007数据集,下载地址为:http://pascallin.ecs.soton.ac.uk/challenges/VOC/ 该数据集分为训练集、测试集两部分。其中训练集5011张图片,测试集4952张图片。已经为每张训练集与测试集图片提供了20类物体标注及位置,这20类物体分别为:"aeroplane","bicycle","bird","boat","bottle","bus","car","cat","chair","cow","diningtable","dog","horse","motorbike","person","pottedplant","sheep","sofa","train","tvmonitor"。我们本学期数字图像处理的大作业即用该数据集训练一个可以从图片上识别这20类物体并标注其位置的一个分类程序。
2. 特征选择
要做目标识别,首先应当从图片上选取合适的描述特征。我们采用的是DenseSift。DenseSift是Sift的一种变种,其每个描述子也是一个128维的向量,表征的是关键点2邻域内16个像素点沿八个方向的梯度变化,因此维度为16*8=128。它与Sift最大的不同在于关键点的选取是稠密且同规格的,如下图所示。

pic2.JPG


我们的程序首先将训练集中每个图片上标注的物体按照类别切出来,再在切出的图片上提取其DenseSift。例如在这5011张图片中,238张图片中含有306架飞机,那么我们就有306个关于飞机的DenseSift矩阵,每个矩阵的列数为128,行数与对应的飞机图片大小有关。由于训练集的飞机有不同的尺度,因此每个矩阵的行数是不同的。
3. 词袋模型的建立
为了建立词袋模型,我们需要将提取出来的DenseSift特征进行离散化,即建立字典,找1000个标准词汇(注意每个标准词汇都是一个128维的向量),将所有DenseSift矩阵中的特征点都用欧氏距离最近的标准词汇上,进而对离散化后的DenseSift统计直方图,这样就能将每一张目标物体的图片用一个有1000个柱的直方图,即一个1000维度的一维向量表示。
这里1000个标准词汇理论上应当用所有DenseSift矩阵中的所有特征点做一个k-mean聚类,聚成1000类。由于总的特征点数据过多,都用来聚类的话会卡爆我的内存。因此实际操作上,我用前987张训练集图片上标注的目标物体的DenseSift特征点进行聚类,用的是OpenCV中的BOWKMeansTrainer进行3次迭代最终找出了1000个类的中心点作为1000个标准词汇。
然后,我们将上一步中得到的DenseSift矩阵的每一行都找到一个与其最接近的标准词汇替代,然后对每一个DenseSift对每一个标准词汇出现的频率进行直方图统计。之所以统计频率而不统计频数,是因为在我们的训练集中切出来的每个目标物体图片的大小是不一样的,因此最终得到的关键点数目也是不一致的。因此统计频率实质上是进行了一部归一化,使得我们每张图片统计结束后得到的都是一个1000维的单位向量。
4. 训练SVM支持向量机
进过上一步之后,306个飞机对象的图片都可以用一个1000维空间中的点来表示,我们可以将飞机对象的图片作为正样本,其他类别图片得到的点做负样本,这样就能为飞机训练一个SVM分类器。然而这一步要注意的是,由于负样本是其他19类样本的和,因此负样本的数量远远大于正样本的数量。会导致我们训练的SVM过拟合,即不管输入什么都输出-1.我们的解决方法是用全部的飞机对象,其他的样本数量只取正样本数量的十分之一,即30张图片进行训练。这样我们的正样本有306个,负样本有570个,比较均衡。用同样的方式可以为另外的19类物体分别训练出一个SVM。
5. 识别目标
有了每类物体的分类器后,任给一张图片,我们就能①对其提取DenseSift,②将其提取到的所有特征点离散化为1000个标准词汇并统计每个标准词汇出现频率的直方图,③将统计后得到的1000维向量做输入分别用20个SVM分类器预测其是否属于自己的类。以下是对整张图片进行识别后得到的结果。

2.jpg

3.jpg

4.jpg


通过比较可以发现,尽管dogy和中华田园犬中都识别出了dog,但同时混入了其他的动物例如cat与sheep。同样地,飞机虽然也被识别了出来,但同时还误识出了car。
而且在实验中还发现,只要是立方体、带有窗户的物体,都会识别成bus或train等缺陷。
6.基于滑动窗口的目标识别
最后要做的就是利用滑动窗口技术在一张图片上遍历识别其中的物体了。由于我们每个滑动窗口都要提取DenseSift、离散化、用SVM分类20次,加上滑动窗口后会更加费时。因此假定要识别一张宽为W高为H的图片,我们用W*H的窗口,W/2*H的窗口,W*H/2的窗口以及W/2*H/2的窗口进行扫描,每个窗口的步长为窗口宽与高的1/2。而且我们规定如果再大尺度的窗口下扫描出了任何物体,就不需在小尺度下进行扫描。好在大部分的图片在较大尺度下就能识别到物体。以下是一些结果:

pic3.JPG

pic4.JPG


7. 存在的不足
现在的问题是,动物类分类并不好,识别猫时会连带识别出鸟,识别狗时会连带识别出猫,识别人时会连带识别出马,识别火车时会连带识别出大巴车,识别鸟会识别出飞机;会把挂在墙上的画识别成显示器等。增大训练样本,会导致内存爆掉。如果建立更多SVM分类器的话,又会导致识别一张图片的速度下降。
在较大的滑动窗口中就能识别出位于屏幕中央非常小的物体,导致目标切割不准。
希望能把识别的准确率再提高一些,不知道大家有什么好的建议呢?
已邀请:

若如初见nwu

赞同来自: July


11.png

已经画出来了

要回复问题请先登录注册

返回顶部