gabor濾波器


https://blog.csdn.net/u013709270/article/details/49642397

https://github.com/xuewenyuan/Gabor_Visualization

https://blog.csdn.net/u013709270/article/details/49642397

第三種

使用的第三種gabor模型:

 

 

 

代碼opencv實現

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <math.h>

cv::Mat mkKernel(int ks, double sig, double th, double lm, double ps)
{
int hks = (ks-1)/2;
double theta = th*CV_PI/180;
double psi = ps*CV_PI/180;
double del = 2.0/(ks-1);
double lmbd = lm;
double sigma = sig/ks;
double x_theta;
double y_theta;
cv::Mat kernel(ks,ks, CV_32F);
for (int y=-hks; y<=hks; y++)
{
for (int x=-hks; x<=hks; x++)
{
x_theta = x*del*cos(theta)+y*del*sin(theta);
y_theta = -x*del*sin(theta)+y*del*cos(theta);
kernel.at<float>(hks+y,hks+x) = (float)exp(-0.5*(pow(x_theta,2)+pow(y_theta,2))/pow(sigma,2))* cos(2*CV_PI*x_theta/lmbd + psi);
}
}
return kernel;
}

int kernel_size=21;
int pos_sigma= 5;
int pos_lm = 50;
int pos_th = 0;
int pos_psi = 90;
cv::Mat src_f;
cv::Mat dest;

void Process(int , void *)
{
double sig = pos_sigma;
double lm = 0.5+pos_lm/100.0;
double th = pos_th;
double ps = pos_psi;
cv::Mat kernel = mkKernel(kernel_size, sig, th, lm, ps);
cv::imshow("kernel window", kernel);
cv::filter2D(src_f, dest, CV_32F, kernel);
cv::imshow("Process window", dest);
cv::Mat Lkernel(kernel_size*20, kernel_size*20, CV_32F);
cv::resize(kernel, Lkernel, Lkernel.size());
Lkernel /= 2.;
Lkernel += 0.5;
cv::imshow("Kernel", Lkernel);
cv::Mat mag;
cv::pow(dest, 2.0, mag);
cv::imshow("Mag", mag);
}

int main(int argc, char** argv)
{
cv::Mat image = cv::imread("1.jpg",1);
cv::imshow("Src", image);
cv::Mat src;
cv::cvtColor(image, src, CV_BGR2GRAY);
src.convertTo(src_f, CV_32F, 1.0/255, 0);
if (!kernel_size%2)
{
kernel_size+=1;
}
cv::namedWindow("Process window", 1);
cv::createTrackbar("Sigma", "Process window", &pos_sigma, kernel_size, Process);
cv::createTrackbar("Lambda", "Process window", &pos_lm, 100, Process);
cv::createTrackbar("Theta", "Process window", &pos_th, 180, Process);
cv::createTrackbar("Psi", "Process window", &pos_psi, 360, Process);
Process(0,0);
cv::waitKey(0);
return 0;
}

第四種 :最完整的變化:代碼在下面

二、Gabor函數

Gabor變換屬於加窗傅立葉變換,Gabor函數可以在頻域不同尺度、不同方向上提取相關的特征。另外Gabor函數與人眼的生物作用相仿,所以經常用作紋理識別上,並取得了較好的效果。二維Gabor函數可以表示為:

其中:

v的取值決定了Gabor濾波的波長,u的取值表示Gabor核函數的方向,K表示總的方向數。參數決定了高斯窗口的大小,這里取。程序中取4個頻率(v=0, 1, ..., 3),8個方向(即K=8,u=0, 1, ... ,7),共32個Gabor核函數。不同頻率不同方向的Gabor函數可通過下圖表示:

圖片來源:GaborFilter.html

圖片來源:http://www.bmva.ac.uk/bmvc/1997/papers/033/node2.html

三、代碼實現

Gabor函數是復值函數,因此在運算過程中要分別計算其實部和虛部。代碼如下:

private void CalculateKernel(int Orientation, int Frequency)
{
   double real, img;
   for(int x = -(GaborWidth-1)/2; x<(GaborWidth-1)/2+1; x++)
      for(int y = -(GaborHeight-1)/2; y<(GaborHeight-1)/2+1; y++)
      {
         real = KernelRealPart(x, y, Orientation, Frequency);
         img = KernelImgPart(x, y, Orientation, Frequency);
         KernelFFT2[(x+(GaborWidth-1)/2) + 256 * (y+(GaborHeight-1)/2)].Re = real;
         KernelFFT2[(x+(GaborWidth-1)/2) + 256 * (y+(GaborHeight-1)/2)].Im = img;
      }
}
private double KernelRealPart(int x, int y, int Orientation, int Frequency)
{
   double U, V;
   double Sigma, Kv, Qu;
   double tmp1, tmp2;
   U = Orientation;
   V = Frequency;
   Sigma = 2 * Math.PI * Math.PI;
   Kv = Math.PI * Math.Exp((-(V+2)/2)*Math.Log(2, Math.E));
   Qu = U * Math.PI  / 8;
   tmp1 = Math.Exp(-(Kv * Kv * ( x*x + y*y)/(2 * Sigma)));
   tmp2 = Math.Cos(Kv * Math.Cos(Qu) * x + Kv * Math.Sin(Qu) * y) - Math.Exp(-(Sigma/2));
   return tmp1 * tmp2 * Kv * Kv / Sigma;   
}
private double KernelImgPart(int x, int y, int Orientation, int Frequency)
{
   double U, V;
   double Sigma, Kv, Qu;
   double tmp1, tmp2;
   U = Orientation;
   V = Frequency;
   Sigma = 2 * Math.PI * Math.PI;
   Kv = Math.PI * Math.Exp((-(V+2)/2)*Math.Log(2, Math.E));
   Qu = U * Math.PI  / 8;
   tmp1 = Math.Exp(-(Kv * Kv * ( x*x + y*y)/(2 * Sigma)));
   tmp2 = Math.Sin(Kv * Math.Cos(Qu) * x + Kv * Math.Sin(Qu) * y) - Math.Exp(-(Sigma/2));
   return tmp1 * tmp2 * Kv * Kv / Sigma;   
}

有了Gabor核函數后就可以采用前文中提到的“離散二維疊加和卷積”或“快速傅立葉變換卷積”的方法求解Gabor變換,並對變換結果求均值和方差作為提取的特征。32個Gabor核函數對應32次變換可以提取64個特征(包括均值和方差)。由於整個變換過程代碼比較復雜,這里僅提供測試代碼供下載。該代碼僅計算了一個101×101尺寸的Gabor函數變換,得到均值和方差。代碼采用兩種卷積計算方式,從結果中可以看出,快速傅立葉變換卷積的效率是離散二維疊加和卷積的近50倍。

代碼下載請點 >>>>  這里 。注意,代碼中沒有包含Exocortex.DSP,請測試者到相應網站上下載並包含在自己的項目中。

解壓縮后,里面有一"GaborTest.png"文件,程序中默認路徑是“D:\”,請將此圖片放置到此路徑下。(程序代碼在Visual Studio .net 2003下調試通過)。

 

 

1.Introduction
下面開始介紹Gabor 濾波器以及相關的知識,首先上wiki上關於Gabor filter的介紹:In image processing, a Gabor filter, named after Dennis Gabor, is a linear filter used for edge detection. Frequency and orientation representations of Gabor filters are similar to those of the human visual system, and they have been found to be particularly appropriate for texture representation and discrimination. In the spatial domain, a 2D Gabor filter is a Gaussian kernel function modulated by a sinusoidal plane wave.說白了就是說這個濾波器與視覺通路信息處理結構很相似,從信號處理的角度上是一個正弦波平面波調制的高斯函數,公式和圖如下:

-------------------------------------------- 1

 

Real part:

-------------------------------------------------------- 2

Imaginary part:

--------------------------------------------------------- 3


  解釋一下參數:\lamda 是波長,不同波長的效果如下:

 

,\theta 是角度,如果想得到不同方向上的濾波器的話,就需要做旋轉,我們知道這個可以通過乘上一個旋轉矩陣得到:

 

                    -------------------------------------------------------------------- 4

下面展示的就是不同角度的Gabor filter:


上面兩個是最關鍵的參數,我們常說Gabor filter可以得到多尺度多方向的響應,其實就是這兩個參數在起作用。其他參數\phi指的是phase offset, \gamma 指的是aspect ratio,也就是x方向和y方向的比例,具體各個參數的效果參考:http://matlabserver.cs.rug.nl/edgedetectionweb/web/edgedetection_params.html

而二維Gabor在三維下顯示的樣子就是:

 

如果沒有正弦調制,二維高斯就是平滑的一個凸起,現在因為有了正弦波調制,就有了這種溝壑。而不要小看了這個溝壑,從圖像處理的角度來講:傅立葉變換在很大程度上只是一個體現大局觀的概念,而無法反映圖像局部的特點,,因此我們無法通過傅立葉變換來對圖像進行細節上更准確的操作。幸運的是,人們之后的研究中,發現了Gabor於1946年發表的論文《the Theory of Communication》,於是在識別的方法上,尤其在紋理識別上達到了一個新的高度。當然小波變換的應用也是差不多這個時間段開始的,由此我們也可以理解數學在圖像領域的價值[1].

===========================================理論==========================================

下面我再從公式開始重新展示一下Gabor filter,目的就是為了解釋為什么會出現我一開始說的多種版本的Gabor filter。其實,我也正是因為搞不懂這個,才重新研究Gabor filter。

Part 1;高斯正弦平面波
我們已經說過Gabor filter是用正弦平面波調制高斯,先說正弦平面波,也就是是二維的正弦波,公式表達為:-------  5,

我們可視化之后樣子如下:

 

當然,最標准的complex sinusoid 函數形式是:------------------------------------- 6,

 

兩者的區別在於后者得到的曲面不是與x軸平行的而是旋轉了45度,考慮到可以對\theta采用旋轉得到一樣的效果,所以兩個形式的函數都是可以的,我們采用第二種形式(公式6)。

Part 2 高斯權重分布或者Gaussian envelope
二維高斯分布的標准形式為:

---------------------------------------------------------------- 7

如果令,那么上式就可以寫成:

-----------------------------------------------------------   8

其中K=1/ab, .

Part 3 Compelte Gabor filter form:
我們將公式8和公式6合並在一起,就得到了:

------------------------------------------------------ 9

我們再把公式1貼過來:

--------------------------- 10

比較兩個公式,我們發現兩者之間有些許的區別,我們找出之間的關聯:

  波長與頻率關系:.那么兩個公式不同的地方呢,開頭和結尾,公式9的開頭有系數,結尾還有指數常數項。

而這也是導致出現不同版本Gabor程序的原因所在。

Part4 多尺度和多方向
對於多尺度和多方向,就是要對公式9進行細化:

 

這樣,就可以得到一組多尺度多方向的濾波器組了:

 

=========================程序部分===========================================

程序部分主要涉及的就是參數問題,因為隨着Gabor的大規模應用,人們對參數進行了簡化或者采用一些默認值。

比如在鏈接:http://blog.csdn.net/watkinsong/article/details/7882443  中,第三,四種實現方式就對應着公式2,而我再這里想重點介紹第五種實現方式,首先先介紹一下

這種方式對應的Gabor filter的函數形式:

 

其中:

 

於是多尺度和多方向就可輕松搞定了。這個就是第五種實現方式的原理,個人感覺這種方式才是最正宗的方式。

 

 

Reference:
[1]http://blog.csdn.net/watkinsong/article/details/7859185
---------------------
作者:Kevein111
來源:CSDN
原文:https://blog.csdn.net/carrierlxksuper/article/details/47189713
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 


免責聲明!

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



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