先來寫付費專欄的第一個項目吧。
在說這個題目之前,先說一下這個項目的總體思路,如下所示。
我們的目的是遇到問題,解決問題。
- 那麼首先我們看一下我們的問題是什麼吧?()
利用Gabor象限特徵實現掌紋識別,從網上找到Gabor變換代碼,進行象限特徵提取和掌紋匹配(分別計算同一個掌紋和不同掌紋的相似度)
-
拿到這個問題,我們首先抓住文章的關鍵詞,
我找到的關鍵詞如下:()
-
接下來呢,我們理清一下思路:()
題目的要求就是1.進行特徵提取,2.將提取的特徵進行匹配,查看相似度
-
然後呢,我們就要藉助搜索引擎了,現在的所有引擎就是基於
關鍵詞搜索
,我們可以提煉一下關鍵詞,比如 ,關鍵詞之間要加空格。第一個關鍵詞Gabor象限特徵
是要查找的代碼類型,第二個關鍵詞Python
是說明要用什麼代碼實現,具體操作如下圖所示。
-
除了標題之外,查看文章摘要,來了解文章是否是自己需要的。
-
然後我們就點一下符合我們要求的文章,詳細查閱。這裏我們先點開第一個文章看一下。通過題目感覺到跟我們的題目要求比較吻合。我們再往下細看。
-
他首先說了一下他的運行環境,如下圖
而我的運行環境是Ubuntu18.04TLS,默認Python版本是3.74,沒關係,我們可以在Terminal
中創建一個虛擬環境,命令格式conda create -n xxx python=3.6
,xxx爲環境名。具體操作如下圖。因爲我們看到的博客上面說的需要的python2的環境,所以我的創建命令行語句是conda create -n gabor python==2.7.4
,效果如下圖所示。()
出現如下字樣,說明配置環境成功
-
進一步的,我們需要進入環境,命令爲
conda activate xxx
,xxx爲環境名稱,這裏我們是剛纔創建的gabor
可以看到綠色部分表示環境已經從base
變成gabor
了。紅色部分則是激活環境的實際代碼。
接下來繼續配置環境,OpenCV版本爲2.4.7,在gabor
環境下輸入命令行爲pip install opencv-python
然後我們就開始書寫我們的代碼
第一步引入庫函數
import cv2 #導入opencv函數庫
import numpy as np #引入提供維度數據與矩陣運算的,支持數組運算的數學函數庫numpy
import pylab as pl #引入pylab,即可以畫圖又可以計算,可以交互使用
- 在Ubuntu下在指定的虛擬環境中用Pycharm創建一個py文件,如果不會在在虛擬環境中創建文件,請參考鏈接,例如
gabor.py
,在文件中添加函數庫引入。如下圖所示。
編譯器沒有報錯,說明導入函數庫成功。 - 構建Gabor濾波器
import cv2
import numpy as np
import pylab as pl
def build_filters():
filters = []
ksize = [7,9,11,13,15,17] #gabor尺度,6個
lamda = np.pi/2.0 #波長
for theta in np.arange(0,np.pi,np.pi / 4): #gabor方向,0 45,90,135共四個
for K in range(6):
kern = cv2.getGaborKernel((ksize[K],ksize[K]),1.0,theta,lamda,0.5,0,ktype=cv2.CV_32F)
kern /= 1.5*kern.sum()
filters.append(kern)
return filters
11. 創建濾波過程
def process(img,filters):
accum = np.zeros_like(img)
for kern in filters:
fimg = cv2.filter2D(img,cv2.CV_8UC3,kern)
np.maximum(accum,fimg,accum)
return accum
12. 特徵圖提取並顯示
#Gabor特徵提取
def getGabor(img,filters):
res = [] #濾波結果
for i in range(len(filters)):
res1 = process(img,filters[i])
res.append(np.asarray(res1))
pl.figure(2)
for temp in range(len(res)):
pl.subplot(4,6,temp+1)
pl.imshow(res[temp],cmap='gray')
pl.show()
return res
- 然後再加入我寫的圖片讀入函數,就可以獲得圖片效果了。
if __name__ == '__main__':
path = "/home/philtell/Downloads/bmp600" # 待讀取的文件夾
path_list = os.listdir(path)
path_list.sort() # 對讀取的路徑進行排序
filters = build_filters()
for filename in path_list[-1:]:
print(filename)
img_path = os.path.join(path, filename)
image = cv2.imread(img_path)
getGabor(image, filters)
原圖如下:
效果圖如下:
再找一張原圖:
特徵效果如下圖
下來就來對提取的特徵進行匹配,
- 先對提取的特徵進行標準化,我們寫一下標準化函數,主要是每一個元素除以最大的元素
#數據歸一化
def normalization(data):
return data / np.max(abs(data))
- 計算特徵之間的相似度,也就是漢明距離
def getSimilarityDistance(feature1,feature2):
diff = 0
x1 = np.array(feature1).flatten() #將特徵抹平,多維矩陣變成一維數組,逐個對比,計算相似度
x2 = np.array(feature2).flatten()
for bit1,bit2 in zip(x1,x2):
if bit1 != bit2:
diff += 1
print(diff)
similarity = 1 - diff/len(x1)
print('相似度',similarity)
diff = 0
print(len(x1))
for bit1,bit2 in zip(x1,x1):
if bit1 != bit2:
diff += 1
print(diff)
similarity = 1 - diff/len(x1)
print(diff)
similarity = 1 - diff/len(x1)
print('相似度',similarity)
- 主函數爲:
if __name__ == '__main__':
path = "/home/philtell/Downloads/bmp600" # 待讀取的文件夾
filters = build_filters() #構建濾波器
img_path = os.path.join(path, '061_5.bmp') #獲得圖片地址
img_path2 = os.path.join(path, '062_5.bmp')
image = cv2.imread(img_path) #將圖片轉化爲多維數組
image2 = cv2.imread(img_path2)
result = getGabor(image, filters)
result2 = getGabor(image2, filters)
features = normalization(np.array(result)) #歸一化圖片特徵
features2 = normalization(np.array(result2))
getSimilarityDistance(features,features2) #計算不同圖片和相同圖片之間相似度
效果如下:
不同圖片相似度爲 0.60,相同圖片相似度爲1.0
最後將全部代碼上傳:
import cv2
import numpy as np
import pylab as pl
import os
def build_filters():
filters = []
ksize = [7,9,11,13,15,17] #gabor尺度,6個
lamda = np.pi/2.0 #波長
for theta in np.arange(0,np.pi,np.pi / 4): #gabor方向,0 45,90,135共四個
for K in range(6):
kern = cv2.getGaborKernel((ksize[K],ksize[K]),1.0,theta,lamda,0.5,0,ktype=cv2.CV_32F)
kern /= 1.5*kern.sum()
filters.append(kern)
print("np.arange(0,np.pi,np.pi / 4)",np.arange(0,np.pi,np.pi / 4))
print("np.pi",np.pi)
print("len",len(filters))
return filters
def process(img,filters):
accum = np.zeros_like(img)
for kern in filters:
fimg = cv2.filter2D(img,cv2.CV_8UC3,kern)
np.maximum(accum,fimg,accum)
return accum
#Gabor特徵提取
def getGabor(img,filters):
print('len(filters)',len(filters))
res = [] #濾波結果
for i in range(len(filters)):
res1 = process(img,filters[i])
res.append(np.asarray(res1))
pl.figure(2)
for temp in range(len(res)):
pl.subplot(4,6,temp+1)
pl.imshow(res[temp],cmap='gray')
pl.show()
return res
#數據歸一化
def normalization(data):
return data / np.max(abs(data))
def getSimilarityDistance(feature1,feature2):
diff = 0
x1 = np.array(feature1).flatten() #將特徵抹平,多維矩陣變成一維數組,逐個對比,計算相似度
x2 = np.array(feature2).flatten()
for bit1,bit2 in zip(x1,x2):
if bit1 != bit2:
diff += 1
print(diff)
similarity = 1 - diff/len(x1)
print('相似度',similarity)
diff = 0
print(len(x1))
for bit1,bit2 in zip(x1,x1):
if bit1 != bit2:
diff += 1
print(diff)
similarity = 1 - diff/len(x1)
print(diff)
similarity = 1 - diff/len(x1)
print('相似度',similarity)
if __name__ == '__main__':
path = "/home/philtell/Downloads/bmp600" # 待讀取的文件夾
path_list = os.listdir(path)
path_list.sort() # 對讀取的路徑進行排序
filters = build_filters()
img_path = os.path.join(path, '061_5.bmp')
img_path2 = os.path.join(path, '062_5.bmp')
image = cv2.imread(img_path)
image2 = cv2.imread(img_path2)
print('image',type(image))
result = getGabor(image, filters)
result2 = getGabor(image2, filters)
features = normalization(np.array(result))
features2 = normalization(np.array(result2))
getSimilarityDistance(features,features2)
如果你能看到我這句話,那麼說明你是訂閱了專欄,感謝你的訂閱~