您的位置:首页 > 其它

CVPR读书笔记[5]:Gabor特征提取之Gabor核的实现

2014-08-16 09:11 330 查看
         朱金华 
jinhua1982@gmail.com   2014.08.09

 

 

本文参考http://blog.csdn.net/njzhujinhua/article/details/38460861的描述基于opencv实现Gabor核.

本文是Gabor特征提取三部分之二:

[1]CVPR读书笔记[4]:Gabor特征提取之Gabor核

http://blog.csdn.net/njzhujinhua/article/details/38460861

[2] CVPR读书笔记[5]:Gabor特征提取之Gabor核的实现

http://blog.csdn.net/njzhujinhua/article/details/38610281

[3] CVPR读书笔记[6]:Gabor特征提取
http://blog.csdn.net/njzhujinhua/article/details/38614697
ZGabor类声明, 该类只具备Kernel的计算, 具体使用在各faborfeature相关算法中实现.

#define GABOR_SCALE_NUM    5
#define GABOR_ANGLE_NUM    8

class ZGabor
{
public:
//默认参数及指定参数的初始化
bool  InitGabor();
bool  InitGabor(Size ksize, double kmax, double f, double sigma);

//存放kernel的实部,虚部及幅值矩阵, 直接使用, 暂未封装
Mat    m_gaborReKernel[GABOR_SCALE_NUM][GABOR_ANGLE_NUM];
Mat    m_gaborImgKernel[GABOR_SCALE_NUM][GABOR_ANGLE_NUM];
Mat    m_gaborMagKernel[GABOR_SCALE_NUM][GABOR_ANGLE_NUM];

void   test();

protected:
bool  InitKernel();
bool  GetKernel(Size ksize, int scaleIdx, int angleIdx, Mat &realKernel, Mat&imgKernel);
Mat   GetKernelMagnitude(const Mat &rekernel, const Mat&imgkernel);

double m_kmax;
double m_f;
double m_sigma;
int    m_scaleNum;
int    m_angleNum;
Size   m_ksize;
private:

};


实现部分

#include "zgabor.h"

/*
Zhu.Jinhua
jinhua1982@gmail.com   20140809 http://blog.csdn.net/njzhujinhua/article/details/38460861 说明:参数初始化,使用默认参数
*/
bool ZGabor::InitGabor()
{
m_kmax = CV_PI/2;
m_f = sqrt(double(2));
m_sigma = 2*CV_PI;
m_scaleNum = GABOR_SCALE_NUM;
m_angleNum = GABOR_ANGLE_NUM;
m_ksize = Size(19,19);

InitKernel();
return true;
}
/*
Zhu.Jinhua
jinhua1982@gmail.com   20140809
说明:参数初始化,使用指定参数
*/
bool ZGabor::InitGabor(Size ksize, double kmax, double f, double sigma)
{
m_kmax = kmax;
m_f = f;
m_sigma = sigma;
m_scaleNum = GABOR_SCALE_NUM;
m_angleNum = GABOR_ANGLE_NUM;
m_ksize = ksize;

InitKernel();
return true;
}
/*
Zhu.Jinhua
jinhua1982@gmail.com   20140809
说明:<span style="color:green;">Gabor</span><span style="color:green;">核的生成</span>
*/
bool ZGabor::InitKernel()
{
for (int scaleIdx=0;scaleIdx < GABOR_SCALE_NUM; scaleIdx++)
{
for (int angleIdx = 0;angleIdx < GABOR_ANGLE_NUM; angleIdx++)
{
GetKernel(m_ksize, scaleIdx, angleIdx, m_gaborReKernel[scaleIdx][angleIdx], m_gaborImgKernel[scaleIdx][angleIdx]);
m_gaborMagKernel[scaleIdx][angleIdx] = GetKernelMagnitude(m_gaborReKernel[scaleIdx][angleIdx], m_gaborImgKernel[scaleIdx][angleIdx]);
}
}

return true;
}

/*
Zhu.Jinhua
jinhua1982@gmail.com   20140809
Get kernel magnitude by re and img part.
return magnitude Mat
*/
Mat  ZGabor::GetKernelMagnitude(const Mat &rekernel, const Mat&imgkernel)
{
CV_Assert(rekernel.size() == imgkernel.size());
CV_Assert(rekernel.type() == imgkernel.type());
Mat mag;
magnitude(rekernel,imgkernel, mag);

//test
/*Mat tmp;
normalize(rekernel,tmp,0,255,CV_MINMAX,CV_8U);
imshow("mag", tmp);
waitKey();
*/

return mag;
}

/*
Zhu.Jinhua
jinhua1982@gmail.com  20140809
Real Part:
G(k,x,y,θ)=k^2/σ^2*exp⁡(-(k^2 (x^2+y^2 ))/(2σ^2 ))*(cos(k(xcosθ+ysinθ))-exp⁡(-σ^2/2))
Imag Part:
G(k,x,y,θ)=k^2/σ^2*exp⁡(-(k^2 (x^2+y^2 ))/(2σ^2 ))*(sin(k(xcosθ+ysinθ)))
In:ksize --kernel size
scaleIdx --Scale index
andeIdx  --angle index
Out:
realKernel  --real part of kernel
imgKernel   --imagine part of kernel
*/
bool  ZGabor::GetKernel(Size ksize, int scaleIdx, int angleIdx, Mat &realKernel, Mat&imgKernel)
{
int xmin=0,xmax=0;
int ymin=0,ymax=0;

//we suppose kernel width equal height.
assert(ksize.width == ksize.height);

xmax=ksize.width/2;
ymax=ksize.height/2;
xmin=-xmax;
ymin=-ymax;

//reset out para mat size
realKernel.create(xmax-xmin+1,ymax-ymin+1,CV_32FC1);
imgKernel.create(xmax-xmin+1,ymax-ymin+1,CV_32FC1);
double k=m_kmax/pow(m_f,scaleIdx);

double scaleFactor=k*k/m_sigma/m_sigma; //k^2/σ^2
double DC=exp(-m_sigma*m_sigma/2); //direct current
double theta=CV_PI*angleIdx/m_angleNum;
double costheta=cos(theta), sintheta=sin(theta);

float *ptr_re = NULL;
float *ptr_img = NULL;;

for (int y=ymin;y<=ymax;y++)
{
ptr_re=realKernel.ptr<float>(y-ymin);
ptr_img = imgKernel.ptr<float>(y-ymin);
for (int x=xmin;x<=xmax;x++)
{
double xcys=x*costheta+y*sintheta; //xcosθ+ysinθ
double pub=scaleFactor*exp(-scaleFactor/2*(x*x+y*y));//k^2/σ^2*exp⁡(-(k^2 (x^2+y^2 ))/(2σ^2 ))
double re_minus_dc=cos(k*xcys)-DC;//(cos(k(xcosθ+ysinθ))-exp⁡(-σ^2/2))
double img=sin(k*xcys);//(sin(k(xcosθ+ysinθ)))

ptr_re[x-xmin]=pub*re_minus_dc;
ptr_img[x-xmin]=pub*img;
//cout<<"y="<<y-ymin<<" x="<<x-xmin<<" = "<<ptr_re[x-xmin]<<endl;
}
}

return true;
}


测试代码

void ZGabor::test()
{
Mat reKernel;
Mat imgKernel;
Mat mag;
Mat displayMatCol,displayMat, line;
//InitGabor();//CV_PI/2,1.4*(1.0+i/10.0),CV_PI*2);
for (int i=0;i<8;i++)
{
displayMatCol.release();

for (int j=0;j<5;j++)
{
normalize(m_gaborReKernel[j][i],reKernel,0,255,CV_MINMAX,CV_8U);

line=Mat::ones(3,reKernel.cols,reKernel.type())*255;
displayMatCol.push_back(reKernel);
displayMatCol.push_back(line);
}
displayMatCol=displayMatCol.t();
line=Mat::ones(2,displayMatCol.cols,displayMatCol.type())*255;
displayMat.push_back(displayMatCol);
displayMat.push_back(line);
}

displayMat=displayMat.t();
imwrite("gabor5x8.jpg",displayMat);
imshow("Gabor Kernel",displayMat);
waitKey(0);
}


得到的实部的图示(图中ksize=100)



使用方法

ZGabor m_gabor
m_gabor.InitGabor();
m_gabor.test();


 

用于滤波的话直接使用m_gabor.m_gaborReKernel[i][j]作为核
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息