圖像檢索
一、Bag of features算法
1.1Bag of features算法原理
1.2算法流程
二、基於Bag of features算法的圖像檢索
2.1代碼
2.2結果截圖
2.3小結
三、圖像源
四、實驗總結
五、遇到的問題以及解決方法
一、Bag of features算法
1.1Bag of features算法原理
此算法的思想是在我們先做一個數據集,然后找到圖像中的關鍵詞,這些關鍵詞必須具備較高的區分度,最主要的操作就是提取sift特征,然后對這些特征點進行聚類算法,然后得到聚類中心,聚類中心就具有很高的代表性,這些聚類中心形成字典,然后自取一張圖片,進行sift特征提取,就可以在字典里找到最相似的聚類中心,統計這些聚類中心出現的次數,然后就直方圖表示出來,對於不同類別的圖片,就可以訓練處一些分類模型,然后就可以進行圖片分類。
1.2算法流程
1.2.1收集數據集
1.2.2提取sift特征
1.2.3根據sift特征提取結果,進行聚類,得到一個字典
1.2.4根據字典將圖片表示成向量(直方圖);
1.2.5訓練分類器或者用 KNN 進行檢索
提取特征:
我們為了是圖片具有較高的分辨度,我們使用sift特征提取,保證旋轉不變性和尺度不變性,每個特征點都是128維的向量,將會提取很多的特征點
得到字典:
我們再次之前提取了很多的特征向量,然后就對這些特征向量進行k-means聚類,k值根據實際情況而定。聚類完成后,我們就得到了這 k 個向量組成的字典,這 k 個向量有一個通用的表達,叫 visual word。
直方圖表示:
聚類之后,我們匹配圖片的「SIFT」向量與字典中的 visual word,統計出最相似的向量出現的次數,最后得到這幅圖片的直方圖向量。
訓練分類器:
當我們得到每幅圖片的直方圖向量后,剩下的這一步跟以往的步驟是一樣的。無非是根據數據庫圖片的向量以及圖片的標簽,訓練分類器模型。然后對需要預測的圖片,我們仍然按照上述方法,提取「SIFT」特征,再根據字典量化直方圖向量,用分類器模型對直方圖向量進行分類。當然,也可以直接根據 KNN 算法對直方圖向量做相似性判斷。
二、圖像源
三、基於Bag of features算法的圖像檢索
3.1讀取圖片,提取特征,建立字典
代碼
1 # -*- coding: utf-8 -*- 2 import pickle 3 from PCV.imagesearch import vocabulary 4 from PCV.tools.imtools import get_imlist 5 from PCV.localdescriptors import sift 6 7 #獲取圖像列表 8 imlist = get_imlist('D:/new/feng/') 9 nbr_images = len(imlist) 10 #獲取特征列表 11 featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)] 12 13 #提取文件夾下圖像的sift特征 14 for i in range(nbr_images): 15 sift.process_image(imlist[i], featlist[i]) 16 17 #生成詞匯 18 voc = vocabulary.Vocabulary('ukbenchtest') 19 voc.train(featlist, 100, 10) 20 #保存詞匯 21 # saving vocabulary 22 with open('D:/new/feng//vocabulary.pkl', 'wb') as f: 23 pickle.dump(voc, f) 24 print ('vocabulary is:', voc.name, voc.nbr_words)
3.1.2結果截圖
sift文件:
PKL文件:
3.2遍歷圖像,然后將向量特征投影到字典里並提交給數據庫
代碼
1 import pickle 2 from PCV.imagesearch import imagesearch 3 from PCV.localdescriptors import sift 4 from sqlite3 import dbapi2 as sqlite 5 from PCV.tools.imtools import get_imlist 6 7 #獲取圖像列表 8 imlist = get_imlist('D:/new/feng/') 9 nbr_images = len(imlist) 10 #獲取特征列表 11 featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)] 12 13 #載入詞匯 14 with open('D:/new/feng//vocabulary.pkl', 'rb') as f: 15 voc = pickle.load(f) 16 #創建索引 17 indx = imagesearch.Indexer('testImaAdd.db',voc) 18 indx.create_tables() 19 20 #遍歷所有的圖像,並將它們的特征投影到詞匯上 21 for i in range(nbr_images)[:1000]: 22 locs,descr = sift.read_features_from_file(featlist[i]) 23 indx.add_to_index(imlist[i],descr) 24 25 #提交到數據庫 26 indx.db_commit() 27 con = sqlite.connect('testImaAdd.db') 28 print(con.execute('select count (filename) from imlist').fetchone()) 29 print(con.execute('select * from imlist').fetchone())
實驗結果截圖:
數據庫
4、進行查詢測試
代碼
1 # -*- coding: utf-8 -*- 2 import pickle 3 from PCV.localdescriptors import sift 4 from PCV.imagesearch import imagesearch 5 from PCV.geometry import homography 6 from PCV.tools.imtools import get_imlist 7 8 # 載入圖像列表 9 imlist = get_imlist('D:/new/feng/') 10 nbr_images = len(imlist) 11 # 載入特征列表 12 featlist = [imlist[i][:-3] + 'sift' for i in range(nbr_images)] 13 14 # 載入詞匯 15 with open('D:/new/feng/vocabulary.pkl', 'rb') as f: 16 voc = pickle.load(f) 17 18 src = imagesearch.Searcher('testImaAdd.db', voc) 19 20 # 查詢圖像索引和查詢返回的圖像數 21 q_ind = 5 22 nbr_results = 20 23 24 # 常規查詢(按歐式距離對結果排序) 25 res_reg = [w[1] for w in src.query(imlist[q_ind])[:nbr_results]] 26 print('top matches (regular):', res_reg) 27 28 # 載入查詢圖像特征 29 q_locs, q_descr = sift.read_features_from_file(featlist[q_ind]) 30 fp = homography.make_homog(q_locs[:, :2].T) 31 32 # 用單應性進行擬合建立RANSAC模型 33 model = homography.RansacModel() 34 rank = {} 35 36 # 載入候選圖像的特征 37 for ndx in res_reg[1:]: 38 locs, descr = sift.read_features_from_file(featlist[ndx])
結果截圖:
四、實驗總結
sift特征提取具有旋轉不變性和尺寸不變性,還有數據源的像素不能過大,否則運行速度會很慢,
五、遇到的問題以及解決方法
我用了這個代碼 ,還是會報錯
pip install pysqlite
然后我復制了報錯的最后一樣在cmd中運行
再次輸入上面的代碼,依然出錯,后面我發現我少加了一個3
加了3之后,還要再imagesearch.py中加入
from numpy import * import pickle import sqlite3 from functools import cmp_to_key import operator class Indexer(object): def __init__(self,db,voc): """ Initialize with the name of the database and a vocabulary object. """ self.con = sqlite3.connect(db) self.voc = voc def __del__(self): self.con.close() def db_commit(self): self.con.commit() def get_id(self,imname): """ Get an entry id and add if not present. """ 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.lastrowid else: return res[0] def is_indexed(self,imname): """ Returns True if imname has been indexed. """ im = self.con.execute("select rowid from imlist where filename='%s'" % imname).fetchone() return im != None def add_to_index(self,imname,descr): """ Take an image with feature descriptors, project on vocabulary and add to database. """ if self.is_indexed(imname): return print ('indexing', imname) # get the imid imid = self.get_id(imname) # get the words imwords = self.voc.project(descr) nbr_words = imwords.shape[0] # link each word to image for i in range(nbr_words): word = imwords[i] # wordid is the word number itself self.con.execute("insert into imwords(imid,wordid,vocname) values (?,?,?)", (imid,word,self.voc.name)) # store word histogram for image # use pickle to encode NumPy arrays as strings self.con.execute("insert into imhistograms(imid,histogram,vocname) values (?,?,?)", (imid,pickle.dumps(imwords),self.voc.name)) def create_tables(self): """ Create the database tables. """ 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()
第二個報錯是
我看了一個學姐的是加入一些代碼,但是仍然報同樣的錯誤,這個問題還沒有解決,所以沒有截圖,實驗總結是分析不出來