天天看點

OpenCV—python Gabor濾波(提取圖像紋理)

文章目錄

  • ​​一、Gabor濾波簡介​​
  • ​​二、代碼示範​​

Gabor是一個用于邊緣提取的線性濾波器,其頻率和方向表達與人類視覺系統類似,能夠提供良好的方向選擇和尺度選擇特性,而且對于光照變化不敏感,是以十分适合紋理分析。在人臉識别等領域有着很廣泛的應用

一、Gabor濾波簡介

Gabor是一個用于邊緣提取的線性濾波器,其頻率和方向表達與人類視覺系統類似,能夠提供良好的方向選擇和尺度選擇特性,而且對于光照變化不敏感,是以十分适合紋理分析。

Gabor濾波器和脊椎動物視覺皮層感受野響應的比較:第一行代表脊椎動物的視覺皮層感受野,第二行是Gabor濾波器,第三行是兩者的殘差。可見兩者相差極小。Gabor濾波器的這一性質,使得其在視覺領域中經常被用來作圖像的預處理。

OpenCV—python Gabor濾波(提取圖像紋理)

Gabor濾波的公式如下所示:

其中實數部分與虛數部分為:

其中

這裡面的參數:

(1) 分别表示像素坐标位置;

(2) 表示濾波的波長;(波長越大,黑白相間的間隔越大)

(3) 表示Gabor核函數圖像的傾斜角度;

(4) 表示相位偏移量,範圍是-180~180;(=0時白條為中心,=180時,黑條為中心 )

(5) 表示高斯函數的标準差;(增大,條紋數量越多)

(6) 表示長寬比,決定這Gabor核函數圖像的橢圓率。(越小,核函數圖像會越高)

這裡的參數不了解不要緊,後面我将會針對這些參數進行一系列的實驗,直覺的展示出這些參數的作用

參數 實體意義 描述
像素坐标位置
波長 直接影響濾波器的濾波尺度,通常大于等于2
方向 Gabor核函數圖像的傾斜角度
相位偏移 調諧函數的相位偏移,取值 -180 ~ 180
空間縱橫比(長寬比) 決定濾波器的形狀橢圓率,取1時為圓形,通常取 0.5
帶寬 高斯濾波器的方差,通常取

二、代碼示範

import cv2,os
import numpy as np
import matplotlib.pyplot as plt


def get_img(input_Path):
    img_paths = []
    for (path, dirs, files) in os.walk(input_Path):
        for filename in files:
            if filename.endswith(('.jpg','.png')):
                img_paths.append(path+'/'+filename)
    return img_paths


#建構Gabor濾波器
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)
     plt.figure(1)

     #用于繪制濾波器
     for temp in range(len(filters)):
         plt.subplot(4, 6, temp + 1)
         plt.imshow(filters[temp])
     plt.show()
     return filters

#Gabor特征提取
def getGabor(img,filters):
    res = [] #濾波結果
    for i in range(len(filters)):
        # res1 = process(img, filters[i])
        accum = np.zeros_like(img)
        for kern in filters[i]:
            fimg = cv2.filter2D(img, cv2.CV_8UC1, kern)
            accum = np.maximum(accum, fimg, accum)
        res.append(np.asarray(accum))

    #用于繪制濾波效果
    plt.figure(2)
    for temp in range(len(res)):
        plt.subplot(4,6,temp+1)
        plt.imshow(res[temp], cmap='gray' )
    plt.show()
    return res  #傳回濾波結果,結果為24幅圖,按照gabor角度排列


if __name__ == '__main__':
    input_Path = './content'
    filters = build_filters()
    img_paths = get_img(input_Path)
    for img in img_paths:
        img = cv2.imread(img)
        getGabor(img, filters)



這個過程有點慢,一張圖檔要1-3s,若是批量處理可以開啟多線程,這樣會快點      
OpenCV—python Gabor濾波(提取圖像紋理)
#coding:utf-8

'''
Gabor濾波器參數可視化
參考:https://blog.csdn.net/lhanchao/article/details/55006663
'''

import cv2
import numpy as np
import math

# λ(波長)變化
kernel1 = cv2.getGaborKernel((200,200),10,0,5,0.5,0)
kernel2 = cv2.getGaborKernel((200,200),10,0,10,0.5,0)
kernel3 = cv2.getGaborKernel((200,200),10,0,15,0.5,0)
kernel4 = cv2.getGaborKernel((200,200),10,0,20,0.5,0)

cv2.imshow("lambda: 5", kernel1)
cv2.imshow("lambda: 10", kernel2)
cv2.imshow("lambda: 15", kernel3)
cv2.imshow("lambda: 20", kernel4)

# θ變化
kernel1 = cv2.getGaborKernel((311, 311), 10, 0, 10, 0.5, 0)
kernel2 = cv2.getGaborKernel((311, 311), 10, math.pi * 0.25, 10, 0.5)
kernel3 = cv2.getGaborKernel((311, 311), 10, math.pi * 0.5, 10, 0.5, 0)
kernel4 = cv2.getGaborKernel((311, 311), 10, math.pi * 0.75, 10, 0.5, 0)

cv2.imshow("theta: 0", kernel1)
cv2.imshow("theta: 45", kernel2)
cv2.imshow("theta: 90", kernel3)
cv2.imshow("theta: 135", kernel4)

# ψ的變化

# σ的變化:
kernel1 = cv2.getGaborKernel((311, 311), 5, 0, 10, 0.5, 0)
kernel2 = cv2.getGaborKernel((311, 311), 10, 0, 10, 0.5, 0)
kernel3 = cv2.getGaborKernel((311, 311), 15, 0, 10, 0.5, 0)
kernel4 = cv2.getGaborKernel((311, 311), 20, 0, 10, 0.5, 0)

cv2.imshow("sigma: 5", kernel1)
cv2.imshow("sigma: 10", kernel2)
cv2.imshow("sigma: 15", kernel3)
cv2.imshow("sigma: 20", kernel4)

# γ的變化

kernel1 = cv2.getGaborKernel((200, 200), 10, 0, 10, 0.5, 0)
kernel2 = cv2.getGaborKernel((200, 200), 10, 0, 10, 1.0, 0)
kernel3 = cv2.getGaborKernel((200, 200), 10, 0, 10, 1.5, 0)
kernel4 = cv2.getGaborKernel((200, 200), 10, 0, 10, 2.0, 0)
cv2.imshow("gamma: 0.5", kernel1)
cv2.imshow("gamma: 1.0", kernel2)
cv2.imshow("gamma: 1.5", kernel3)
cv2.imshow("gamma: 2.0", kernel4)

cv2.waitKey()
cv2.destroyAllWindows()      

繼續閱讀