计算机视觉——图像检索

目录

一:Bag-of-words简介

二: Bag-of-words原理及流程

2.1特征提取

2.2学习视觉词典

2.3对图像特征集进行量化

2.4将图像转换为视觉单词的频率直方图

2.5. 构造特征到图像的倒排表 

 2.6根据索引结果进行直方图匹配

三:实验测试


一:Bag-of-words简介

BoW模型最初是为解决文档建模问题而提出的,因为文本本身就是由单词组成的。它忽略文本的词序,语法,句法,仅仅将文本当作一个个词的集合,并且假设每个词彼此都是独立的。这样就可以使用文本中词出现的频率来对文档进行描述,将一个文档表示成一个一维的向量将一幅图像看着文本对象,图像中的不同特征可以看着构成图像的不同词汇。和文本的BoW类似,这样就可以使用图像特征在图像中出现的频率,使用一个一维的向量来描述图像。

二: Bag-of-words原理及流程

2.1特征提取

特征必须具有较高的区分度,而且要满足旋转不变性以及尺寸不变性等,通常采用SIFT特征。SIFT会从图片上提取出很多特征点,每个特征点都是 128 维的向量,如果图片足够多的话,我们会提取出一个巨大的特征向量库。

2.2学习视觉词典

提取完特征后,进行学习视觉词典,采取聚类算法对这些特征向量进行聚类。通才采用k-means聚类。

k-means聚类算法:最小化每个特征 xi 与其相对应的聚类中心 mk 之间的欧式距离

算法流程:

随机初始化 K 个聚类中心

重复下述步骤直至算法收敛:

        对应每个特征,根据距离关系赋值给某个中心/类别

对每个类别,根据其对应的特征集重新计算聚类中心

聚类是实现 visual vocabulary /codebook的关键

无监督学习策略

 k-means 算法获取的聚类中心作为 codevector

Codebook 可以通过不同的训练集协同训练获得

一旦训练集准备足够充分, 训练出来的码本( codebook)将 具有普适性

码本/字典用于对输入图片的特征集进行量化:对于输入特征,量化的过程是将该特征映射到距离其最接近 的 codevector

2.3对图像特征集进行量化

针对输入图片对应的特征集,根据视觉词典进行量化。

对于输出特征,量化的过程时将该特征映射到距离其最接近的视觉的单词,并实现计数。利用单词表的中词汇表示图像。利用SIFT算法,可以从每幅图像中提取很多个特征点,这些特征点都可以用单词表中的单词近似代替,通过统计单词表中每个单词在图像中出现的次数,可以将图像表示成为一个n维数值向量。

最常用的权重是TF-IDF(term frequency-inverse document frequency,词频- 逆向文档频率)。

单词w 在文档d中的词频是:

 逆向文档频率为:

 最终的TF-IDF权值为词频与逆文档频率的乘积。

2.4将图像转换为视觉单词的频率直方图

把输入图像,根据TF-IDF转化成视觉单词( visual words)的频率直方图 ,用视觉单词直方图来表示图像。如图下所示:

2.5. 构造特征到图像的倒排表 

构造特征到图像的倒排表,通过倒排表快速索引相关图像。以此可以快速使用倒排表进行计算测试图像与数据库中训练图像之间的相似性,索引到相关图片,然后和测试图像特征进行直方图匹配。

例:

 2.6根据索引结果进行直方图匹配

利用建立起来的索引找到包含特定的所有图像,即相似物体、相似的脸、相似颜色等;为了获得包含多个单词的候选图像,例如一个单词直方图中全部非零元素,在每个单词上进行遍历,得到包含改单词的图像列表,合并这些列表。然后创建一个元组列表有单词id和次数构成,其中次数以候选列表中每个单词出现的次数为准。同时还以元组中的第二个元素为准进行排序。最后会得到一个包含图像id的列表,排在列表最前面的是最好的匹配图像

利用一副图像进行查询是没必要进行完全的搜索,对了比较单词直方图,需要从数据库中读入图像单词直方图,检索每个单词直方图及候选图像列表,对于每个候选图像,用标准的欧式距离比较它和查询图像间的直方图,返回一个已经排好序的的元组列表。

三:实验测试

# -*- coding: utf-8 -*-
import pickle
from PCV.imagesearch import imagesearch
from PCV.geometry import homography
from PCV.tools.imtools import get_imlist
from PCV.localdescriptors import sift
import warnings
warnings.filterwarnings("ignore")

# 载入图像列表
imlist = get_imlist('E:\\workspace\\cv_code\\bagofword\\data')
nbr_images = len(imlist)
# 载入特征列表
featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)]

# 载入词汇
with open('E:\\workspace\\cv_code\\bagofword\\data\\vocabulary1000.pkl', 'rb') as f:
    voc = pickle.load(f, encoding='iso-8859-1')

src = imagesearch.Searcher('testImaAdd1000.db', voc)

# 查询图像索引和查询返回的图像数
q_ind = 1
nbr_results = 20

# 常规查询(按欧式距离对结果排序)
res_reg = [w[1] for w in src.query(imlist[q_ind])[:nbr_results]]
print('top matches (regular):', str(res_reg))

# 载入查询图像特征
q_locs, q_descr = sift.read_features_from_file(featlist[q_ind])
fp = homography.make_homog(q_locs[:, :2].T)

# 用单应性进行拟合建立RANSAC模型
model = homography.RansacModel()
rank = {}

# 载入候选图像的特征
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[:6])  # 常规查询
imagesearch.plot_results(src, res_geom[:6])  # 重排后的结果


版权声明:本文为hshagahhva原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。