Bag of features算法--图像检索

目录

一、Bag of features算法

1、算法原理

2、算法步骤

3、补充:K-means算法

二、实验分析

1、收集图片

2、实验源码

2、运行结果

3、实验小结


 

一、Bag of features算法

1、算法原理

Bag of features算法一种是用于图像和视频检索的算法,该算法对于不同角度、光照的图像,基本都能在图像库中正确检索。

2、算法步骤

(1)收集图片,用sift算法生成图像库中没附图的特征及描述符。

(2)用K-means算法对图像库中的特征点进行训练,生成类聚中心。

(3)通过判断图像的每个特征点与那个类心最近,最近则放入该类心,最后生成一列频数表,生成每幅图像的BOF。

(4)对需要查询的图片不断进行(3)操作,生成一列查询图片的BOF。

(5) 将得到的BOF向量与图像库中每幅图的BOF向量求夹脚,夹脚最小的即为匹配对象。

3、补充:K-means算法

K-means算法是一种类聚算法,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇。

K-means算法步骤:

(1)从数据中选择K个对象作为初始类聚中心。

(2)计算每个类聚对象到类心的距离。

(3)计算标准测度函数,直到达到最大迭代次数,停止。

二、实验分析

1、收集图片

2、实验源码

(1)提取每张图片的sifi特征,生成词汇表。

import pickle

from PCV.imagesearch import vocabulary

from PCV.tools.imtools import get_imlist

from PCV.localdescriptors import sift

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


# 获取图像列表

imlist = get_imlist('E:/BOF/img1/')  # 存放数据集的路径

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('E:/BOF/vocabulary.pkl', 'wb') as f:
    pickle.dump(voc, f)

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

(2)连接数据库,将数据集转成数据库,方便查询。

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('E:/BOF/img1/')  # 存放数据集的路径

nbr_images = len(imlist)

# nbr_images = 300

# 获取特征列表

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

# 载入词汇

with open('E:/BOF/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())

(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('E:/Python37_course/test7/first1000/')
imlist = get_imlist('E:/BOF/img1/')
nbr_images = len(imlist)
#载入特征列表
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]

#载入词汇

with open('E:/BOF/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 = 15
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[:6]) #常规查询
imagesearch.plot_results(src,res_geom[:6]) #重排后的结果

2、运行结果

输入图片:

输出结果:

常规查询:

重排后结果: 

 

3、实验小结

 

根据上述实验结果可以看出,由于选取的图像集数量有限及其他各种因素,还是存在较大的误差,因此还需要进一步的探讨以及实验。

实验中遇到的一些小问题与解决方案:

(1)由于我们python的版本为3.6,所以pysqlite2不能使用,将其改为from sqlite3 import dbapi2 as sqlite.

(2)一定要记得将PCV放置在对应的路径下。

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值