python-圖像檢索


圖像檢索

一、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()

  第二個報錯是

 

我看了一個學姐的是加入一些代碼,但是仍然報同樣的錯誤,這個問題還沒有解決,所以沒有截圖,實驗總結是分析不出來

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM