編程小白的人工智能路之Gabor濾波提取掌紋特徵並對比掌紋相似度(一)

先來寫付費專欄的第一個項目吧。

在說這個題目之前,先說一下這個項目的總體思路,如下所示。
在這裏插入圖片描述

我們的目的是遇到問題,解決問題。

  1. 那麼首先我們看一下我們的問題是什麼吧?(\color{green}發現問題

利用Gabor象限特徵實現掌紋識別,從網上找到Gabor變換代碼,進行象限特徵提取和掌紋匹配(分別計算同一個掌紋和不同掌紋的相似度)

  1. 拿到這個問題,我們首先抓住文章的關鍵詞,
    我找到的關鍵詞如下:(\color{green}分析問題
    Gabor,,\color{red}{Gabor,象限特徵}\color{pink}{掌紋,識別}\color{blue}{象限特徵提取,掌紋匹配}

  2. 接下來呢,我們理清一下思路:(/\color{green}提取/總結問題
    題目的要求就是1.進行特徵提取,2.將提取的特徵進行匹配,查看相似度

  3. 然後呢,我們就要藉助搜索引擎了,現在的所有引擎就是基於關鍵詞搜索,我們可以提煉一下關鍵詞,比如Gabor\color{red}{Gabor象限特徵 } Python\color{red}{Python},關鍵詞之間要加空格。第一個關鍵詞Gabor象限特徵是要查找的代碼類型,第二個關鍵詞Python是說明要用什麼代碼實現,具體操作如下圖所示。
    在這裏插入圖片描述

  4. 除了標題之外,查看文章摘要,來了解文章是否是自己需要的。
    在這裏插入圖片描述

  5. 然後我們就點一下符合我們要求的文章,詳細查閱。這裏我們先點開第一個文章看一下。通過題目感覺到跟我們的題目要求比較吻合。我們再往下細看。
    在這裏插入圖片描述

  6. 他首先說了一下他的運行環境,如下圖
    在這裏插入圖片描述
    而我的運行環境是Ubuntu18.04TLS,默認Python版本是3.74,沒關係,我們可以在Terminal中創建一個虛擬環境,命令格式conda create -n xxx python=3.6,xxx爲環境名。具體操作如下圖。因爲我們看到的博客上面說的需要的python2的環境,所以我的創建命令行語句是conda create -n gabor python==2.7.4,效果如下圖所示。(python2python3python2python3\color{red}{可以不用指定的環境,比如python2你可以用python3代替,只需要把對應的python2代碼換成python3就可以})
    在這裏插入圖片描述
    出現如下字樣,說明配置環境成功
    在這裏插入圖片描述

  7. 進一步的,我們需要進入環境,命令爲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,即可以畫圖又可以計算,可以交互使用
  1. 在Ubuntu下在指定的虛擬環境中用Pycharm創建一個py文件,如果不會在在虛擬環境中創建文件,請參考鏈接,例如gabor.py,在文件中添加函數庫引入。如下圖所示。
    在這裏插入圖片描述
    編譯器沒有報錯,說明導入函數庫成功。
  2. 構建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
  1. 然後再加入我寫的圖片讀入函數,就可以獲得圖片效果了。
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)

原圖如下:
在這裏插入圖片描述
效果圖如下:
在這裏插入圖片描述

再找一張原圖:
在這裏插入圖片描述
特徵效果如下圖
在這裏插入圖片描述


下來就來對提取的特徵進行匹配,

  1. 先對提取的特徵進行標準化,我們寫一下標準化函數,主要是每一個元素除以最大的元素
#數據歸一化
def normalization(data):
    return data / np.max(abs(data))
  1. 計算特徵之間的相似度,也就是漢明距離
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)
  1. 主函數爲:
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)

如果你能看到我這句話,那麼說明你是訂閱了專欄,感謝你的訂閱~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章