pyhton BOF图像检索

BOF图像检索

1 图像检索

1.1 概述

  图像检索,就是从图片检索数据库中检索出满足条件的图片,图像检索技术的研究根据描述图像内容方式的不同可以分为两类:
  一类是基于文本的图像检索技术,简称TBIR,主要是利用文本标注的方式为图像添加关键词,这种方式需要人为给每一张图像标注,非常耗费人工。
  一类是基于内容的图像检索技术,简称CBIR,这种检索方式首先需要准备一个数据集(dateset)作为训练,通过某种算法提取数据集中每张图像的特征(SIFT特征)向量,然后将这些特征存储起来,组成一个数据库,当需要搜索某张图片的时候,就输入这张图片,然后提取输入图片的特征,用某种匹配准则将提取的输入图片的特征和数据库中的特征进行比较,最后从数据库中按照相似度从大到小输出相似的图片。

2 BOF( Bag of features )

2.1 概述

  BoF(Bag Of Feature)借鉴文本处理的词袋(BoW,Bag Of Bag)算法,将图像表示成视觉关键词的统计直方图。像文本的处理一样,提取文本中出现单词组成词汇表,这里关键是得到图像库的“词汇表”。为了得到图像库的“词汇表",通常对提取到的图像特征进行聚类,得到一定个数的簇。这些聚类得到的簇,就是图像的”词汇“,可以称为视觉词(Visual Word)。聚类形成的簇,可以使用聚类中心来描述,所以,视觉词指的是图像的局部区域特征(如纹理,特征点)经过聚类形成的聚类中心。
在这里插入图片描述

2.2 K-means聚类

  聚类(Clustering)是一种无监督学习算法,其目的是将数据集中的样本划分为若干个不相交的子集,每个子集称为一个簇(Cluster)。聚类的时候并不关心某一类是什么,只根据数据的相似性,将数据划分到不同的组中。每个组内的成员具有相似的性质。

聚类算法可以分为三类:

  原型聚类,此类算法假设聚类结构能够通过一组原型描述,这里原型指的是样本空间中具有代表性的点。
  密度聚类,该类算法假设聚类结构能够通过样本分布的紧密程度来确定。
  层次聚类,在不同的层次对数据集进行划分,从而形成树形的聚结构。
   K-Means算法是原型聚类的一种,对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。

  如果用数据表达式表示,假设簇划分为(C1,C2,…Ck),则我们的目标是最小化平方误差E:

在这里插入图片描述

其中μi是簇Ci的均值向量,有时也称为质心,表达式为:
在这里插入图片描述

K-Means算法基本流程:

  • 随机初始化 K 个聚类中心
  • 重复下述步骤直至算法收敛:
      对应每个特征,根据距离关系赋值给某个中心/类别
      对每个类别,根据其对应的特征集重新计算聚类中心

2.3 算法流程

1、准备一个训练图片集,提取这些图片的SIFT特征

2、对这些特征进行K-Means聚类,创建视觉词典。

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

4、输入测试图片,提取测试图片的SIFT特征,把输入图像转成视觉单词的频率直方图。

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

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


3 实验过程

3.1 实验数据

各种鸟类的图片百张左右:
在这里插入图片描述

3.2 实验代码

1、先提取训练图像集的 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('D:/pythonProjects/ImageRetrieval/first500/')
imlist = get_imlist('D:\\PythonProject\\图像检索\\images')
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('ukbenchtest')
voc.train(featlist, 1000, 10)
#保存词汇
# saving vocabulary
with open('D:\\PythonProject\\图像检索\\images\\vocabulary.pkl', 'wb') as f:
    pickle.dump(voc, f)
print('vocabulary is:', voc.name, voc.nbr_words)

2、将图像添加到数据库

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

#获取图像列表
imlist = get_imlist('D:\\PythonProject\\图像检索\\images')
nbr_images = len(imlist)
#获取特征列表
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]

# load vocabulary
#载入词汇
with open('D:\\PythonProject\\图像检索\\images\\vocabulary.pkl', 'rb') as f:
    voc = pickle.load(f)
#创建索引
indx = imagesearch.Indexer('testImaAdd.db',voc)
indx.create_tables()
# go through all images, project features on vocabulary and insert
#遍历所有的图像,并将它们的特征投影到词汇上
for i in range(nbr_images)[:500]:
    locs,descr = sift.read_features_from_file(featlist[i])
    indx.add_to_index(imlist[i],descr)
# 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())

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('D:\\PythonProject\\图像检索\\images')
nbr_images = len(imlist)
#载入特征列表
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]

#载入词汇
with open('D:\\PythonProject\\图像检索\\images\\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 = 0        # 检索的图像下标
nbr_results = 148 # 数据集大小

# 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:]:
    try:
        locs,descr = sift.read_features_from_file(featlist[ndx])  # because 'ndx' is a rowid of the DB that starts at 1
    except:
        continue
    # 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]) #重排后的结果



3.3 实验结果

检索的图像:
在这里插入图片描述
运行的结果:
在这里插入图片描述

3.4 结果分析

  输入一张小鸟的图像,观察输入的小鸟图像,小鸟有白,棕,黑三种颜色相间的羽毛花色,羽毛重叠展现的纹路,同时鸟的头部外观也很有特色,鸟的眼睛,嘴等;第二张小鸟虽然颜色不相近,但边缘部分有相似的地方,因此被认为和输入图像匹配;第三张、第六张的小鸟从羽毛花色,头部,眼睛,嘴上看均有相似之处。第五张的猫头鹰从羽毛花色,羽毛重叠展现的纹路上看最为相似。而第四张,仔细观察是鸟的脚部最为相似,外形和颜色都十分接近,因此也被匹配出来了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值