目录

一、原理解析

1.1计算机视觉领域的图像分类是什么意思?

1.2图像分类要如何实现?

1.3Bag-of-features算法和过程?

1.4TF-IDF?

1.5当前图像分类中会遇到一些值得挑战的问题

二、代码解析

2.1创建词汇

2.2 建立数据库

2.3在数据库中搜索图像


一.原理解析

1.1计算机视觉领域的图像分类是什么意思?

图像分类,即通过图像内容的不同将图像划分为不同的类别,该技术二十世纪九十年代末提出,并命名为基于图像内容的图像分类(Content- Based ImageClassific- ation, CEIC)算法概念,基于内容的图像分类技术不需要对图像的语义信息进行人工标注,而是通过计算机提取图像中所包含的特征,并对特征进行处理和分析,得出分类结果。
 
常用的图像特征有 图像颜色、纹理、灰度等信息。而图像分类过程中,提取的特征要求不容易受随机因素干扰,特征的有效提取可提高图像分类的精度。特征提取完成后,选择合适的算法创建图像类型与视觉特征之间的关联度,对图像进行类别划分。
 
图像分类领域中,根据图像分类要求,一般可以分为 场景分类和 目标分类两类问题。场景分类也可以称为事件分类,场景分类是对 整幅图像所代表的 整体信息进行分类,或者是对图像中所发生事件的总体描述。目标分类(又称为物体分类)是对图像中 出现的目标 (物体)进行识别或分类。

1.2图像分类要如何实现?

视觉词袋模型( Bag-of-features )是当前计算机视觉领域中较为常用的图像表示方法。
视觉词袋模型来源于词袋模型(Bag-of-words),词袋模型最初被用在文本分类中,将文档表示成特征矢量。它的基本思想是假定 对于一个文本,忽略其词序和语法、句法, 仅仅将其看做是一些词汇的集合, 而文本中的每个词汇都是独立的。简单说就是讲每篇文档都看成一个袋子 (因为里面装的都是词汇,
所以称为词袋,Bag of words即因此而来)然后看这个袋子里装的都是些什么词汇,将其分类。
如果文档中猪、 马、牛、羊、山谷、土地、拖拉机这样的词汇多些,而银行、大厦、汽车、公园这样的词汇少些, 我们就倾向于判断它是一 篇描绘乡村的文档,而不是描述城镇的。
Bag of Feature也是借鉴了这种思路,只不过在图像中,我们抽出的不再是一个个word, 而是 图像的关键特征Feature,所以研究人员将它更名为Bag of Feature.Bag of Feature在检索中的算法流程和分类几乎完全一样,唯一的区别在于,对于原始的BOF特征,也就是直方图向量,我们引入TF_IDF权值。

1.3Bag-of-features算法和过程?

算法过程:
1)提取图像特征
2)对特征进行聚类,得到一部视觉字典( visual vocabulary )
3)根据字典将图片表示成向量(直方图)
4)把输入图片转化成视觉单词的频率直方图
 
1)提取图像特征
特征提取及描述主要是将一些 具有代表性且 区分性较强的 全局或局部特征从图像中进行抽取,并对这些特征进行描述。
这些特征一般是类别之间差距比较 明显的特征,可以将其与其他类别区分开,其次,这些特征还要求具有 较好的稳定性,能够最大限度的在光照、视角、尺度、噪声以及各种外在因素变化的情况下保持稳定,不受其影响。这样即使在非常复杂的情况下,计算机也能通过这些稳定的特征很好的检测与识别出这个物体。
特征提取最简单且有效的方法就是 规则网格方法,
该方法采用均匀网格对图像进行划分,从而得到图像的局部区域特征。
兴趣点检测方法是另一个有效的特征提取方法,兴趣点检测的基本思想是:
在人为判断一幅图像的类别时,首先捕捉到物体的整体轮廓特征,然后聚焦于物体与其他物体具有显著特征区别的地方,最后判断出图像的类别。即通过该物体与其他物体 区别开的 显著特征,进而判断图像的类别。
在提取完图像的特征后,下一步就要应用特征描述子来对抽取的图像特征进行描述,特征描述子所表示的特征向量一般在处理算法时会作为输入数据,因此,如果描述子具有一定的判别性及可区分性,则该描述子会在后期的图像处理过程中起着很大的作用。
其中,SIFT描述子是近年比较经典且被广泛应用的一种描述子。
SIFT会从图片上提取出很多特征点,每个特征点都是128维的向量,因此,如果图片足够多的话,我们会提取出一个巨大的特征向量库。

2)训练字典( visual vocabulary )
 在上面提取完SIFT特征的步骤后,利用K-means聚类算法将提取的SIFT特征聚类生成视觉词典。
K-means算法是度量样本间相似性的一种方法,该算法设置参数为K,把N个对象分成K个簇,簇内之间的相似度较高,而簇间的相似度较低。聚类中心有K个,视觉词典为K。构建视觉单词的过程如图所示。

提取完特征后,我们会采用一些 聚类算法对这些特征向量进行聚类。 最常用的聚类算法是k-means。
至于k-means中的k如何取,要根据具体情况来确定。另外,由于特征的数量可能非常庞大,这个聚类的过程也会非常漫长。聚类完成后,我们就得到了这k个向量组成的字曲,这k个向量有一个通 用的表达,叫visual word.

3)图片直方图表示
利用视觉词典中的词汇表示待分类图像。计算每幅图像中的SIFT特征到这K个视觉单词的距离,
其中 距离最近的视觉单词为该SIFT特征对应的视觉单词。
通过统计每个单词在图像中出现的次数,将图像表示成一个K维数值向量,
如图所示,其中K=4,每幅图像用直方图进行描述。

4)训练分类器
当我们得到每幅图片的直方图向量后,剩下的这一步跟以往的步骤是一样的。
无非是数据库图片的向量以及图片的标签,训练分类器模型。然后对需要预测的图片,我们仍然按照上述方法,提取SIFT特征,再根据字典量化直方图向量,用分类器模型对直方图向量进行分类。当然,也可以直接根据 KNN 算法对直方图向量做相似性判断。

1.4TF-IDF?

TF-IDF(Term frequency-Inverse document frequency)是一种统计方法,用来评估特征词的重要程度。根据TF-IDF公式,特征词的权重与在 语料库中出现的频率有关,也与在文档里出现的频率有关。传统的TF-IDF公式如下:

TF-IDF用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。就目前来说,如果一个关键词只在很少的网页中出现,我们通过它就 容易锁定搜索目标,它的权重也就应该 大。反之如果一个词在大量网页中出现,我们看到它仍然 不是很清楚要找什么内容,因此它应该小。

1.5当前图像分类中会遇到一些值得挑战的问题

图像分类的目的是 通过图像内容对一幅未知图像进行分类。
但人类自身进行观察时,由于人们对图像的理解不同,偏重不同,不同的人也会产生不同的结果,
而且人为判断一幅图像的类别时,具有一定的主观性。
而计算机是客观的,它会通过一定的数据信息来判断图像的类别。
因此图像分类是一个比较困难的问题,并且该问题很难达到完美,
现在的分类方法大多都是尽可能地将分类准确率继续提高。
图像分类过程中遇到的问题主要是由 图像的类内变化、 图像类间的语义差异和 语义鸿沟造成的。

1、类内差异
所谓类内差异表示的是属于同一类的图像,由于各种原因,使图像的内容呈现出多种变化。
类内差异主要包括: 视角差异、目标形变、光照差异、尺度差异、部分遮挡、复杂背景、同类异形等

2、类间差异

所谓类间差异指的是不同类别含有相同的底层特征,导致不同类别图像分为同一类别。

3、语义鸿沟
长期的知识积累,人类可以通过对图像高层次的抽象理解进而对语义的相似性进行判断。
但计算机只能通过图像底层的统计特征来判断图像类别,不具备人类 对图像进行抽象和推理的能力,
导致计算机提取的图像底层视觉特征获取的图像类别信息和人类对图像的理解获取的图像类别信息不一致,造成“语义鸿沟”,
“语义鸿沟” 实际上就是图像的 底层视觉特征与 高层语义信息之间的 客观区别。

二、代码解析

2.1创建词汇

对每张图片生成相应的sif文件,及视觉词汇,以便建立BOW模型。如果需要增加图像或减少只需要改代码里读取训练图像的数量。要得到不同维度的量级,需要修改数据集训练次数。

def train(self,featurefiles,k=100,subsampling=10):""" 用含有k个单词的 K-means 列出在 featurefiles 中的特征文件训练出一个词汇。对训练数据下采样可以加快训练速度 """nbr_images = len(featurefiles)# 从文件中读取特征descr = []descr.append(sift.read_features_from_file(featurefiles[0])[1])# 将所有的特征并在一起,以便后面进行 K-means 聚类descriptors = descr[0]for i in arange(1,nbr_images):descr.append(sift.read_features_from_file(featurefiles[i])[1])descriptors = vstack((descriptors,descr[i]))#K-means: 最后一个参数决定运行次数self.voc,distortion = kmeans(descriptors[::subsampling,:],k,1)self.nbr_words = self.voc.shape[0]# 遍历所有的训练图像,并投影到词汇上imwords = zeros((nbr_images,self.nbr_words))for i in range( nbr_images ):imwords[i] = self.project(descr[i])nbr_occurences = sum( (imwords > 0)*1 ,axis=0)self.idf = log( (1.0*nbr_images) / (1.0*nbr_occurences+1) )self.trainingdata = featurefilesdef project(self,descriptors):""" 将描述子投影到词汇上,以创建单词直方图  """# 图像单词直方图imhist = zeros((self.nbr_words))words,distance = vq(descriptors,self.voc)for w in words:imhist[w] += 1return imhist
# -*- codeing =utf-8 -*-
# @Time : 2021/6/1 14:25
# @Author : ArLin
# @File : demo1.py
# @Software: PyCharm
# -*- 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('datasets/')
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, 37, 10)# 保存词汇
# saving vocabulary
with open('BOW\\vocabulary.pkl', 'wb') as f:pickle.dump(voc, f)
print('vocabulary is:', voc.name, voc.nbr_words)

同时生成了数据模型vocabulary.pkl,如果数据模型为空,在后面存入数据库会出现报错,读入数据为空。判断.pkl是否为空可根据查看它的大小,如图所示,这里pkl为41KB,故不为空

2.2 建立数据库

将上面得到的数据模型存放数据库testImaAdd.db中,即运行下面代码会生成一个testImaAdd.db数据库文件。

# -*- codeing =utf-8 -*-
# @Time : 2021/6/1 14:52
# @Author : ArLin
# @File : demo2.py
# @Software: PyCharm
import pickle
from PCV.imagesearch import imagesearch
from PCV.localdescriptors import sift
import sqlite3
from PCV.tools.imtools import get_imlist# 获取图像列表
# imlist = get_imlist('E:/Python37_course/test7/first1000/')
imlist = get_imlist('datasets/')
nbr_images = len(imlist)
# 获取特征列表
featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)]# load vocabulary
# 载入词汇
'''with open('E:/Python37_course/test7/first1000/vocabulary.pkl', 'rb') as f:voc = pickle.load(f)'''
with open('BOW\\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)[:36]:locs, descr = sift.read_features_from_file(featlist[i])indx.add_to_index(imlist[i], descr)
# commit to database
# 提交到数据库
indx.db_commit()con = sqlite3.connect('testImaAdd.db')
print(con.execute('select count (filename) from imlist').fetchone())
print(con.execute('select * from imlist').fetchone())

2.3在数据库中搜索图像

利用索引获取候选图像 + 用一幅图像进行查询 + 确定对比基准并绘制结果,建立好图像的索引,就可以在数据库中搜索相似的图像了。这里,使用BoW(词袋模型)来表示整个图像,这是通用的,可以应用于寻找相似的物体、相似的脸、相似的颜色等,它完全取决于图像及所用的描述子。为了实现搜索,在Imagesearch.py中添加Searcher类。

Searcher 类:
class Searcher(object):def __init__(self,db,voc):""" Initialize with the name of the database. """self.con = sqlite3.connect(db)self.voc = vocdef __del__(self):self.con.close()def get_imhistogram(self,imname):""" Return the word histogram for an image. """im_id = self.con.execute("select rowid from imlist where filename='%s'" % imname).fetchone()s = self.con.execute("select histogram from imhistograms where rowid='%d'" % im_id).fetchone()# use pickle to decode NumPy arrays from stringreturn pickle.loads(s[0])def candidates_from_word(self,imword):""" Get list of images containing imword. """im_ids = self.con.execute("select distinct imid from imwords where wordid=%d" % imword).fetchall()return [i[0] for i in im_ids]def candidates_from_histogram(self,imwords):""" Get list of images with similar words. """# get the word idswords = imwords.nonzero()[0]# find candidatescandidates = []for word in words:c = self.candidates_from_word(word)candidates+=c# take all unique words and reverse sort on occurrencetmp = [(w,candidates.count(w)) for w in set(candidates)]tmp.sort(key=cmp_to_key(lambda x,y:operator.gt(x[1],y[1])))tmp.reverse()# return sorted list, best matches first    return [w[0] for w in tmp]def query(self,imname):""" Find a list of matching images for imname. """h = self.get_imhistogram(imname)candidates = self.candidates_from_histogram(h)matchscores = []for imid in candidates:# get the namecand_name = self.con.execute("select filename from imlist where rowid=%d" % imid).fetchone()cand_h = self.get_imhistogram(cand_name)cand_dist = sqrt( sum( self.voc.idf*(h-cand_h)**2 ) )matchscores.append( (cand_dist,imid) )# return a sorted list of distances and database idsmatchscores.sort()return matchscoresdef get_filename(self,imid):""" Return the filename for an image id. """s = self.con.execute("select filename from imlist where rowid='%d'" % imid).fetchone()return s[0]def tf_idf_dist(voc,v1,v2):v1 /= sum(v1)v2 /= sum(v2)return sqrt( sum( voc.idf*(v1-v2)**2 ) )def compute_ukbench_score(src,imlist):""" Returns the average number of correctimages on the top four results of queries. """nbr_images = len(imlist)pos = zeros((nbr_images,4))# get first four results for each imagefor i in range(nbr_images):pos[i] = [w[1]-1 for w in src.query(imlist[i])[:4]]# compute score and return averagescore = array([ (pos[i]//4)==(i//4) for i in range(nbr_images)])*1.0return sum(score) / (nbr_images)

使用几何特性对结果排序

这是一种是常用BoW模型改进检索结果的常用方法。BoW模型的一个主要 缺点是在用视觉单词表示图像时 不包含图像特征的位置信息,这是为了 获取速度和可伸缩性而付出的 代价。最常用的方法是在查询图像与靠前图像的特征位置间拟合单应性。

# -*- codeing =utf-8 -*-
# @Time : 2021/6/1 15:29
# @Author : ArLin
# @File : demo3.py
# @Software: PyCharmimport 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('datasets/') # 存放数据集的路径
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)# index of query image and number of results to return
# 查询图像索引和查询返回的图像数
q_ind =18
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)# 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# 获取匹配数 # 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 countrank[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[:8])  # 常规查询
imagesearch.plot_results(src, res_geom[:8])  # 重排后的结果

查询图像在最左边,后面都是按图像列表检索的前5幅图像。
对输出的结果,首先是载入图像列表、特征列表及词汇。然后创建一个Searcher对象,执行定期查询,并将结果保存在res_reg列表中,然后载入res_reg列表中每一幅图像特征,并和查询的图像进行匹配。通过计算匹配数和计数内点数得到,最终可通过减少内点数目对包含图像索引和内点数的字典进行排序。最后可视化检索靠前的匹配图像结果。

计算机视觉-图像检索相关推荐

  1. Python计算机视觉——图像检索与识别

    目录 一.原理解析 1.1计算机视觉的图像分类是什么意思? 1.2图像分类如何实现? 1.3Bag of features算法和过程 1)提取图像特征 2)训练字典 3)图像直方图生成 4)训练分类器 ...

  2. 计算机视觉—BOW图像检索

    BOW图像检索 一.图像检索 1.1图像检索原理 1.2实现步骤 二.实验过程 2.1数据集 2.2代码 2.3结果 三.实验总结 一.图像检索 1.1图像检索原理 1.图像检索 简单的说便是从图片检 ...

  3. python计算机视觉--基于(BOW)的图像检索与识别

    目录 前言 一.基本原理 1.1 图像分类简介 1.2 Bag-of-words模型 1.3 Bag-of-features模型 1.4  Bag-of-features算法 1.5  Bag-of- ...

  4. CV之IR:计算机视觉之图像检索(Image Retrieval)方向的简介、使用方法、案例应用之详细攻略

    CV之IR:计算机视觉之图像检索(Image Retrieval)方向的简介.使用方法.案例应用之详细攻略 目录 图像检索(Image Retrieval)方向的简介 图像检索(Image Retri ...

  5. 计算机视觉——Bag Of features图像检索

    计算机视觉--Bag Of features图像检索 原理 什么是图像检索 什么是Bag Of Word模型 什么是sift特征提取 什么是视觉词典 什么是TF-IDF 基于BOW的图像检索步骤 结果 ...

  6. 【计算机视觉】基于BOW的图像检索

    一.图像检索概述 简单的说便是从图片检索数据库中检索出满足条件的图片,图像检索技术的研究根据描述图像内容方式的不同可以分为两类:一类是基于文本的图像检索技术,一类为基于内容的图像检索技术.它最早用于对 ...

  7. Python计算机视觉之基于BOW的图像检索

    目录 一.图像检索 1.1 简介 1.2 步骤 二.Bag Of Words模型(BOW) 2.1 简介 2.2 原理 2.2.1 特征提取 2.2.2 学习"视觉词典" 2.2. ...

  8. Python计算机视觉(五)——基于BOW的图像检索

    文章目录 一.图像搜索 二.BOW模型图像检索 1.BOW(Bag-of-words) 2.Bag-of-features 三.算法流程 1.特征提取 2.学习"视觉词典"(vis ...

  9. 基于BOW的图像检索 【计算机视觉第七章】

    目录 BOW简介 基于BOW的图像检索流程 1. 特征提取 (SIFT) 2. 学习 "视觉词典(visual vocabulary)" (k-means) 3. 针对输入特征集, ...

最新文章

  1. 近20个绚丽实用的jQuery/CSS3侧边栏菜单
  2. vsftp的安装或升级
  3. 30秒清除你电脑中的垃圾(使你电脑急速如飞)
  4. Qt Creator填写代码
  5. 信息学奥赛C++语言:5个人分糖块
  6. Win10电脑如何合并磁盘分区
  7. UnityShader2:Shader与材质
  8. C++ placement new使用
  9. 微任务,宏任务和Event-Loop
  10. 一起来学Spring Cloud | 第一章 :如何搭建一个多模块的springcloud项目
  11. 解析大型.NET ERP系统 业务逻辑设计与实现
  12. java - 小程序二维码中间的logo占整个二维码的比例计算
  13. 联想启天M4880(老机)安装Centos7安装总结
  14. STAF/STAX安装配置
  15. 人到中年怎样防止头发花白
  16. mc服务器天赋系统,我的世界战斗狂人的最爱Mod,天赋系统乱入,玩家发展不受限制...
  17. 身份证最后一位验证[python]
  18. 吐血整理:最受欢迎的250份学习资料,99%的DBA都收藏了!
  19. Teamviewer过期,获取免费版
  20. Apache Spark【从无到有从有到无】【编程指南】【AS5】结构化流编程指南

热门文章

  1. python执行mysql存储过程,Mysql学习---使用Python执行存储过程
  2. 膜片钳电生理检测ACSF和电极内液配制
  3. 电网计算机基础资料,国家电网考试大学计算机基础复习题.docx
  4. 数字化时代,CIO该如何定位自己的角色?
  5. 在项目管理中为什么要设置项目里程碑?
  6. java正则表达式所有字符串_java正则表达式如何获取字符串中所有匹配内容
  7. DataNavigator
  8. 6.django笔记之orm
  9. Python+selenium入门
  10. react实现粒子动画