Bag of features:图像检索
一、算法简介
1、原理
Bag-of-Words模型源于文本分类技术,在信息检索中,它假定对于一个文本,忽略其词序和语法、句法。Bag-of-words词袋模型最初被用在信息检索领域,对于一篇文档来说,假定不考虑文档内的词的顺序关系和语法,只考虑该文档是否出现过这个单词。
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是一种用于图像和视频检索的算法,这个算法厉害的地方在于对于不同角度不同光照的图像都能检索到。这个算法的模型源于文本分类技术,在信息检索中,它假定对于一个文本,忽略其词序和语法、句法。将其仅仅看作是一个词集合,或者说是词的一个组合,文本中每个词的出现都是独立的,不依赖于其他词是否出现,或者说这篇文章的作者在任意一个位置选择词汇都不受前面句子的影响而独立选择的。
2、流程
2.1、针对数据集,做SIFT特 征提取
2.2、根据SIFT特征提取结果,采用k-means算法学习“视觉词典.”
2.3、根据IDF原理,计算每个视觉单词的权
2.4、针对数据库中每张图片的特征集,根据视觉词典进行量化以及TF-IDF解算。每张图片转化成特征向量
2.5、对于输入的检索图像(非数据库中图片),计算SIFT特征,.并根据TF-IDF转化成频率直方图/特征向量
2.6、构造检索图像特征到数据库图像的倒排表,快速索引相关候选匹配图像集
2.7、针对候选匹配图像集与检索图像进行直方图/特征匹配
3、应用
Bag-of-Features更多地是用于图像分类或对象识别。对训练集提取Bag-of-Features特征,在某种监督学习(如:SVM)的策略下,对训练集的Bag-of-Features特征向量进行训练,获得对象或场景的分类模型;对于待测图像,提取局部特征,计算局部特征与词典中每个码字的特征距离,选取最近距离的码字代表该特征,建立一个统计直方图,统计属于每个码字的特征个数,即为待测图像之Bag-of-Features特征;在分类模型下,对该特征进行预测从实现对待测图像的分类。
二、实验步骤
1、构造不小于100张图片的数据集
2、针对数据集,做sift特征提取
3、根据SIFT特征提取结果,采用K-MEANS算法学习“视觉词典”,其中维度至少满足4个量级(比如10,50,100,1000,5000)
4、根据IDF原理,计算每个视觉单词的权
5、针对数据库中每张土坯那的特征集,根据视觉词典进行量化,以及TF-IDF解算。每张图片转化成特征向量
6、对于输入的检索图像(非数据库中图片),计算SIFT特征,并根据TF-IDF转化成频率直方图/特征向量
7、构造检索图像特征到数据库图像的倒排表,快速索引相关候选匹配图像集
8、针对候选匹配图像集与检索图像进行直方图/特征匹配
三、实验操作
四、实验总结
五、实验代码
(1)提取sift特征并建立视觉词典
# -*- coding: utf-8 -*- import pickle from PCV.imagesearch import vocabulary from PCV.tools.imtools import get_imlist from PCV.localdescriptors import sift #获取图像列表 imlist = get_imlist('C:/Users/Administrator/Desktop/pictures/') nbr_images = len(imlist) #获取特征列表 featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)] #提取文件夹下图像的sift特征 for i in range(nbr_images): sift.process_image(imlist[i], featlist[i]) #生成词汇 voc = vocabulary.Vocabulary('ukbenchtest') voc.train(featlist, 1000, 10) #保存词汇 # saving vocabulary with open('C:/Users/Administrator/Desktop/pictures/vocabulary.pkl', 'wb') as f: pickle.dump(voc, f) print ('vocabulary is:', voc.name, voc.nbr_words)
(2)将特征投影到词汇并提交到数据库
# -*- coding: utf-8 -*- import pickle from PCV.imagesearch import imagesearch from PCV.localdescriptors import sift from sqlite3 import dbapi2 as sqlite from PCV.tools.imtools import get_imlist #获取图像列表 imlist = get_imlist('C:/Administrator/Desktop/pictures/') nbr_images = len(imlist) #获取特征列表 featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)] # load vocabulary #载入词汇 with open('C:/Adminstrator/Desktop/pictures/vocabulary.pkl', 'rb') as f: voc = pickle.load(f) #创建索引 indx = imagesearch.Indexer('testImaAdd.db',voc) indx.create_tables() # go through all images, project features on vocabulary and insert #遍历所有的图像,并将它们的特征投影到词汇上 for i in range(nbr_images)[:1000]: locs,descr = sift.read_features_from_file(featlist[i]) indx.add_to_index(imlist[i],descr) # commit to database #提交到数据库 indx.db_commit() con = sqlite.connect('testImaAdd.db') print (con.execute('select count (filename) from imlist').fetchone()) print (con.execute('select * from imlist').fetchone())
(3)测试
# -*- coding: utf-8 -*- import pickle from PCV.localdescriptors import sift from PCV.imagesearch import imagesearch from PCV.geometry import homography from PCV.tools.imtools import get_imlist # load image list and vocabulary #载入图像列表 imlist = get_imlist('C:/Users/Administrator/Desktop/pictures/') nbr_images = len(imlist) #载入特征列表 featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)] #载入词汇 with open('C:/Users/Administrator/Desktop/pictures/vocabulary.pkl', 'rb') as f: voc = pickle.load(f) src = imagesearch.Searcher('testImaAdd.db',voc) # index of query image and number of results to return #查询图像索引和查询返回的图像数 q_ind = 6 nbr_results = 20 # regular query # 常规查询(按欧式距离对结果排序) res_reg = [w[1] for w in src.query(imlist[q_ind])[:nbr_results]] print ('top matches (regular):', res_reg) # load image features for query image #载入查询图像特征 q_locs,q_descr = sift.read_features_from_file(featlist[q_ind]) fp = homography.make_homog(q_locs[:,:2].T) # RANSAC model for homography fitting #用单应性进行拟合建立RANSAC模型 model = homography.RansacModel() rank = {} # load image features for result #载入候选图像的特征 for ndx in res_reg[1:]: locs,descr = sift.read_features_from_file(featlist[ndx]) # because 'ndx' is a rowid of the DB that starts at 1 # get matches matches = sift.match(q_descr,descr) ind = matches.nonzero()[0] ind2 = matches[ind] tp = homography.make_homog(locs[:,:2].T) # compute homography, count inliers. if not enough matches return empty list try: H,inliers = homography.H_from_ransac(fp[:,ind],tp[:,ind2],model,match_theshold=4) except: inliers = [] # store inlier count rank[ndx] = len(inliers) # sort dictionary to get the most inliers first sorted_rank = sorted(rank.items(), key=lambda t: t[1], reverse=True) res_geom = [res_reg[0]]+[s[0] for s in sorted_rank] print ('top matches (homography):', res_geom) # 显示查询结果 imagesearch.plot_results(src,res_reg[:5]) #常规查询 imagesearch.plot_results(src,res_geom[:5]) #重排后的结果