朱金华  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]作为核

CVPR读书笔记[5]:Gabor特征提取之Gabor核的实现的更多相关文章

  1. 2019 ICCV、CVPR、ICLR之视频预测读书笔记

    2019 ICCV.CVPR.ICLR之视频预测读书笔记 作者 | 文永亮 学校 | 哈尔滨工业大学(深圳) 研究方向 | 视频预测.时空序列预测 ICCV 2019 CVP github地址:htt ...

  2. 【读书笔记与思考】《python数据分析与挖掘实战》-张良均

    [读书笔记与思考]<python数据分析与挖掘实战>-张良均 最近看一些机器学习相关书籍,主要是为了拓宽视野.在阅读这本书前最吸引我的地方是实战篇,我通读全书后给我印象最深的还是实战篇.基 ...

  3. Gabor变换、Gabor滤波器

    D.Gabor 1946年提出 窗口Fourier变换,为了由信号的Fourier变换提取局部信息,引入了时间局部化的窗函数. 由于窗口Fourier变换只依赖于部分时间的信号,所以,现在窗口Four ...

  4. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  5. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  6. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  7. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  8. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  9. Web高级征程:《大型网站技术架构》读书笔记系列

    一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...

随机推荐

  1. (转)phpmyadmin操作技巧:如何在phpmyadmin里面复制mysql数据库?

    转之--http://blogunion.org/posts/copy-mysql-data-in-phpmyadmin.html 对于每一个站长而言,都会遇到要进行网站测试的时候.这个时候,往往需要 ...

  2. java_reflect_01

    最近学习java开始接触到了框架,突然觉得java反射很重要,因此在这里做了一些总结(参考园中大苞米大神的文章) 首先我们要认识一下Class: 一.Class类有什么用? class类的实例表示ja ...

  3. Animator Override Controllers 学习及性能测试

    本文由博主(YinaPan)原创,转载请注明出处:http://www.cnblogs.com/YinaPan/p/Unity_AnimatorOverrideContorller.html  The ...

  4. 设计模式C++实现(1)——工厂模式

    该文章转载自: http://blog.csdn.net/wuzhekai1985 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装 ...

  5. 94 Binary Tree Inorder Traversal(二叉树中序遍历Medium)

    题目意思:二叉树中序遍历,结果存在vector<int>中 解题思路:迭代 迭代实现: /** * Definition for a binary tree node. * struct ...

  6. 如何完全禁用或卸载Windows 10中的OneDrive - 51CTO.COM

    OneDrive 是微软的个人云存储平台,提供了对个人用户的文件托管.存储和同步等服务,OneDrive 默认被内置在 Windows 10 操作系统当中,而且当用户使用 微软账户 登录时,OneDr ...

  7. python序列化之pickle

    来自引用: 1.什么东西能用pickle模块存储? 所有Python支持的 原生类型 : 布尔, 整数, 浮点数, 复数, 字符串, bytes(字节串)对象, 字节数组, 以及 None. 由任何原 ...

  8. IDA6.6调试安卓程序配置教程

    1.把ida 目录下android_server传到设备的 /data/local/tmp/ cmd执行adb shell 进入模拟器命令行 su cd /data/local/tmp/ chmod ...

  9. 黑马程序员—C语言的函数、数组、字符串

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.函数 定义:函数是代码复用的一种机制. 函数的基本语法: 返回类型 函数名 ( 参数类型 参 ...

  10. PQJ 1686(栈栈栈)

    PQJ  1686(栈栈栈) 用栈解决问题 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I6 ...