本文对前面的几篇文章进行个总结,实现一个小型的图像检索应用。
一个小型的图像检索应用可以分为两部分:
train,构建图像集的特征数据库。
retrieval,检索,给定图像,从图像库中返回最类似的图像
构建图像数据库的过程如下:
生成图像集的视觉词汇表(Vocabulary)
提取图像集所有图像的sift特征
对得到的sifte特征集合进行聚类,聚类中心就是Vocabulary
对图像集中的图像重新编码表示,可使用BoW或者VLAD,这里选择VLAD.
将图像集中所有图像的VLAD表示组合到一起得到一个VLAD表,这就是查询图像的数据库。
得到图像集的查询数据后,对任一图像查找其在数据库中的最相似图像的流程如下:
提取图像的sift特征
加载Vocabulary,使用VLAD表示图像
在图像数据库中查找与该VLAD最相似的向量
构建图像集的特征数据库的流程通常是offline的,查询的过程则需要是实时的,基本流程参见下图:
由两部分构成:offline的训练过程以及online的检索查找
各个功能模块的实现
下面就使用VLAD表示图像,实现一个小型的图像数据库的检索程序。下面实现需要的功能模块
特征点提取
构建Vocabulary
构建数据库
第一步,特征点的提取
不管是BoW还是VLAD,都是基于图像的局部特征的,本文选择的局部特征是SIFT,使用其扩展RootSift。提取到稳定的特征点尤为的重要,本文使用OpenCV体哦那个的SiftDetecotr,实例化如下:
auto fdetector = xfeatures2d::SIFT::create(0,3,0.2,10);
create的声明如下:
static Ptr cv::xfeatures2d::SIFT::create ( int nfeatures = 0,
int nOctaveLayers = 3,
double contrastThreshold = 0.04,
double edgeThreshold = 10,
double sigma = 1.6
)
nfeatures 设置提取到的特征点的个数,每个sift的特征点都根据其对比度(local contrast)计算出来一个分数。设置了该值后,会根据分数排序,只保留前nfeatures个返回
nOctaveLayers 每个octave中的层数,该值可以根据图像的分辨率大小计算出来。D.Lowe论文中该值为3
contrastThreshold 过滤掉低对比度的不稳定特征点,该值越大,提取到的特征点越少
edgeThreshold