转载于: RoyalVane
matlab+VC 实现Bag of features
Bag of features(Bof)一种是用于图像和视频检索的算法,此算法的神奇之处,就在于对于不同角度,光照的图像,基本都能在图像库中正确检索。而写这篇文章的目的也就在于向大家介绍这种神奇的图像检索算法,也是给自己做个备忘。
(Ps:阅读此文需要读者对图像提取特征点,生成描述符的知识有一定了解,如sift,surf算法等等,对生成向量类心的k-means算法也需要有一定的了解。本文附带的源码中也用到了opencv中surf的一些接口和k-means(matlab实现)的一些接口。)
为实现BoF算法,我们需要的工具有:
1:matlab
2:vs2010
3:opencv(本文所用为opencv2.2库,网上也有很多下载和配置教程。)
*4:我的BoF源码下载地址:
http://download.csdn.net/source/3489669
好了,下面就正式介绍BoF算法的思想。
Bof,即Bag of features,中文翻译为“词袋”,是一种用于图像或视频检索的技术。而检索就要进行比对。两幅不同的图像如何比对,比对什么,这就需要提炼出每幅图像中精练的东西出来进行比较。正如超市中的条形码,就能很好的反映出一件商品的所有特征。因此概括的来说,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向量求夹角,夹角最小的即为匹配对象。
其实思想也很简单,对吧~
后面就是编码实现了,其实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%,还是相当准的。