标签:常用 均值 sift 介绍 extract 运算 调用 简介 快速
今天主要回顾一下关于图像检索中VLAD(Vector of Aggragate Locally Descriptor)算法,免得时间一长都忘记了。关于源码有时间就整理整理。
一、简介
虽然现在深度学习已经基本统一了图像识别与分类这个江湖,但是我觉得在某些小型数据库上或者小型的算法上常规的如BoW,FV,VLAD,T-Embedding等还是有一定用处的,如果专门做图像检索的不知道这些常规算法也免得有点贻笑大方了。
如上所说的这些算法都大同小异,一般都是基于局部特征(如SIFT,SURF)等进行特征编码获得一个关于图像的feature,最后计算feature之间的距离,即使是CNN也是这个过程。下面主要就是介绍一下关于VLAD算法,它主要是得优点就是相比FV计算量较小,相比BoW码书规模很小,并且检索精度较高。
二、VLAD算法
SurfFeatureDetector detector; SurfDescriptorExtractor extractor; detector.detect( image_0, keypoints ); extractor.compute( image_0, keypoints, descriptors );
如果对特征有什么要求也可以根据OpenCV的源码或者网上的源码进行修改,最终的结果就是提取到了一幅图像的局部特征(还有关于局部特征参数的控制);
kmeans(descriptors, numClusters, labels, TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 0.01 ), 3, KMEANS_PP_CENTERS, centers);
需要做的就是定义一些参数,如果自己写的话就不清楚了。另外码书的大小从64-256甚至更大不等,理论上码书越大检索精度越高。
const int k=1, Emax=INT_MAX;
KDTree T(centers,false); T.findNearest(descriptors_row, k, Emax, idx_t, noArray(), noArray());
通过KDTree下的findNearest函数找到与之最近的聚类中心,需要注意的是输入的STL的vector类型,返回的是centers的索引值;
PCA pca( vlad, noArray(), CV_PCA_DATA_AS_ROW, 256 );
pca.project(vlad,vlad_tt);
输入训练矩阵,定义按照行或列进行降维,和降维之后的维度,经过训练之后就可以进行投影处理了,也可以直接调用特征向量进行矩阵乘法运算。这里有一点就是PCA的过程是比较费时的,进行查询的时候由于同样需要进行降维处理,所以可以直接保存投影矩阵(特征值矩阵),也可以把特征向量、特征值、均值都保存下来然后恢复出训练的pca,然后进行pca.project进行投影处理;
三、总结
可以看到,整个VLAD算法结合OpenCV实现起来还是非常简单的,并且小型数据库上的检索效果还可以,但是当数据库规模很大时只使用这一种检索算法检索效果会出现不可避免的下降。另外在作者的原文中,针对百万甚至千万级的数据库时单单使用PCA降维加速距离的计算仍然是不够的,所以还会使用称之为积量化或乘积量化(Product Quantization)的检索算法进行加速,这个也是一个很有意思的算法,以后有机会再介绍它。
标签:常用 均值 sift 介绍 extract 运算 调用 简介 快速
原文地址:http://www.cnblogs.com/mafuqiang/p/6909556.html