计算机视觉课后作业6——图像检索

                                   图像检索

1.实验目的:

从内容检索CBIR。外部给定一张图片,能够从内部数据库中找到相似的数张图片。

2.实验原理:

 

图像检索过程:查询图像输入——>预处理(尺寸归一化)(图像数据库)——>特征提取(图像特征库)——>特征欧氏距离——>相似性搜索——>得到结果

图像检索的本质是特征提取和相似度计算的过程。

关键问题1.怎么抽取图像众多像素点中的有效特征?

               2.如何进行相似度计算?

我们要提取局部特征而非全局特征,主要是以下原因:

        图像局部特征:角点,关键点,N*128维,N为关键点数,针对不同图像可能提取到不同特征个数,SIFT算法,尺度不变性,转换角度特征不变

        全局特征:整体,512维

        局部特征优于全局特征

图像局部特征进行相似点计算,利用局部特征点的匹配个数,越多越相似,匹配繁杂,次数非常大,所以我们考虑聚类分析,构建词袋模型

        词袋模型:提取所有图片的sift特征(全部是向量),统计在一起得到N*128维的矩阵,对该矩阵进行聚类(合并相近特征),得到的聚类矩阵(分为几类)的聚类中心就类似我们做文字统计的单词空间(所有单词)——拿图像二次分类的矩阵来对应简单例子的一次汇总。

这边涉及到两个主要算法:

首先是特征提取——SIFT算法,遍历检测数据集图片的角点。

其次是聚类分析——K_means算法,对于得到的特征的向量矩阵进行分类,相似特征归为一类,以聚类中心代替该类向量描述,得到的N个聚类中心相当于词典中的“字母”,简化匹配流程,构成视觉词典模型。

3.实验思路:

     1、构造一个数据集

     2、sift算子提取特征点及描述符

     3、采用k-means算法对特征点进行训练生成聚类中心

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

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

     6、构造检索图像到数据库图像的倒排表,针对候选图像集与检索图像进行匹配

4.具体实验:

   1、构造数据集并生成.sift文件:

         sift算法在之前的实验已经写过,主要是对于图片角点的检测。

if __name__ == '__main__':
    download_path = "C:/Users/oulia/Pictures/TXJS"
    path = "C:/Users/oulia/Pictures/TXJS"

    imlist = imtools.get_imlist(download_path)
    nbr_images = len(imlist)

    featlist = [imname[:-3] + 'sift' for imname in imlist]
    for i, imname in enumerate(imlist):
        sift.process_image(imname, featlist[i])

    matchscores = zeros((nbr_images, nbr_images))

    for i in range(nbr_images):
        for j in range(i, nbr_images):  # only compute upper triangle
            print('comparing ', imlist[i], imlist[j])
            l1, d1 = sift.read_features_from_file(featlist[i])
            l2, d2 = sift.read_features_from_file(featlist[j])
            matches = sift.match_twosided(d1, d2)
            nbr_matches = sum(matches > 0)
            print('number of matches = ', nbr_matches)
            matchscores[i, j] = nbr_matches

    # copy values
    for i in range(nbr_images):
        for j in range(i + 1, nbr_images):  # no need to copy diagonal
            matchscores[j, i] = matchscores[i, j]

    # 可视化

    threshold = 20  # min number of matches needed to create link 创建链接所需匹配的最小数量

    g = pydot.Dot(graph_type='graph')  # don't want the default directed graph

    for i in range(nbr_images):
        for j in range(i + 1, nbr_images):
            if matchscores[i, j] > threshold:
                # first image in pair
                im = Image.open(imlist[i])
                im.thumbnail((100, 100))
                filename = path + str(i) + '.jpg'
                im.save(filename)  # need temporary files of the right size
                g.add_node(pydot.Node(str(i), fontcolor='transparent', shape='rectangle', image=filename))

                # second image in pair
                im = Image.open(imlist[j])
                im.thumbnail((100, 100))
                filename = path + str(j) + '.jpg'
                im.save(filename)  # need temporary files of the right size
                g.add_node(pydot.Node(str(j), fontcolor='transparent', shape='rectangle', image=filename))

                g.add_edge(pydot.Edge(str(i), str(j)))

      数据集以及运行结果

    2、提取特征点并生成视觉词汇词典:

          k_means算法  创建直方图  生成视觉词汇词典

import pickle
from PCV.imagesearch import vocabulary
from PCV.tools.imtools import get_imlist
from PCV.localdescriptors import sift



#获取图像列表
imlist = get_imlist('C:/Users/oulia/Pictures/TXJS/')
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, 18, 3) # 使用k-means算法在featurelist里边训练处一个词汇
                             # 注意这里使用了下采样的操作加快训练速度
                             # 将描述子投影到词汇上,以便创建直方图
#保存词汇
# saving vocabulary
with open('C:/Users/oulia/PycharmProjects/untitled/BagOfFeature/BOW/vocabulary.pkl', 'wb') as f:
    pickle.dump(voc, f)
print ('vocabulary is:', voc.name, voc.nbr_words)

运行截图:

生成码本:

     3、遍历特征投影到词汇上存入数据库 建立数据库 testImaAdd

           建立数据库:有了视觉单词和对应的直方图后,就可以保存为一个数据库,当需要检索的时候输入图像在数据库中进行查询,返回一个匹配的搜索结果。

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('C:/Users/oulia/Pictures/TXJS/')
nbr_images = len(imlist)

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

# load vocabulary
#载入词汇
with open('C:/Users/oulia/PycharmProjects/untitled/BagOfFeature/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)[:18]:
    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())

运行截图:

创建数据库

 

      4、进行图像内部检索

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
#载入图像列表
from BagOfFeature.PCV.imagesearch import vocabulary

imlist = get_imlist('C:/Users/oulia/Pictures/TXJS/')
nbr_images = len(imlist)
print(nbr_images)

#载入特征列表
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]

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



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

# index of query image and number of results to return
#查询图像索引和查询返回的图像数
q_ind = 7
nbr_results = 5

# regular query
# 常规查询(按欧式距离对结果排序)
res_reg = [w[1] for w in src.query(imlist[q_ind])[:nbr_results]]
print('top matches (regular):', res_reg)

imagesearch.plot_results(src,res_reg[:5]) #常规查询

运行截图:

5.实验中遇到的问题:

     实验要求外部输入图像进行数据库检索部分尚未实现,由于数据库图片数量的局限性,在聚类方面的划分还可以进一步优化。

 

posted @ 2021-06-06 19:40  欧egg  阅读(346)  评论(0编辑  收藏  举报