计算机视觉——Bag of features:图像检索

文章目录

  • 一、Bag of features算法
    • 1、算法原理
    • 2、算法过程
  • 二、实验分析
    • 1、数据集准备
    • 2、实验源码
      • 第一部分 sift特征匹配
      • 第二部分 将图片集特征提交到数据库
      • 第三部分 图片检索查询
    • 3、实验小结
  • 三、实验所遇到的问题

一、Bag of features算法

1、算法原理

Bag of features(Bof)一种是用于图像和视频检索的算法,此算法的神奇之处,就在于对于不同角度,光照的图像,基本都能在图像库中正确检索。Bof,即Bag of features,中文翻译为“词袋”,是一种用于图像或视频检索的技术。而检索就要进行比对。两幅不同的图像如何比对,比对什么,这就需要提炼出每幅图像中精练的东西出来进行比较。正如超市中的条形码,就能很好的反映出一件商品的所有特征。因此概括的来说,bof就是生成每幅图像的“条形码”来进行检索。

实验中,我们有一个包含100幅图像的小型图像库。然后再拿一些图像进行query,来找出库中与之对应的图像。

2、算法过程

1.首先,我们用sift算法生成图像库中每幅图的特征点及描述符。

2.再用k-means算法对图像库中的特征点进行训练,生成类心。

3.生成每幅图像的BOF,具体方法为:判断图像的每个特征点与哪个类心最近,最近则放入该类心,最后将生成一列频数表,即初步的无权BOF。
4.通过tf-idf对频数表加上权重,生成最终的bof。(因为每个类心对图像的影响不同。比如超市里条形码中的第一位总是6,它对辨别产品毫无作用,因此权重要减小)。
5.对query进来的图像也进行3.4步操作,生成一列query图的BOF。
6.将query的Bof向量与图像库中每幅图的Bof向量求夹角,夹角最小的即为匹配对象。

二、实验分析

1、数据集准备

本次实验准备了100张图片,来源于附近的景观,以及网络上面的图片。在实验开始前最好进行图片压缩,以方便后续的运行,否则速度将会很慢。同样也可以选择网络上的数据集直接进行操作。

2、实验源码

第一部分 sift特征匹配

# -*- coding: utf-8 -*

import pickle

from PCV.imagesearch import vocabulary

from PCV.tools.imtools import get_imlist

from PCV.localdescriptors import sift

# 要记得将PCV放置在对应的路径下


# 获取图像列表

imlist = get_imlist('D:/pycharm/untitled1/image/')  # 存放数据集的路径

nbr_images = len(imlist)  # 获取数据集的长度

# nbr_images = 300  # 可以是自己选择用多少张图片作为训练数据集

# 获取特征列表

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('imglltest')

voc.train(featlist, 300, 10)

# 保存词汇

with open('D:/pycharm/untitled1/vocabulary.pkl', 'wb') as f:
    pickle.dump(voc, f)

    print 'vocabulary is:', voc.name, voc.nbr_words

先将整个图片集的所有图片进行特征提取,生成一整个视觉词典。

第二部分 将图片集特征提交到数据库

# -*- 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

# 要记得将PCV放置在对应的路径下


# 获取图像列表

imlist = get_imlist('D:/pycharm/untitled1/image/')  # 存放数据集的路径

nbr_images = len(imlist)

# nbr_images = 300

# 获取特征列表

featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)]

# 载入词汇

with open('D:/pycharm/untitled1/vocabulary.pkl', 'rb') as f:  # 读取再上一步中保存的.pkl文件

    voc = pickle.load(f)

# 创建索引

index = imagesearch.Indexer('testImaAdd.db', voc)  # 创建数据库

index.create_tables()  # 创建数据库表单

# 遍历所有的图像,并将它们的特征投影到词汇上

for i in range(nbr_images)[:300]:
    locs, descr = sift.read_features_from_file(featlist[i])

    index.add_to_index(imlist[i], descr)

# 提交到数据库

index.db_commit()

con = sqlite.connect('testImaAdd.db')  # 连接到数据库

print con.execute('select count (filename) from imlist').fetchone()  # 数据库操作

print con.execute('select * from imlist').fetchone()

这里将提取到的特征值放入视觉字典后并将其连接到数据库,将一开始的整个数据集转成数据库,以方便后面的查询。
这里需要运用到新的库–sqlite库,利用sqlist库进行数据的存储和链接。因此在该部分运行前,需要先下载sqlite库。

第三部分 图片检索查询


# -*- 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

# 要记得将PCV放置在对应的路径下

# 载入图像列表

imlist = get_imlist('D:/pycharm/untitled1/image/')  # 存放数据集的路径

nbr_images = len(imlist)

# nbr_images = 300

# 载入特征列表

featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]

# 载入词汇

with open('D:/pycharm/untitled1/vocabulary.pkl', 'rb') as f:  # 存放模型的路径

    voc = pickle.load(f)

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

imlist = get_imlist('D:/pycharm/untitled1/image/')  # 存放数据集的路径

# 查询图像索引和查询返回的图像数

q_ind = 030    # 查询图片的索引

nbr_results = 5

# 常规查询(按欧式距离对结果排序)

res_reg = [w[1] for w in src.query(imlist[q_ind])[:nbr_results]]

print 'top matches (regular):', 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])

# 获取匹配数

# get matches执行完后会出现两张图片

matches = sift.match(q_descr, descr)

ind = matches.nonzero()[0]

ind2 = matches[ind]

tp = homography.make_homog(locs[:, :2].T)

# 计算单应性,对内点技术。如果没有足够的匹配书则返回空列表

try:

    H, inliers = homography.H_from_ransac(fp[:, ind], tp[:, ind2], model, match_theshold=4)

except:

    inliers = []

# 存储内点数

rank[ndx] = len(inliers)

# 将字典排序,以首先获取最内层的内点数

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])  # 重排后的结果

在以上建立了索引的情况下,可以进行图像的检索,输入需要检索的图片,跟整个数据集中的图片进行对比,挑出与该张图片较为匹配的五张图。

3、实验小结

1、实验图片:
计算机视觉——Bag of features:图像检索_第1张图片
实验结果:
实验出来了与要进行索引的图片最为相近的五张图
在这里插入图片描述经过ransac算法进行索引,显示最为接近的五张图
在这里插入图片描述2、实验图片:

计算机视觉——Bag of features:图像检索_第2张图片
实验出来了与要进行索引的图片最为相近的五张图
计算机视觉——Bag of features:图像检索_第3张图片经过ransac算法进行索引,显示最为接近的五张图
计算机视觉——Bag of features:图像检索_第4张图片从上述的结果中,可以看到第一组所得检测结果较为准确,但是第二组实验中的匹配结果出现了误差,5张图片中出现了一种不符合匹配的图片。可能是因为数据集中的建筑比较多,图片的背景都是蓝色,大致相似,因此导致了结果的不准确。这也说明此算法在一些检测程度上效果还不足,这说明可能在创建词汇上,特征描述相似,还不够准确独特,这就需要深入研究了。此次实验数据集只含100张图片,可以扩大数据集来进行更进一步的研究。

三、实验所遇到的问题

在本次实验中,运用到了sqlite库,python2.7的版本可以到https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl进行相应版本的下载,利用pip install pysqlite-2.8.3-cp27-cp27m-win_amd64.whl进行库的下载。
**注意:**在使用pip进行库的安装时,需要进入到该库所在的文件目录下面,否则系统找不到该文件会提示错误。
在这里插入图片描述

你可能感兴趣的:(计算机视觉)