看到一篇文章关于Gabor滤波器的文章,有感,遂记录一下。
一.Gabor 滤波器简介(部分资料来自维基百科)
在图像处理领域,Gabor滤波器是一个用于边缘检测的线性滤波器。Gabor滤波器的频率和方向表示接近人类视觉系统对于频率和方向的表示,并且它们常备用于纹理表示和描述。在空域,一个2维的Gabor滤波器是一个正弦平面波和高斯核函数的乘积。Gabor滤波器是自相似的,也就是说,所有Gabor滤波器都可以从一个母小波经过膨胀和旋转产生。实际应用中,Gabor滤波器可以在频域的不同尺度,不同方向上提取相关特征。
二.Gabor滤波器公式化定义
公式中:
λ:正弦函数波长;
θ:Gabor核函数的方向
ψ:相位偏移
σ:高斯函数的标准差
γ: 空间的宽高比(这个没太理解)
四.Gabor 滤波器opencv实现代码
1
CGaborFilter::CGaborFilter(
float dLambda,
float dTheta,
float dRatio_S2L,
float dGamma,
float dPhi)
2 {
3 Lambda = dLambda;
4 Theta = dTheta;
5 sigma = dLambda*dRatio_S2L;
6 Gamma = dGamma;
7 Phi = dPhi;
8 m_pGaborFilter = NULL;
9 bParam = 1;
10}
11
12
13 CGaborFilter::~CGaborFilter( void)
14 {
15 cvReleaseMat(&m_pGaborFilter);
16}
17
18 void CGaborFilter::Init()
19 {
20 float dtmp;
21 int itmp;
22 if(is_param() == 0)
23 {
24 printf("The parameters are not enough!");
25 }
26 else
27 {
28 dtmp = sqrt(48*pow(sigma,2)+1);
29 itmp = cvRound(dtmp);
30 if(itmp%2 == 0)
31 itmp ++;
32 GaborWindow.height = GaborWindow.width = 16;
33 bInit = 1;
34
35 create_kernel();
36 }
37}
38
39 void CGaborFilter::Init( float dSigma, float dTheta, float dPhi)
40 {
41 float dtmp;
42 int itmp;
43
44 sigma = dSigma;
45 Theta = dTheta;
46 Phi = dPhi;
47 Gamma = GAMMA;
48 Lambda = sigma/RATIO_S2L;
49 bParam = 1;
50
51 dtmp = sqrt(24*pow(sigma,2));
52 itmp = cvRound(dtmp);
53 if(itmp%2 == 0)
54 itmp ++;
55 GaborWindow.height = GaborWindow.width = itmp;
56 bInit = 1;
57
58 create_kernel();
59}
60
61 void CGaborFilter::Init( float dLambda, float dTheta, float dPhi, float dGamma)
62 {
63 float dtmp;
64 int itmp;
65
66 Lambda = dLambda;
67 Theta = dTheta;
68 Phi = dPhi;
69 Gamma = dGamma;
70 sigma = Lambda * RATIO_S2L;
71 bParam = 1;
72
73 dtmp = sqrt(24*pow(sigma,2));
74 itmp = cvRound(dtmp);
75 if(itmp%2 == 0)
76 itmp ++;
77 GaborWindow.height = GaborWindow.width = itmp;
78 bInit = 1;
79
80 create_kernel();
81}
82
83 void CGaborFilter::create_kernel()
84 {
85 float tmp1,tmp2,xtmp,ytmp,re;
86 int i,j,x,y;
87
88 if(is_init() == 0)
89 printf("The parameters haven't been initialed!");
90
91
92 else{
93
94
95 m_pGaborFilter = cvCreateMat(GaborWindow.height,GaborWindow.width,CV_32FC1);
96 for(i= 0; i< GaborWindow.height; i++)
97 for(j = 0; j< GaborWindow.width; j++)
98 {
99 x = j - GaborWindow.width/2;
100 y = i - GaborWindow.height/2;
101
102
103 xtmp = (float)x*cos(Theta) - (float)y*sin(Theta);
104 ytmp = (float)x*sin(Theta) + (float)y*cos(Theta);
105
106 tmp1 = exp(-(pow(xtmp,2)+pow(ytmp*Gamma,2))/(2*pow(sigma,2)));
107 tmp2 = cos(2*PI*xtmp/Lambda + Phi);
108 // int p=sizeof(float);
109 re = tmp1*tmp2;
110 cvSetReal2D((CvMat*)m_pGaborFilter,i,j,re);
111
112 }
113 bKernel = 1;
114 }
115}
116
117 IplImage * CGaborFilter::get_Image()
118 {
119 if(is_kernel() == 0)
120 {
121 printf("The filter hasn't bee created!");
122 }
123 else
124 {
125 IplImage *pImg = cvCreateImage(GaborWindow,IPL_DEPTH_32F,1);
126 IplImage *pImgU8 = cvCreateImage(GaborWindow,IPL_DEPTH_8U,1);
127 CvMat * pMat = cvCreateMat(GaborWindow.height,GaborWindow.width,CV_32FC1);
128
129 cvCopy(m_pGaborFilter,pImg);
130 //pImg->imageData = (char *)pMat->data;
131 cvNormalize((IplImage*)pImg, (IplImage*)pImg,0,255,CV_MINMAX,NULL);
132 cvConvertScaleAbs(pImg,pImgU8,1,0);
133 return pImgU8;
134 }
135}
136
137 IplImage * CGaborFilter::do_filter( const IplImage * src)
138 {
139 if(is_kernel()==false)
140 {
141 printf("The Gabor Kernel has not been created!");
142 }
143 else{
144
145 IplImage *pDestImage = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
146 // IplImage * pGaborImage = get_Imge();
147 // CvMat GaborKernel = cvMat(pGaborImage->height,pGaborImage->width,CV_8U,pGaborImage->imageData);
148 IplImage *tmpImg = cvCloneImage(src);
149 IplImage *tmpGrayImg = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
150
151 if(tmpImg->nChannels != 1)
152 {
153 cvCvtColor(tmpImg,tmpGrayImg,CV_BGR2GRAY);
154 }
155 else
156 {
157 cvReleaseImage(&tmpGrayImg);
158 tmpGrayImg = tmpImg;
159 }
160 CvMat * pGaborKernel = get_Mat();
161
162 cvFilter2D(tmpGrayImg,pDestImage,pGaborKernel,cvPoint((GaborWindow.width-1)/2,(GaborWindow.height-1)/2));
163
164 cvReleaseImage(&tmpImg);
165 return pDestImage;
166 }
167}
2 {
3 Lambda = dLambda;
4 Theta = dTheta;
5 sigma = dLambda*dRatio_S2L;
6 Gamma = dGamma;
7 Phi = dPhi;
8 m_pGaborFilter = NULL;
9 bParam = 1;
10}
11
12
13 CGaborFilter::~CGaborFilter( void)
14 {
15 cvReleaseMat(&m_pGaborFilter);
16}
17
18 void CGaborFilter::Init()
19 {
20 float dtmp;
21 int itmp;
22 if(is_param() == 0)
23 {
24 printf("The parameters are not enough!");
25 }
26 else
27 {
28 dtmp = sqrt(48*pow(sigma,2)+1);
29 itmp = cvRound(dtmp);
30 if(itmp%2 == 0)
31 itmp ++;
32 GaborWindow.height = GaborWindow.width = 16;
33 bInit = 1;
34
35 create_kernel();
36 }
37}
38
39 void CGaborFilter::Init( float dSigma, float dTheta, float dPhi)
40 {
41 float dtmp;
42 int itmp;
43
44 sigma = dSigma;
45 Theta = dTheta;
46 Phi = dPhi;
47 Gamma = GAMMA;
48 Lambda = sigma/RATIO_S2L;
49 bParam = 1;
50
51 dtmp = sqrt(24*pow(sigma,2));
52 itmp = cvRound(dtmp);
53 if(itmp%2 == 0)
54 itmp ++;
55 GaborWindow.height = GaborWindow.width = itmp;
56 bInit = 1;
57
58 create_kernel();
59}
60
61 void CGaborFilter::Init( float dLambda, float dTheta, float dPhi, float dGamma)
62 {
63 float dtmp;
64 int itmp;
65
66 Lambda = dLambda;
67 Theta = dTheta;
68 Phi = dPhi;
69 Gamma = dGamma;
70 sigma = Lambda * RATIO_S2L;
71 bParam = 1;
72
73 dtmp = sqrt(24*pow(sigma,2));
74 itmp = cvRound(dtmp);
75 if(itmp%2 == 0)
76 itmp ++;
77 GaborWindow.height = GaborWindow.width = itmp;
78 bInit = 1;
79
80 create_kernel();
81}
82
83 void CGaborFilter::create_kernel()
84 {
85 float tmp1,tmp2,xtmp,ytmp,re;
86 int i,j,x,y;
87
88 if(is_init() == 0)
89 printf("The parameters haven't been initialed!");
90
91
92 else{
93
94
95 m_pGaborFilter = cvCreateMat(GaborWindow.height,GaborWindow.width,CV_32FC1);
96 for(i= 0; i< GaborWindow.height; i++)
97 for(j = 0; j< GaborWindow.width; j++)
98 {
99 x = j - GaborWindow.width/2;
100 y = i - GaborWindow.height/2;
101
102
103 xtmp = (float)x*cos(Theta) - (float)y*sin(Theta);
104 ytmp = (float)x*sin(Theta) + (float)y*cos(Theta);
105
106 tmp1 = exp(-(pow(xtmp,2)+pow(ytmp*Gamma,2))/(2*pow(sigma,2)));
107 tmp2 = cos(2*PI*xtmp/Lambda + Phi);
108 // int p=sizeof(float);
109 re = tmp1*tmp2;
110 cvSetReal2D((CvMat*)m_pGaborFilter,i,j,re);
111
112 }
113 bKernel = 1;
114 }
115}
116
117 IplImage * CGaborFilter::get_Image()
118 {
119 if(is_kernel() == 0)
120 {
121 printf("The filter hasn't bee created!");
122 }
123 else
124 {
125 IplImage *pImg = cvCreateImage(GaborWindow,IPL_DEPTH_32F,1);
126 IplImage *pImgU8 = cvCreateImage(GaborWindow,IPL_DEPTH_8U,1);
127 CvMat * pMat = cvCreateMat(GaborWindow.height,GaborWindow.width,CV_32FC1);
128
129 cvCopy(m_pGaborFilter,pImg);
130 //pImg->imageData = (char *)pMat->data;
131 cvNormalize((IplImage*)pImg, (IplImage*)pImg,0,255,CV_MINMAX,NULL);
132 cvConvertScaleAbs(pImg,pImgU8,1,0);
133 return pImgU8;
134 }
135}
136
137 IplImage * CGaborFilter::do_filter( const IplImage * src)
138 {
139 if(is_kernel()==false)
140 {
141 printf("The Gabor Kernel has not been created!");
142 }
143 else{
144
145 IplImage *pDestImage = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
146 // IplImage * pGaborImage = get_Imge();
147 // CvMat GaborKernel = cvMat(pGaborImage->height,pGaborImage->width,CV_8U,pGaborImage->imageData);
148 IplImage *tmpImg = cvCloneImage(src);
149 IplImage *tmpGrayImg = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
150
151 if(tmpImg->nChannels != 1)
152 {
153 cvCvtColor(tmpImg,tmpGrayImg,CV_BGR2GRAY);
154 }
155 else
156 {
157 cvReleaseImage(&tmpGrayImg);
158 tmpGrayImg = tmpImg;
159 }
160 CvMat * pGaborKernel = get_Mat();
161
162 cvFilter2D(tmpGrayImg,pDestImage,pGaborKernel,cvPoint((GaborWindow.width-1)/2,(GaborWindow.height-1)/2));
163
164 cvReleaseImage(&tmpImg);
165 return pDestImage;
166 }
167}