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


             朱金华  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]作为核
  • 相关阅读:
    Bzoj1499: [NOI2005]瑰丽华尔兹
    Bzoj1016: [JSOI2008]最小生成树计数
    清橙A1212:剪枝
    SPOJ1825:Free tour II
    http://www.freepik.com/
    A Guide To Transclusion in AngularJS
    styling-customizing-file-inputs
    You Don't Know JS: this & Object Prototypes
    git中https和SSH的区别
    difference between match and exec
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4003873.html
Copyright © 2020-2023  润新知