计算机视觉-Bag of features

Bag of Feature 是一种参考文本检索中Bag of words的方法,其主要思想是将每幅图像描述为一个局部特征的无序序列,然后使用某种聚类方法将局部特征进行聚类,对每个聚类中心再将其量化成一个码字后,形成视觉词典。在检索时通过直方图向量去统计每个视觉词汇出现次数,这就是Bag of features。

一、Bag of Words 模型

要了解Bag of Feature,首先要知道Bag of Words。

Bag of Words 是文本分类中一种通俗易懂的策略。一般来讲,如果我们要了解一段文本的主要内容,最行之有效的策略是抓取文本中的关键词,根据关键词出现的频率确定这段文本的中心思想。这里所说的关键词,就是Bag of words中的 words ,它们是区分度较高的单词。根据这些 words ,我们可以很快地识别出文章的内容,并快速地对文章进行分类。而 Bag of Feature 也是借鉴了这种思路,只不过在图像中,我们抽出的不再是一个个word,而是图像的关键特征Feature,所以研究人员将它更名为Bag of Feature。

二、Bag of Feature 算法

Bag of Feature的本质是提出一种图像的特征表示方法。

按照Bag of Feature算法的思想,首先需要找到图像中的关键词,而且这些关键词必须具备较高的区分度。实际过程中,通常会采用SIFT特征。

有了特征之后,我们会将这些特征通过聚类算法得出很多聚类中心。这些聚类中心通常具有较高的代表性,比如,对于人脸来说,虽然不同人的眼睛、鼻子等特征都不尽相同,但它们往往具有共性,而这些聚类中心就代表了这类共性。我们将这些聚类中心组合在一起,形成一部字典(CodeBook)。

对于图像中的每个SIFT特征,我们能够在字典中找到最相似的聚类中心,统计这些聚类中心出现的次数,可以得到一个向量表示(有些文章称之为直方图),如本文开篇的图片所示。这些向量就是所谓的Bag。这样,对于不同类别的图片,这个向量应该具有较大的区分度,基于此,我们可以训练出一些分类模型(SVM等),并用其对图片进行分类。

4.步骤

1、构造一个数据集

2、用sift算子对数据集中每幅图提取特征点及描述符

3、采用k-means算法对特征点进行训练生成聚类中心,得到一部视觉字典

4、计算每个视觉单词的权重生成直方图

5、对于输入的检索图像计算sift特征生成直方图

6、构造检索图像到数据库图像的倒排表,对候选图像集通过倒排表快速索引相关图像

7、根据索引结果进行直方图匹配。

五、代码

构造数据集,提取特征点生成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('database/')
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('test77_test')
voc.train(featlist, 65, 10)
    
#保存词汇
# saving vocabulary
with open('BOW/vocabulary.pkl', 'wb') as f:
    pickle.dump(voc, f)
print ('vocabulary is:', voc.name, voc.nbr_words)

获取特征列表,载入词汇对,输入的检索图像计算sift特征以直方图形式保存,生成数据库

import pickle
from PCV.imagesearch import vocabulary
from PCV.tools.imtools import get_imlist
from PCV.localdescriptors import sift
from PCV.imagesearch import imagesearch
from PCV.geometry import homography
from sqlite3 import dbapi2 as sqlite  # 使用sqlite作为数据库

# 获取图像列表
imlist = get_imlist('database/')
nbr_images = len(imlist)
# 获取特征列表
featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)]

# load vocabulary
# 载入词汇
with open('BOW/vocabulary.pkl', 'rb') as f:
    voc = pickle.load(f)
# 创建索引
indx = imagesearch.Indexer('testImaAdd.db', voc)  # 在Indexer这个类中创建表、索引,将图像数据写入数据库
indx.create_tables()  # 创建表
# go through all images, project features on vocabulary and insert
# 遍历所有的图像,并将它们的特征投影到词汇上
for i in range(nbr_images)[:888]:
    locs, descr = sift.read_features_from_file(featlist[i])
    indx.add_to_index(imlist[i], descr)  # 使用add_to_index获取带有特征描述子的图像,投影到词汇上
    # 将图像的单词直方图编码存储
# 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())

查询,匹配

# -*- 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('database/')
nbr_images = len(imlist)
#载入特征列表
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]

#载入词汇
with open('BOW/vocabulary.pkl', 'rb') as f:
    voc = pickle.load(f)

src = imagesearch.Searcher('testImaAdd.db',voc)# Searcher类读入图像的单词直方图执行查询

# index of query image and number of results to return
#查询图像索引和查询返回的图像数
q_ind = 3  #匹配
nbr_results = 6  #生成

# 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[:6]) #常规查询
# imagesearch.plot_results(src,res_geom[:6]) #重排后的结果

运行结果

 计算机视觉-Bag of features

 

 计算机视觉-Bag of features

 

上一篇:628_AUTOSAR_RS_Features阅读_集成、移植以及文档


下一篇:pytorch自学笔记——实战 Kaggle 比赛:预测房价