您的位置:首页 > 编程语言 > C语言/C++

基于opencv的Gabor滤波器设计(C++)版

2014-07-09 20:46 495 查看
一直在做人脸识别方向,想用一下Gabor滤波器做一下Gabor人脸。从网上看到Mian Zhou. Thesis. Gabor-Boosting Face Recognition的Gabor代码,也是基于Opencv的但是,代码是基于C结构的,用起来感觉不方便,就花一天的时间,修改成了C++结构的。
/*
Copyright (C) 2014 by Fangqi Su
Reference: Mian Zhou. Thesis. Gabor-Boosting Face Recognition
*/
#ifndef GABORFLITER_H
#define GABORFLITER_H
#include<iostream>
#include<opencv2\opencv.hpp>
#include<highgui.h>
#define CV_GABOR_REAL 1
#define CV_GABOR_IMAG 2
#define CV_GABOR_MAG 3
#define CV_GABOR_PHASE 4
using namespace cv;
class Gabor
{

public:
Gabor();
Gabor(int iMu,int iNu,double dSigma);
Gabor(int iMu,int iNu,double dSigma,double dF);
Gabor(double dPhi,int iNu);
Gabor(double dPhi,int iNu,double dSigma);
Gabor(double dPhi,int iNu,double dSigma,double dF);
Gabor(int iMu,int iNu);
bool IsInit();
bool IsKernelCreate();
long mask_width();
void Init(int iMu,int iNu,double dSigma,double dF);
void Init(double dPhi,int iNu,double dSigma,double dF);
void output_file(const char *filename,int Type);
Mat get_matrix(int Type);
Mat get_image(int Type);
void show(int Type);
void conv_img(Mat &src,Mat&dst,int Type);
long Gabor::get_mask_width();

protected:
int KernelSize;
double Sigma;
double F;
double Kmax;
double K;
double Phi;
bool bInitialised;
bool bKernel;
long Width;
Mat Imag;
Mat Real;

private:
void creat_kernel();

};

#endif
/*
Copyright (C) 2014 by Fangqi Su
Reference: Mian Zhou. Thesis. Gabor-Boosting Face Recognition
*/
#include"GaborFliter.h"

Gabor::Gabor()
{

}
/*
fn Gabor::Gabor(int iMu,int iNu,double dSigma);
Constuct a gabor
Parameters:
iMu		The orientation iMu*PI/8,
iNu 		The scale,
dSigma 		The sigma value of Gabor,

Create a gabor with a orientation iMu*PI/8, a scale iNu, and a sigma value dSigma. The spatial frequence (F) is set to sqrt(2) defaultly. It calls Init() to generate parameters and kernels.
*/
Gabor::Gabor(int iMu,int iNu,double dSigma)
{
F=sqrt(2.0);
Init(iMu,iNu,dSigma,F);
}
/*!
\fn Gabor::Gabor(int iMu, int iNu, double dSigma, double dF)
Construct a gabor

Parameters:
iMu		    The orientation iMu*PI/8
iNu 		The scale
dSigma 		The sigma value of Gabor
dF		    The spatial frequency

Returns:
None

Create a gabor with a orientation iMu*PI/8, a scale iNu, a sigma value dSigma, and a spatial frequence dF. It calls Init() to generate parameters and kernels.
*/
Gabor::Gabor(int iMu,int iNu,double dSigma,double dF)
{
Init(iMu,iNu,dSigma,dF);
}
/*!
\fn Gabor::Gabor(double dPhi, int iNu)
Construct a gabor

Parameters:
dPhi		The orientation in arc
iNu 		The scale

Returns:
None

Create a gabor with a orientation dPhi, and with a scale iNu. The sigma (Sigma) and the spatial frequence (F) are set to 2*PI and sqrt(2) defaultly. It calls Init() to generate parameters and kernels.
*/
Gabor::Gabor(double dPhi,int iNu)
{
Sigma=2*CV_PI;
F=sqrt(2.0);
Init(dPhi,iNu,Sigma,F);
}
/*!
\fn Gabor::Gabor(double dPhi, int iNu, double dSigma)
Construct a gabor

Parameters:
dPhi		The orientation in arc
iNu 		The scale
dSigma		The sigma value of Gabor

Returns:
None

Create a gabor with a orientation dPhi, a scale iNu, and a sigma value dSigma. The spatial frequence (F) is set to sqrt(2) defaultly. It calls Init() to generate parameters and kernels.
*/
Gabor::Gabor(double dPhi,int iNu,double dSigma)
{
F=sqrt(2.0);
Init(dPhi,iNu,dSigma,F);
}
/*!
\fn Gabor::Gabor(double dPhi, int iNu, double dSigma, double dF)
Construct a gabor

Parameters:
dPhi		The orientation in arc
iNu 		The scale
dSigma 		The sigma value of Gabor
dF		The spatial frequency

Returns:
None

Create a gabor with a orientation dPhi, a scale iNu, a sigma value dSigma, and a spatial frequence dF. It calls Init() to generate parameters and kernels.
*/
Gabor::Gabor(double dPhi,int iNu,double dSigma,double dF)
{
Init(dPhi,iNu,dSigma,dF);
}
/*!
\fn Gabor::IsInit()
Determine the gabor is initilised or not

Parameters:
None

Returns:
a boolean value, TRUE is initilised or FALSE is non-initilised.

Determine whether the gabor has been initlized - variables F, K, Kmax, Phi, Sigma are filled.
*/
bool Gabor::IsInit()
{
return bInitialised;
}
/*!
\fn Gabor::mask_width()
Give out the width of the mask

Parameters:
None

Returns:
The long type show the width.

Return the width of mask (should be NxN) by the value of Sigma and iNu.
*/
long Gabor::mask_width()
{

long lWidth;
if(IsInit()==false)
{
perror("Error:Error: The Object has not been initilised in mask_width()!\n");
return 0;
}
else
{
double dModSigma=Sigma/K;
double dWidth=cvRound(dModSigma*6+1);

if(fmod(dWidth,2.0)==0.0)
dWidth++;
lWidth=(long)dWidth;
return lWidth;
}
}
/*!
\fn Gabor::creat_kernel()
Create gabor kernel

Parameters:
None

Returns:
None

Create 2 gabor kernels - REAL and IMAG, with an orientation and a scale
*/
void Gabor::creat_kernel()
{
if (IsInit() == false) {perror("Error: The Object has not been initilised in creat_kernel()!\n");}
else
{
Mat mReal(Width,Width,CV_32F),mImag(Width,Width,CV_32F);
/**************************** Gabor Function ****************************/
int x,y;
double dReal;
double dImag;
double dTemp1,dTemp2,dTemp3;
for(int i=0;i<Width;i++)
{
for(int j=0;j<Width;j++)
{
x=i-(Width-1)/2;
y=j-(Width-1)/2;
dTemp1 = (pow(K,2)/pow(Sigma,2))*exp(-(pow((double)x,2)+pow((double)y,2))*pow(K,2)/(2*pow(Sigma,2)));
dTemp2 = cos(K*cos(Phi)*x + K*sin(Phi)*y) - exp(-(pow(Sigma,2)/2));
dTemp3 = sin(K*cos(Phi)*x + K*sin(Phi)*y);
dReal = dTemp1*dTemp2;
dImag = dTemp1*dTemp3;
mReal.at<float>(i,j)=dReal;
mImag.at<float>(i,j)=dImag;
}
}
/**************************** Gabor Function ****************************/
bKernel=true;
mReal.copyTo(Real);
mImag.copyTo(Imag);

}
}
/*!
\fn Gabor::get_image(int Type)
Get the speific type of image of Gabor

Parameters:
Type		The Type of gabor kernel, e.g. REAL, IMAG, MAG, PHASE

Returns:
Pointer to image structure, or NULL on failure

Return an Image (gandalf image class) with a specific Type   "REAL"	"IMAG" "MAG" "PHASE"
*/
Mat Gabor::get_image(int Type)
{
if(IsKernelCreate() == false)
{
perror("Error: the Gabor kernel has not been created in get_image()!\n");
return Mat();
}
Mat pImage(Width,Width,CV_32F,1);
Mat newimage(Width,Width,CV_32FC1);
Mat kernel(Width,Width,CV_32FC1);
Mat re(Width,Width,CV_32FC1);
Mat im(Width,Width,CV_32FC1);
Mat ve;
int rows=kernel.rows;
int cols=kernel.cols;
switch (Type)
{
case 1://real
Real.copyTo(kernel);
kernel.copyTo(pImage);
pImage=pImage.t();
break;
case 2://Imag
Imag.copyTo(kernel);
kernel.copyTo(pImage);
pImage=pImage.t();
break;
case 3://Magnitude
Real.copyTo(re);
Imag.copyTo(im);
pow(re,2,re);
pow(im,2,im);
pow(im+re,0.5,ve);
ve.copyTo(pImage);
pImage=pImage.t();
break;
default:
break;
}
normalize(pImage,pImage,0,255,CV_MINMAX,NULL);
pImage.convertTo(pImage,CV_8U);
convertScaleAbs(pImage,newimage,1,0);
newimage.convertTo(newimage,CV_8U);
return newimage;
}
/*!
\fn Gabor::IsKernelCreate()
Determine the gabor kernel is created or not

Parameters:
None

Returns:
a boolean value, TRUE is created or FALSE is non-created.

Determine whether a gabor kernel is created.
*/
bool Gabor::IsKernelCreate()
{

return bKernel;
}
/*!
\fn Gabor::get_mask_width()
Reads the width of Mask

Parameters:
None

Returns:
Pointer to long type width of mask.
*/
long Gabor::get_mask_width()
{
return Width;
}
/*!
\fn Gabor::Init(int iMu, int iNu, double dSigma, double dF)
Initilize the.gabor

Parameters:
iMu 	The orientations which is iMu*PI.8
iNu 	The scale can be from -5 to infinit
dSigma 	The Sigma value of gabor, Normally set to 2*PI
dF 	The spatial frequence , normally is sqrt(2)

Returns:

Initilize the.gabor with the orientation iMu, the scale iNu, the sigma dSigma, the frequency dF, it will call the function creat_kernel(); So a gabor is created.
*/
void Gabor::Init(int iMu,int iNu,double dSigma,double dF)
{
bInitialised=false;
bKernel=false;
F=dF;
Sigma=dSigma;
Kmax=CV_PI/2;
// Absolute value of K
K = Kmax / pow(F, (double)iNu);
Phi = CV_PI*iMu/8;
bInitialised = true;
Width = mask_width();
Real = Mat( Width, Width, CV_32FC1);
Imag = Mat( Width, Width, CV_32FC1);
creat_kernel();

}
/*!
\fn CvGabor::CvGabor(int iMu, int iNu)
*/
Gabor::Gabor(int iMu, int iNu)
{
double dSigma = 2*CV_PI;
F = sqrt(2.0);
Init(iMu, iNu, dSigma, F);
}
/*!
\fn Gabor::Init(double dPhi, int iNu, double dSigma, double dF)
Initilize the.gabor

Parameters:
dPhi 	The orientations
iNu 	The scale can be from -5 to infinit
dSigma 	The Sigma value of gabor, Normally set to 2*PI
dF 	The spatial frequence , normally is sqrt(2)

Returns:
None

Initilize the.gabor with the orientation dPhi, the scale iNu, the sigma dSigma, the frequency dF, it will call the function creat_kernel(); So a gabor is created.filename 	The name of the image file
file_format 	The format of the file, e.g. GAN_PNG_FORMAT
image 	The image structure to be written to the file
octrlstr 	Format-dependent control structure

*/
void Gabor::Init(double dPhi, int iNu, double dSigma, double dF)
{

bInitialised = false;
bKernel = false;
Sigma = dSigma;
F = dF;
Kmax =CV_PI/2;
// Absolute value of K
K = Kmax / pow(F, (double)iNu);
Phi = dPhi;
bInitialised = true;
Width = mask_width();
Real = Mat( Width, Width, CV_32FC1);
Imag = Mat( Width, Width, CV_32FC1);
creat_kernel();
}
/*!
\fn Gabor::get_matrix(int Type)
Get a matrix by the type of kernel

Parameters:
Type		The type of kernel, e.g. REAL, IMAG, MAG, PHASE

Returns:
Pointer to matrix structure, or NULL on failure.

Return the gabor kernel.
*/
Mat Gabor::get_matrix(int Type)
{
if (!IsKernelCreate()) {perror("Error: the gabor kernel has not been created!\n"); return Mat();}
switch (Type)
{
case CV_GABOR_REAL:
return Real;
break;
case CV_GABOR_IMAG:
return Imag;
break;
case CV_GABOR_MAG:
return Mat();
break;
case CV_GABOR_PHASE:
return Mat();
break;
}
}
/*!
\fn Gabor::output_file(const char *filename, Gan_ImageFileFormat file_format, int Type)
Writes a gabor kernel as an image file.

Parameters:
filename 	The name of the image file
file_format 	The format of the file, e.g. GAN_PNG_FORMAT
Type		The Type of gabor kernel, e.g. REAL, IMAG, MAG, PHASE
Returns:
None

Writes an image from the provided image structure into the given file and the type of gabor kernel.
*/
void Gabor::output_file(const char *filename, int Type)
{
Mat pImage;
pImage = get_image(Type);
if(pImage .data!= NULL)
{
if( imwrite(filename, pImage ))
printf("%s has been written successfully!\n", filename);
else
printf("Error: writting %s has failed!\n", filename);
}
else
perror("Error: the image is empty in output_file()!\n");

}
/*!
\fn CvGabor::conv_img_a(IplImage *src, IplImage *dst, int Type)
*/
void Gabor::conv_img(Mat &src, Mat &dst, int Type)
{
Mat mat;
src.copyTo(mat);
mat.convertTo(mat,CV_32FC1);
mat=mat.t();
Mat temp;
Mat rmat(src.rows,src.cols,CV_32FC1);
Mat imat(src.rows,src.cols,CV_32FC1);
Mat kernel(Width,Width,CV_32FC1);

switch (Type)
{
case CV_GABOR_REAL:
Real.copyTo(kernel);
filter2D( mat, mat,mat.depth(),kernel, Point( (Width-1)/2, (Width-1)/2));
break;
case CV_GABOR_IMAG:
Imag.copyTo(kernel);
filter2D( mat, mat,mat.depth(),kernel, Point( (Width-1)/2, (Width-1)/2));
break;
case CV_GABOR_MAG:
/* Real Response */
Real.copyTo(kernel);
filter2D( mat, rmat,rmat.depth(),kernel, Point( (Width-1)/2, (Width-1)/2));
/* Imag Response */
Imag.copyTo(kernel);
filter2D( mat, imat,imat.depth(),kernel, Point( (Width-1)/2, (Width-1)/2));
/* Magnitude response is the square root of the sum of the square of real response and imaginary response */
pow(rmat,2,rmat);
pow(imat,2,imat);
add(rmat,imat,temp);
pow(temp,0.5,temp);
temp.copyTo(mat);
break;
case CV_GABOR_PHASE:
break;
}
normalize(mat,mat,0,255,CV_MINMAX,NULL);
mat.convertTo(mat,CV_8U);
mat=mat.t();
mat.copyTo(dst);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: