转自http://blog.163.com/shi-xj/blog/static/3178051520110703223313/
前几篇日志介绍了Gabor滤波器,我在OPENCV上编了一个Gabor核类,望各位看客指正。
参考公式:
/**********************************************************
Author XJ Shi. FileName: Gabor.h
Define the class head to Gabor Filter
@ 2011.1.2
***********************************************************/
#ifndef _GABOR_H
#define _GABOR_H
#include <stdio.h>
#include <iostream>
//#include <stdafx.h>
#include <cv.h>
#define PI 3.14159
#define GAMMA 0.5 //The default value of γ,which is the spatial aspect ratio (sigma_x/sigma_y)
#define RATIO_S2L 0.56 //The default value of σ/λ
class Gabor {
public:
//@construct
Gabor(float dLambda, float dTheta,float dRatio_S2L = RATIO_S2L, float dGamma = GAMMA,float dPhi = 0);
//@abolish
~Gabor();
//@init
void init(float dLambda,float dTheta, float dPhi,float dGamma = GAMMA);
//@init
void init(float dSigma, float dTheta, float dPhi);
//@init
void init();
//@To find whether the Gabor kernel is created
bool is_kernel(){ return bKernel; }
//@To find whether the parameters is inited
bool is_init() { return bInit; }
//@To find whether the parameters inited is enough
bool is_param() { return bParam; }
//@Get the kernel in matrix form
CvMat* get_Mat() { return pGaborfilter; }
//@Get the kernel in image form
IplImage* get_Imge();
//@Do the filtering operation to input image with Gabor kernel
IplImage* do_filter(const IplImage *src);
protected:
bool bParam; //bool , if the parameters inited are enough
bool bKernel; //bool
bool bInit; //bool
float Lambda; //Wavelength of the cosine factor, which represent the central frequency of Gabor filter
float Theta; //Orientation of the Gabor function, the axis x'
float Sigma; // The standard deviation of x, and for y , it is Sigma/Gamma;
float Gamma; // The spatial aspect ratio
float Phi; //The phase offset of Gabor
CvSize GaborWindow; //The width of window
CvMat *pGaborfilter; //The kernel of Gabor filter
private:
void create_kernel();
};
#endif
/*************************************************************************************************
Author: XJ Shi. FileName: Gabor.cpp
The member function in class Gabor
@2010.1.3
**************************************************************************************************/
#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <Gabor.h>
#include <cstdlib>
Gabor::Gabor(float dLambda, float dTheta, float dRatio_S2L, float dGamma, float dPhi)
{
Lambda = dLambda;
Theta = dTheta;
Sigma = dLambda*dRatio_S2L;
Gamma = dGamma;
Phi = dPhi;
pGaborfilter = NULL;
bParam = 1;
}
Gabor::~Gabor()
{
cvReleaseMat(&pGaborfilter);
}
void Gabor::init()
{
float dtmp;
int itmp;
if(is_param() == 0)
{
printf("The parameters are not enough!");
}
else
{
dtmp = sqrt(48*pow(Sigma,2)+1);
itmp = cvRound(dtmp);
if(itmp%2 == 0)
itmp ++;
GaborWindow.height = GaborWindow.width = 16;
bInit = 1;
create_kernel();
}
}
void Gabor::init(float dSigma, float dTheta, float dPhi)
{
float dtmp;
int itmp;
Sigma = dSigma;
Theta = dTheta;
Phi = dPhi;
Gamma = GAMMA;
Lambda = Sigma/RATIO_S2L;
bParam = 1;
dtmp = sqrt(24*pow(Sigma,2));
itmp = cvRound(dtmp);
if(itmp%2 == 0)
itmp ++;
GaborWindow.height = GaborWindow.width = itmp;
bInit = 1;
create_kernel();
}
void Gabor::init(float dLambda, float dTheta, float dPhi, float dGamma)
{
float dtmp;
int itmp;
Lambda = dLambda;
Theta = dTheta;
Phi = dPhi;
Gamma = dGamma;
Sigma = Lambda * RATIO_S2L;
bParam = 1;
dtmp = sqrt(24*pow(Sigma,2));
itmp = cvRound(dtmp);
if(itmp%2 == 0)
itmp ++;
GaborWindow.height = GaborWindow.width = itmp;
bInit = 1;
create_kernel();
}
void Gabor::create_kernel()
{
float tmp1,tmp2,xtmp,ytmp,re;
int i,j,x,y;
if(is_init() == 0)
printf("The parameters haven't been initialed!");
else{
pGaborfilter = cvCreateMat(GaborWindow.height,GaborWindow.width,CV_32FC1);
for(i= 0; i< GaborWindow.height; i++)
for(j = 0; j< GaborWindow.width; j++)
{
x = j - GaborWindow.width/2;
y = i - GaborWindow.height/2;
xtmp = (float)x*cos(Theta) - (float)y*sin(Theta);
ytmp = (float)x*sin(Theta) + (float)y*cos(Theta);
tmp1 = exp(-(pow(xtmp,2)+pow(ytmp*Gamma,2))/(2*pow(Sigma,2)));
tmp2 = cos(2*PI*xtmp/Lambda + Phi);
// int p=sizeof(float);
re = tmp1*tmp2;
cvSetReal2D((CvMat*)pGaborfilter,i,j,re);
}
bKernel = 1;
}
}
IplImage* Gabor::get_Imge()
{
if(is_kernel() == 0)
printf("The filter hasn't bee created!");
else{
IplImage *pImg = cvCreateImage(GaborWindow,IPL_DEPTH_32F,1);
IplImage *pImgU8 = cvCreateImage(GaborWindow,IPL_DEPTH_8U,1);
CvMat * pMat = cvCreateMat(GaborWindow.height,GaborWindow.width,CV_32FC1);
cvCopy(pGaborfilter,pImg);
//pImg->imageData = (char *)pMat->data;
cvNormalize((IplImage*)pImg, (IplImage*)pImg,0,255,CV_MINMAX,NULL);
cvConvertScaleAbs(pImg,pImgU8,1,0);
return pImgU8;
}
}
IplImage * Gabor::do_filter(const IplImage *src)
{
if(is_kernel()==false)
printf("The Gabor Kernel has not been created!");
else{
IplImage *pDestImage = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
// IplImage * pGaborImage = get_Imge();
// CvMat GaborKernel = cvMat(pGaborImage->height,pGaborImage->width,CV_8U,pGaborImage->imageData);
IplImage *tmpImg = cvCloneImage(src);
IplImage *tmpGrayImg = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
if(tmpImg->nChannels != 1)
cvCvtColor(tmpImg,tmpGrayImg,CV_BGR2GRAY);
else
{
cvReleaseImage(&tmpGrayImg);
tmpGrayImg = tmpImg;
}
CvMat * pGaborKernel = get_Mat();
cvFilter2D(tmpGrayImg,pDestImage,pGaborKernel,cvPoint((GaborWindow.width-1)/2,(GaborWindow.height-1)/2));
cvReleaseImage(&tmpImg);
return pDestImage;
}
}
测试代码如下::
/*******************************************************************
FileName: test.cpp
The main function is in the file.
2010.1.3
***********************************************************************/
#include <iostream>
#include <Gabor.h>
#include "cv.h"
#include "highgui.h"
#include <ctype.h>
void main()
{
Gabor filter1(2.74,PI*3/4,RATIO_S2L,GAMMA,0);
filter1.init();
IplImage* pGaborImg = filter1.get_Imge();
IplImage* inputImg = cvLoadImage("F://12.jpg",-1);
cvNamedWindow("InputImage",CV_WINDOW_AUTOSIZE);
cvShowImage("InputImage",inputImg);
cvNamedWindow("Gabor",CV_WINDOW_AUTOSIZE);
cvShowImage("Gabor",pGaborImg);
IplImage* outImage = filter1.do_filter(inputImg);
cvNamedWindow("OutputImage",CV_WINDOW_AUTOSIZE);
cvShowImage("OutputImage",outImage);
int key;
key = cvWaitKey(0);
cvSaveImage("F:\\GaborKernel.jpg",pGaborImg);
//cvReleaseImage(&pGaborImg);
cvSaveImage("F:\\FilteredImage.jpg",outImage);
}
结果:
Gabor图像: