首页 > 代码库 > CVPR读书笔记[5]:Gabor特征提取之Gabor核的实现
CVPR读书笔记[5]:Gabor特征提取之Gabor核的实现
朱金华 jinhua1982@gmail.com 2014.08.09
本文参考http://blog.csdn.net/njzhujinhua/article/details/38460861的描述基于opencv实现Gabor核.
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]作为核
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。