计算机视觉编程——图像搜索
文章目錄
- 圖像搜索
- 1 基于內容的圖像檢索
- 2 視覺單詞
- 3 圖像索引
- 3.1 建立數據庫
- 3.2 添加圖像
- 4 在數據庫中搜索圖像
- 4.1 利用索引獲取候選圖像
- 4.2 用一幅圖像進行查詢
- 4.3 確定對比基準并繪制結果
- 5 使用幾何特性對結果排序
- 6 建立演示程序以及Web應用
- 6.1 用CherryPy創建Web應用
- 6.2圖像搜索演示程序
圖像搜索
1 基于內容的圖像檢索
在大型圖像數據庫上,CBIR(基于內容的圖像檢索)用于檢索在視覺上具有相似性的圖像。這樣的返回的圖像可以是顏色相似、紋理相似、圖像中的物體或者場景相似。
矢量空間模型是一個用于表示和搜索文本文檔的模型,它基本可以應用于任何對象類型,包括圖像。通過單詞計數來構建文檔直方圖向量v,從而建立起文檔索引。圖像內容檢索與文本檢索類似,使用局部特征構建視覺詞袋向量來表示圖像。對圖像提取若干個局部特征描述子,對這些描述子進行量化。聚類后的質心即為視覺單詞。得到視覺詞庫后,輸入檢索圖像提取其特征,與目標庫比對查找近鄰向量,計算距離即可。
2 視覺單詞
它的思想是將描述子空間量化成一些典型實例,并將圖像中的每個描述子指派到其中的某個實例中。這些典型實例可以通過分析訓練圖像集確定,并被視為視覺單詞。對于給定的問題、圖像類型,或是在通常情況下僅需呈現視覺內容,可以創建特定的詞匯。
從一個圖像集提取特征描述子,利用一些聚類算法可以構建出視覺單詞。采用聚類算法得到的視覺單詞是聚類質心,用視覺單詞直方圖來表示圖像,則該模型就被稱為BOW模型。
為創建視覺單詞詞匯,首先需要提取特征描述子。在這里使用SIFT特征描述子。運行下面的代碼,可以得到每幅圖像提取出的描述子,并將每幅圖像的描述子保存在一個文件中:
nbr_images = len(imlist) featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)]for i in range(nbr_images):sift.process_image(imlist[i], featlist[i])創建一個詞匯類,以及在訓練圖像數據集上訓練處一個詞匯的方法:
class Vocabulary(object):def __init__(self,name):self.name = nameself.voc = []self.idf = []self.trainingdata = []self.nbr_words = 0def train(self,featurefiles,k=100,subsampling=10): nbr_images = len(featurefiles)# read the features from filedescr = []descr.append(sift.read_features_from_file(featurefiles[0])[1])descriptors = descr[0] #stack all features for k-meansfor i in arange(1,nbr_images):descr.append(sift.read_features_from_file(featurefiles[i])[1])descriptors = vstack((descriptors,descr[i]))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 imhistVocabulary類包含了一個由單詞聚類中心VOC與每個單詞對應的逆向文檔頻率構成的向量,為了在某些圖像集上訓練詞匯,train()方法獲取包含有.sift后綴的描述文件列表和詞匯單詞數k。
下面的代碼根據提取出的sift文件創建一個長為k的詞匯表:
voc = vocabulary.Vocabulary('ukbenchtest') voc.train(featlist, 1000, 10)with open('vocabulary.pkl', 'wb') as f:pickle.dump(voc, f)print('vocabulary is :', voc.name, voc.nbr_words)3 圖像索引
在開始搜索之前,需要建立圖像數據庫和圖像的視覺單詞表示。
3.1 建立數據庫
在索引圖像之前,需要建立一個數據庫。這里,對圖像進行索引就是從這些圖像中提取描述子,利用詞匯將描述子轉換成視覺單詞,并保存視覺單詞以及對應圖像的單詞直方圖。從而可以利用圖像對數據庫進行查詢,并返回相似的圖像作為搜索結果。
在開始之前,需要創建表、索引和索引器Indexer類,以便將圖像數據寫入數據庫:
class Indexer(object):def __init__(self,db,voc):""" Initialize with the name of the database and a vocabulary object. """self.con = sqlite.connect(db)self.voc = vocdef __del__(self):self.con.close()def db_commit(self):self.con.commit()這里僅需一個包含三個表單的簡單數據庫模式。表單imlist包含所有索引的圖像文件名,imwords包含了一個那些單詞的單詞索引、用到的詞匯和單詞出現在哪些圖像中,最后imhistograms包含了全部每幅圖像的單詞直方圖。根據矢量空間模型需要這些以便進行圖像比較。
下面Indexer類中的方法用于創建表單以及一些有用的索引以加快搜索速度:
def create_tables(self): self.con.execute('create table imlist(filename)')self.con.execute('create table imwords(imid,wordid,vocname)')self.con.execute('create table imhistograms(imid,histogram,vocname)') self.con.execute('create index im_idx on imlist(filename)')self.con.execute('create index wordid_idx on imwords(wordid)')self.con.execute('create index imid_idx on imwords(imid)')self.con.execute('create index imidhist_idx on imhistograms(imid)')self.db_commit()3.2 添加圖像
有了數據庫表單,我們便可以在索引中添加圖像。為了實現該功能,需要在Indexer中加入add_to_index()方法:
def add_to_index(self,imname,descr):if self.is_indexed(imname): returnprint ('indexing', imname)imid = self.get_id(imname)imwords = self.voc.project(descr)nbr_words = imwords.shape[0]for i in range(nbr_words):word = imwords[i]self.con.execute("insert into imwords(imid,wordid,vocname) values (?,?,?)", (imid,word,self.voc.name))self.con.execute("insert into imhistograms(imid,histogram,vocname) values (?,?,?)", (imid,pickle.dumps(imwords),self.voc.name))該方法獲取圖像文件名與NumPy數組,該數組包含的是在圖像找到的描述子。這些描述子投影到該詞匯,并插入到imwords和imhistograms表單中。接下來使用兩個輔助函數:is_indexed()和get_id()檢查圖像是否已經被索引和對一幅圖像文件名給定id號。
def get_id(self,imname):cur = self.con.execute("select rowid from imlist where filename='%s'" % imname)res=cur.fetchone()if res==None:cur = self.con.execute("insert into imlist(filename) values ('%s')" % imname)return cur.lastrowidelse:return res[0] def is_indexed(self,imname):im = self.con.execute("select rowid from imlist where filename='%s'" % imname).fetchone()return im != None下面的實例代碼會遍歷整個ukbench數據庫中的樣本圖像,并將其加入索引。
with open('vocabulary.pkl', 'wb') as f:pickle.dump(voc, f)print('vocabulary is :', voc.name, voc.nbr_words)for i in range(nbr_images):sift.process_image(imlist[i], featlist[i])with open('vocabulary.pkl', 'rb') as f:voc = pickle.load(f)indx = imagesearch.Indexer('test.db', voc) indx.create_tables()for i in range(nbr_images)[:1000]:locs, descr = my_sift.read_features_from_file(featlist[i])indx.add_to_index(imlist[i], descr)index.db_commit()com = sqlite.connect('test.db') print(con.execute('select count (filename) from inlist').fetchone()) print(con.execute('select * from inlist').fetchone())4 在數據庫中搜索圖像
4.1 利用索引獲取候選圖像
4.2 用一幅圖像進行查詢
4.3 確定對比基準并繪制結果
5 使用幾何特性對結果排序
6 建立演示程序以及Web應用
6.1 用CherryPy創建Web應用
6.2圖像搜索演示程序
未完待續
總結
以上是生活随笔為你收集整理的计算机视觉编程——图像搜索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习——推荐算法
- 下一篇: 算法分析与设计——蛮力法0/1背包