程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python計算機視覺——圖像檢索與識別

編輯:Python

目錄

一、原理解析

1.1計算機視覺的圖像分類是什麼意思?

1.2圖像分類如何實現?

1.3Bag of features算法和過程

1)提取圖像特征

2)訓練字典

3)圖像直方圖生成

4)訓練分類器

1.4TF-IDF

二、實驗過程

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權值。

圖像分類問題是計算機視覺領域的基礎問題,它的目的是根據圖像的語義信息將不同類別圖像區分開來,實現最小的分類誤差。具體任務要求是從給定的分類集合中給圖像分配一個標簽的任務。總體來說,對於單標簽的圖像分類問題,它可以分為跨物種語義級別的圖像分類,子類細粒度圖像分類,以及實例級圖像分類三大類別。因為VOC數據集是不同物種類別的數據集,所以本文主要研究討論跨物種語義級別的圖像分類任務。
通常圖像分類任務存在以下技術難點:
(1)視角變化:同一個物體,攝像機可以從多個角度來展現。
(2)大小變化:物體可視的大小通常是會變化的。
(3)形變:很多東西的形狀並非一成不變,會有很大變化。 (4)遮擋:目標物體可能被擋住。有時候只有物體的一小部分是可見的。
(5)光照條件:在像素層面上,光照的影響非常大。
(6)背景干擾:物體可能混入背景之中,使之難以被辨認。
(7)類內差異:一類物體的個體之間的外形差異很大,比如椅子。這一類物體有許多不同的對象,每個都有自己的外形


 

1.3Bag of features算法和過程

1)提取圖像特征

特征提取及描述主要是將一些 具有代表性且 區分性較強的 全局或局部特征從圖像中進行抽取,並對這些特征進行描述。
這些特征一般是類別之間差距比較 明顯的特征,可以將其與其他類別區分開,其次,這些特征還要求具有 較好的穩定性,能夠最大限度的在光照、視角、尺度、噪聲以及各種外在因素變化的情況下保持穩定,不受其影響。這樣即使在非常復雜的情況下,計算機也能通過這些穩定的特征很好的檢測與識別出這個物體。
特征提取最簡單且有效的方法就是 規則網格方法,
該方法采用均勻網格對圖像進行劃分,從而得到圖像的局部區域特征。
興趣點檢測方法是另一個有效的特征提取方法,興趣點檢測的基本思想是:
在人為判斷一幅圖像的類別時,首先捕捉到物體的整體輪廓特征,然後聚焦於物體與其他物體具有顯著特征區別的地方,最後判斷出圖像的類別。即通過該物體與其他物體 區別開的 顯著特征,進而判斷圖像的類別。
在提取完圖像的特征後,下一步就要應用特征描述子來對抽取的圖像特征進行描述,特征描述子所表示的特征向量一般在處理算法時會作為輸入數據,因此,如果描述子具有一定的判別性及可區分性,則該描述子會在後期的圖像處理過程中起著很大的作用。
其中,SIFT描述子是近年比較經典且被廣泛應用的一種描述子。
SIFT會從圖片上提取出很多特征點,每個特征點都是128維的向量,因此,如果圖片足夠多的話,我們會提取出一個巨大的特征向量庫。


 

 

2)訓練字典

在上面提取完SIFT特征的步驟後,利用K-means聚類算法將提取的SIFT特征聚類生成視覺詞典。
K-means算法是度量樣本間相似性的一種方法,該算法設置參數為K,把N個對象分成K個簇,簇內之間的相似度較高,而簇間的相似度較低。聚類中心有K個,視覺詞典為K。構建視覺單詞的過程如圖所示。

 

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用以評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度。字詞的重要性隨著它在文件中出現的次數成正比增加,但同時會隨著它在語料庫中出現的頻率成反比下降。就目前來說,如果一個 關鍵詞只在很少的網頁中出現,我們通過它就 容易鎖定搜索目標,它的 權重也就應該 大。反之如果一個詞在大量網頁中出現,我們看到它仍然 不是很清楚要找什麼內容,因此它應該 小。
 

二、實驗過程

2.1代碼分析

生成詞匯表:

# -*- 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('test/')
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, 122, 10)
# 保存詞匯
# saving vocabulary
'''with open('D:/Program Files (x86)/QQdate/BagOfFeature/BagOfFeature/BOW/vocabulary.pkl', 'wb') as f:
pickle.dump(voc, f)'''
with open('C:/Users/86158/Desktop/計算機視覺實驗/Bag Of Feature/BOW/vocabulary.pkl', 'wb') as f:
pickle.dump(voc, f)
print('vocabulary is:', voc.name, voc.nbr_words)

生成數據庫:

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('test/')
nbr_images = len(imlist)
#獲取特征列表
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]
# load vocabulary
#載入詞匯
with open('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)[:888]:
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())

圖像搜索:

# -*- coding: utf-8 -*-
#使用視覺單詞表示圖像時不包含圖像特征的位置信息
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
#載入圖像列表
imlist = get_imlist('test/')
nbr_images = len(imlist)
#載入特征列表
featlist = [imlist[i][:-3]+'sift' for i in range(nbr_images)]
#載入詞匯
'''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)
src = imagesearch.Searcher('testImaAdd.db',voc)# Searcher類讀入圖像的單詞直方圖執行查詢
# index of query image and number of results to return
#查詢圖像索引和查詢返回的圖像數
q_ind = 0
nbr_results = 130
# 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:]:
try:
locs,descr = sift.read_features_from_file(featlist[ndx])
except:
continue
#locs,descr = sift.read_features_from_file(featlist[ndx]) # because 'ndx' is a rowid of the DB that starts at 1
# 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 count
rank[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[:6]) #常規查詢
imagesearch.plot_results(src,res_geom[:6]) #重排後的結果

2.2實驗過程

數據集:

測試集:

 

 

2.3實驗結果

 

 

 


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved