基于BOW模型的图像检索

一、BOW模型

Bag of words模型最初被用在文本分类中,将文档表示成特征矢量。它的基本思想是假定对于一个文本,忽略其词序和语法、句法,仅仅将其看做是一些词汇的集合,而文本中的每个词汇都是独立的。简单说就是讲每篇文档都看成一个袋子(因为里面装的都是词汇,所以称为词袋,Bag of words即因此而来),然后看这个袋子里装的都是些什么词汇,将其分类。如果文档中猪、马、牛、羊、山谷、土地、拖拉机这样的词汇多些,而银行、大厦、汽车、公园这样的词汇少些,我们就倾向于判断它是一篇描绘乡村的文档,而不是描述城镇的。至于为什么要用BOW模型描述图像,原因是SIFT特征虽然也能描述一幅图像,但是每个SIFT矢量都是128维的,而且一幅图像通常都包含成百上千个SIFT矢量,在进行相似度计算时,这个计算量是非常大的,通行的做法是用聚类算法对这些矢量数据进行聚类,然后用聚类中的一个簇代表BOW中的一个视觉词,将同一幅图像的SIFT矢量映射到视觉词序列生成码本,这样每一幅图像只用一个码本矢量来描述,这样计算相似度时效率就大大提高了。

二、基于BOW模型的图像搜索

对于两张图片,我们可以利用SIFT特征算法来进行特征匹配。但是面对大规模图像特征匹配,我们不可能一个个特征匹配,因为这样计算量实在是过于庞大。比如,25000张图片约有310亿个图相对,即使每个图匹配只需要两秒,也需要500台并行计算机工作一年才可以完成,所以我们不能用这种一个个特征匹配的暴力匹配法,需要寻找其他更快更有效的方法。我们发现,面对大场景数据集,其实只有少于0.1%的图像具有匹配关系,所以我们可用图像整体特征实现匹配/检索,而非局部特征点。所以,我们找到那个快速有效的方法——BOW模型。将BOW模型应用于图像领域,即把图像视为与位置无关的局部特征集合,局部特征就相当于文本中的单词,称为“视觉单词”,视觉单词的集合称为“视觉词典”(也叫码本)。
图像检索的基本流程是:

①特征提取(SIFT算法)

②学习“视觉词典(visual vocabulary)”(k-means算法)

③针对输入的特征集,根据视觉词典进行量化

④把输入图像转化成视觉单词(visual words)的频率直方图

⑤构造特征到图像的倒排表,通过倒排表快速索引相关图像

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

1.特征提取(SIFT算法)

特征提取就是从图像中提取出关键点(或特征点、角点)等,我们在这里采用的SIFT算法。SIFT算法用来侦测与描述影像中的局部特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。此算法由David Lowe 在1999 年所发表,2004 年完善总结。SIFT 算法的实质是在不同的尺度空间上查找关键点( 特征点),并计算出关键点的方向。SIFT 所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。SIFT 算法在构建好的尺度空间的基础上搜索尺度空间中的极值点( 特征点),然后确定极值点的尺度信息以及位置,再确定极值点的方向( 其邻域梯度的主方向),最终可以得到具有鲁棒性的128 维(448) 的特征向量。SIFT具体原理和实现参见我的另一篇博客:https://editor.csdn.net/md/?articleId=104702866

2.学习“视觉字典”

前面已经说过了,面对大场景数据集,只凭特征匹配,由于计算时间过长,是不可能实现图像检索的。所以我们想到了将相似的特征向量聚到一起,用一个视觉单词来表示这些特征,就像文本中用“walk”来表示“walk, walking,walks” 一样。我们采用的算法是K-means算法。
“K-means” 是一种基于样本间相似性度量的间接聚类方法,属于非监督学习方法。

输入:聚类个数k,图像的特征集合。
输出:满足方差最小标准的k个聚类。

最小化每个特征 与其相对应的聚类中心 之间的欧式距离。
算法流程是:
① 随机初始化 K 个聚类中心
②重复下述步骤直至算法收敛

对应每个特征,根据距离关系赋值给某个中心/类别(计算每个特征点到聚类中心的距离,将特征点分给离其最近的聚类中心,视为属于类,这里采用的距离是欧式距离。) 对每个类别,根据其对应的特征集重新计算聚类中心。
k-means算法的流程示意图如下:
在这里插入图片描述
k-means算法是实现视觉词典(码本)的关键,我们将K-means 算法获取的聚类中心作为视觉单词(码本向量)。当训练集准备足够充分是,训练出的码本将具有普适性。需要注意的是如何选择视觉词典/码本的规模,太少会出现视觉单词无法覆盖所有可能出现的情况;太多又会计算量大,容易过拟合。

3.针对输入的特征集,根据视觉字典进行量化

对于文本而言,当一个单词在所有文本都出现那么这个单词就不能区分文本。同理,如果一个视觉单词在每个图像中都出现,那么这个视觉单词就不能区分图像了。类比文本,我们这里也采用TF-IDF权重来表示视觉单词对区分图像的重要程度。

4.把输入图像转化为视觉单词的频率直方图

<
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
BOW (Bag of Words) 是一种常用的图像检索方法,其基本思想是将图像转化为向量,然后通过计算向量之间的距离来实现图像检索。下面是一个基于Python的BOW图像检索系统的设计思路和实现方法。 ## 设计思路 1. 预处理阶段:对于每张图片,提取其SURF特征,并使用K-means算法将特征向量聚类,得到视觉词汇表。 2. 训练阶段:对于每张图片,使用其SURF特征和视觉词汇表,构造其Bag of Words向量,并使用SVM分类器对图像进行分类。 3. 检索阶段:对于查询图片,提取其SURF特征并构造其Bag of Words向量,计算查询向量与训练集中所有图像的距离,并返回距离最近的前K张图片作为检索结果。 ## 实现方法 下面是一个基于Python的BOW图像检索系统的实现方法。 ### 1. 预处理阶段 ```python import cv2 import numpy as np from sklearn.cluster import KMeans # 定义SURF特征提取器 surf = cv2.xfeatures2d.SURF_create() # 定义K-means聚类器 kmeans = KMeans(n_clusters=50) # 加载训练集图片 train_images = [] for i in range(1, 11): img = cv2.imread(f'train/{i}.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) kp, des = surf.detectAndCompute(gray, None) train_images.append(des) # 将特征向量聚类,得到视觉词汇表 features = np.vstack(train_images) kmeans.fit(features) vocabulary = kmeans.cluster_centers_ ``` 以上代码中,我们使用OpenCV的SURF特征提取器提取训练集图片的SURF特征,并使用K-means算法将特征向量聚类,得到视觉词汇表。 ### 2. 训练阶段 ```python import os # 构造训练集的Bag of Words向量和标签 train_data = [] train_labels = [] for i in range(1, 11): img = cv2.imread(f'train/{i}.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) kp, des = surf.detectAndCompute(gray, None) words = kmeans.predict(des) bow_vector = np.zeros((1, 50)) for w in words: bow_vector[0, w] += 1 train_data.append(bow_vector) train_labels.append(i) # 使用SVM分类器对图像进行分类 svm = cv2.ml.SVM_create() svm.setType(cv2.ml.SVM_C_SVC) svm.setKernel(cv2.ml.SVM_LINEAR) svm.train(np.array(train_data), cv2.ml.ROW_SAMPLE, np.array(train_labels)) ``` 以上代码中,我们对每张训练集图片提取SURF特征并构造其Bag of Words向量,然后使用SVM分类器对图像进行分类。 ### 3. 检索阶段 ```python # 加载查询图片 query_img = cv2.imread('query.jpg') query_gray = cv2.cvtColor(query_img, cv2.COLOR_BGR2GRAY) query_kp, query_des = surf.detectAndCompute(query_gray, None) # 构造查询图片的Bag of Words向量 query_words = kmeans.predict(query_des) query_bow = np.zeros((1, 50)) for w in query_words: query_bow[0, w] += 1 # 计算查询向量与训练集中所有图像的距离 distances = [] for i in range(1, 11): img = cv2.imread(f'train/{i}.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) kp, des = surf.detectAndCompute(gray, None) words = kmeans.predict(des) bow_vector = np.zeros((1, 50)) for w in words: bow_vector[0, w] += 1 dist = np.linalg.norm(query_bow - bow_vector) distances.append((i, dist)) # 返回距离最近的前K张图片作为检索结果 k = 5 results = sorted(distances, key=lambda x: x[1])[:k] for r in results: print(f'train/{r[0]}.jpg') ``` 以上代码中,我们对查询图片提取SURF特征并构造其Bag of Words向量,然后计算查询向量与训练集中所有图像的距离,并返回距离最近的前K张图片作为检索结果。 ## 总结 BOW图像检索系统是一种基于特征向量的图像检索方法,在实际应用中具有广泛的应用。本文介绍了基于Python的BOW图像检索系统的设计思路和实现方法,希望能够对读者有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值