Bag of features(Bof)一种是用于图像和视频检索的算法。此算法对于不同角度,光照的图像,基本都能在图像库中正确检索。
检索就要进行比对。两幅不同的图像如何比对,比对什么,这就需要提炼出每幅图像中精练的东西出来进行比较。正如超市中的条形码,就能很好的反映出一件商品的所有特征。因此概括的来说,bof就是生成每幅图像的“条形码”来进行检索。实验中,我们有一个包含100幅图像的小型图像库。然后再拿一些图像进行query,来找出库中与之对应的图像。
1.首先,我们用surf算法生成图像库中每幅图的特征点及描述符。
2.再用k-means算法对图像库中的特征点进行训练,生成类心。
3.生成每幅图像的BOF,具体方法为:判断图像的每个特征点与哪个类心最近,最近则放入该类心,最后将生成一列频数表,即初步的无权BOF。
4.通过tf-idf对频数表加上权重,生成最终的bof。(因为每个类心对图像的影响不同。比如超市里条形码中的第一位总是6,它对辨别产品毫无作用,因此权重要减小)。
5.对query进来的图像也进行3.4步操作,生成一列query图的BOF。
6.将query的Bof向量与图像库中每幅图的Bof向量求夹角,夹角最小的即为匹配对象。
图像检索中应用LSH实现快速搜索,其在一定概率的保证下解决了高维特征查询的问题,但笔者在应用LSH结合SIFT特征实践图像检索实验时,由于每张图像涉及上百个特征,那么在查询一张图片时,需要进行上而次的特征查询,即便是将查询图片的特征点数筛选至50%的量,一次图片查询需要进行的特征查询次数亦不容小窥。那么有没有方法可以将任意图片的所有特征向量用一个固定维数的向量表出,且这个维数并不因图片特征点数不同而变化?本篇要讲到的方法可以解决这个问题,尽管它并不是因这个问题而生的。
Bag-of-Words模型源于文本分类技术,在信息检索中,它假定对于一个文本,忽略其词序和语法、句法。将其仅仅看作是一个词集合,或者说是词的一个组合,文本中每个词的出现都是独立的,不依赖于其他词是否出现,或者说这篇文章的作者在任意一个位置选择词汇都不受前面句子的影响而独立选择的。
图像可以视为一种文档对象,图像中不同的局部区域或其特征可看做构成图像的词汇,其中相近的区域或其特征可以视作为一个词。这样,就能够把文本检索及分类的方法用到图像分类及检索中去。
Accelerating Bag-of-Features SIFT Algorithm for 3D Model Retrieval
Bag-of-Features模型仿照文本检索领域的Bag-of-Words方法,把每幅图像描述为一个局部区域/关键点(Patches/Key Points)特征的无序集合。使用某种聚类算法(如K-means)将局部特征进行聚类,每个聚类中心被看作是词典中的一个视觉词汇(Visual Word),相当于文本检索中的词,视觉词汇由聚类中心对应特征形成的码字(code word)来表示(可看当为一种特征量化过程)。所有视觉词汇形成一个视觉词典(Visual Vocabulary),对应一个码书(code book),即码字的集合,词典中所含词的个数反映了词典的大小。图像中的每个特征都将被映射到视觉词典的某个词上,这种映射可以通过计算特征间的距离去实现,然后统计每个视觉词的出现与否或次数,图像可描述为一个维数相同的直方图向量,即Bag-of-Features。
Bag of Features Codebook Generation by Self-Organisation
Bag-of-Features更多地是用于图像分类或对象识别。在上述思路下对训练集提取Bag-of-Features特征,在某种监督学习(如:SVM)的策略下,对训练集的Bag-of-Features特征向量进行训练,获得对象或场景的分类模型;对于待测图像,提取局部特征,计算局部特征与词典中每个码字的特征距离,选取最近距离的码字代表该特征,建立一个统计直方图,统计属于每个码字的特征个数,即为待测图像之Bag-of-Features特征;在分类模型下,对该特征进行预测从实现对待测图像的分类。
Classification Process
1、局部特征提取:通过分割、密集或随机采集、关键点或稳定区域、显著区域等方式使图像形成不同的patches,并获得各patches处的特征。
其中,SIFT特征较为流行。
2、构建视觉词典
由聚类中心代表的视觉词汇形成视觉词典:
3、生成码书,即构造Bag-of-Features特征,也即局部特征投影过程
4、SVM训练BOF特征得分类模型,对待测图像BOF特征预测
Retrieval Process
Bag-of-words在CV中的应用首先出现在Andrew Zisserman[6]中为解决对视频场景的搜索,其提出了使用Bag-of-words关键点投影的方法来表示图像信息。后续更多的研究者归结此方法为Bag-of-Features,并用于图像分类、目标识别和图像检索。在Bag-of-Features方法的基础上,Andrew Zisserman进一步借鉴文本检索中TF-IDF模型(Term Frequency-Inverse Document Frequency)来计算Bag-of-Features特征向量。接下来便可以使用文本搜索引擎中的反向索引技术对图像建立索引,高效的进行图像检索。
Hamming embedding and weak geometric consistency for large scale image search
实现检索的过程同分类的过程无本质的差异,更多的是细节处理上的差异:
1、局部特征提取;
2、构建视觉词典;
3、生成原始BOF特征;
4、引入TF-IDF权值:
TF-IDF是一种用于信息检索的常用加权技术,在文本检索中,用以评估词语对于一个文件数据库中的其中一份文件的重要程度。词语的重要性随着它在文件中出现的频率成正比增加,但同时会随着它在文件数据库中出现的频率成反比下降。TF的主要思想是:如果某个关键词在一篇文章中出现的频率高,说明该词语能够表征文章的内容,该关键词在其它文章中很少出现,则认为此词语具有很好的类别区分度,对分类有很大的贡献。IDF的主要思想是:如果文件数据库中包含词语A的文件越少,则IDF越大,则说明词语A具有很好的类别区分能力。
词频(Term Frequency,TF)指的是一个给定的词语在该文件中出现的次数。如:tf = 0.030 ( 3/100 )表示在包括100个词语的文档中, 词语'A'出现了3次。
逆文档频率(Inverse Document Frequency,IDF)是描述了某一个特定词语的普遍重要性,如果某词语在许多文档中都出现过,表明它对文档的区分力不强,则赋予较小的权重;反之亦然。如:idf = 13.287 ( log (10,000,000/1,000) )表示在总的10,000,000个文档中,有1,000个包含词语'A'。
最终的TF-IDF权值为词频与逆文档频率的乘积。
5、对查询图像生成同样的带权BOF特征;
6、查询:初步是通过余弦距离衡量,至于建立索引的方法还未学习到,望看客指点。
Issues
1、使用k-means聚类,除了其K和初始聚类中心选择的问题外,对于海量数据,输入矩阵的巨大将使得内存溢出及效率低下。有方法是在海量图片中抽取部分训练集分类,使用朴素贝叶斯分类的方法对图库中其余图片进行自动分类。另外,由于图片爬虫在不断更新后台图像集,重新聚类的代价显而易见。
2、字典大小的选择也是问题,字典过大,单词缺乏一般性,对噪声敏感,计算量大,关键是图象投影后的维数高;字典太小,单词区分性能差,对相似的目标特征无法表示。
3、相似性测度函数用来将图象特征分类到单词本的对应单词上,其涉及线型核,塌方距离测度核,直方图交叉核等的选择。
4、将图像表示成一个无序局部特征集的特征包方法,丢掉了所有的关于空间特征布局的信息,在描述性上具有一定的有限性。为此, Schmid[2]提出了基于空间金字塔的Bag-of-Features。
5、Jégou[7]提出VLAD(vector of locally aggregated descriptors),其方法是如同BOF先建立出含有k个visual word的codebook,而不同于BOF将一个local descriptor用NN分类到最近的visual word中,VLAD所采用的是计算出local descriptor和每个visual word(ci)在每个分量上的差距,将每个分量的差距形成一个新的向量来代表图片。
Resources
Two bag-of-words classifiers(Matlab)
Code for Vocabulary tree based image search(C++)
matlab+VC 实现Bag of features
Bag of Words/Bag of Features的Matlab源码
aMMAI BLOG
Visual Wordsを用いた類似画像検索
bayonを使って画像からbag-of-keypointsを求める
Paper
1.Bag of words models(.ppt ) byLi Fei-Fei(Stanford)
2. Spatial Pyramid Matching:Beyond Bags of Features: Spatial Pyramid Matching for Recognizing Natural Scene CategoriesS. Lazebnik, C. Schmid, and J. Ponce, CVPR 2006
Slides, MATLAB code, scene category dataset
3. Improving bag-of-features for large scale image search
Improving bag-of-features for large scale image search.
Hervé Jégou, Matthijs Douze, Cordelia Schmid.International Journal of Computer Vision, Volume 87, Number 3 - feb 2010.[pdf]
Demo:bigimbaz image search engine
4. Hamming embedding and weak geometric consistency for large scale image search. Hervé Jégou, Matthijs Douze, Cordelia Schmid
European Conference on Computer Vision - oct 2008.[pdf][slides]
5. Bag-of-colors for improved image search. Christian Wengert, Matthijs Douze, Hervé Jégou,ACM Multimedia (2011).[pdf]
6. Video Google: A Text Retrieval Approach to Object Matching in Videos . J. Sivic, A. Zisserman. IEEE International Conference on Computer Vision, Volume 2, page 1470--1477, 2003.[PDF ]
7.Aggregating local descriptors into a compact image representation. Hervé Jégou, Matthijs Douze, Cordelia Schmid, Patrick Pérez. IEEE Conference on Computer Vision & Pattern Recognition - jun 2010. [pdf][sildes]
code
为实现BoF算法,我们需要的工具有:matlab,vs2010,opencv(本文所用为opencv2.2库)
BoF源码下载地址:http://download.csdn.net/source/3489669
opencv库和yael库中已经分别把生成描述符和k-means训练类心的接口都给出来了,所以写代码也很简单。源码我在上文已经给了下载地址,下面讲讲怎么用它。
下载下来可以看到,文件夹中含有两部分,一部分是yael,这是matlab实现的k-means算法。另一个是testsurf,是我用opencv接口编写的一个图像提点、生成描述符的程序。
整个实现过程需要两者的配合,即需要用matlab来调用vc所生成的exe文件。
具体步骤
1:用vc2010打开testsurf工程,修改include、lib路径至你自己的opencv2.2中的include及lib文件夹。(*特别注意:打开cpp文件你会看到有一大段是被注释掉的,千万别把它删了!!因为我将图像库生成描述符和query图像生成描述符分为了两个过程。首先运行,将生成的exe文件重命名为query.exe,放入opencv2.2的bin中,然后将原来的注释打开,而将现有的代码注释掉,再次运行,生成testsurf.exe,也保存在bin中。生成工程时,有warning是正常,因为现在的main参数为空,argv[]=null,以后需要用matlab对其进行传参。把生成的EXE文件放入opencv2.2中的bin文件夹里是因为需要其中的DLL。)
2:自己建立100幅图像的原始库和100幅图像的查询库,文件名要以001.jpg~100.jpg严格命名。(主要是图像库过大,我无法上传)。路径为D:\pic_test\business_cards\Canon (原始图像库)
D:\pic_test\business_cards\Reference (查询库)
3:打开matlab,将yael里的matlab文件夹加入到matlab路径中。可以看到里面有两个文件surf_bof.m和surf_query.m,这两个是我自己编写的,都有注释,先运行第一个,在运行第二个,就会有结果了。运行结果会很长,将近要1个多小时,请耐心等待,别以为是死机而中断了。如果有错matlab会报的,没报错就耐心等待。
4:在D盘的Surf_BoF文件夹中会有一些保存的数据产生,读者可以结合程序看看里面的内容,更好的感受算法的整个流程。
最后的Final_result显示的就是匹配率,运行的结果达到了82%。