zoukankan      html  css  js  c++  java
  • 【OpenCV学习】DFT变换

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

    #include "cv.h"
    #include "highgui.h"
    #include "cxcore.h"
    void cvShiftDFT(CvArr *src_arr,CvArr *dst_arr)
    {
        CvMat * tmp;
        CvMat q1stub,q2stub;
        CvMat q3stub,q4stub;
        CvMat d1stub,d2stub;
        CvMat d3stub,d4stub;
        CvMat *q1,*q2,*q3,*q4;
        CvMat *d1,*d2,*d3,*d4;
        CvSize size = cvGetSize(src_arr);
        CvSize dst_size = cvGetSize(dst_arr);
        int cx,cy;
        if ((dst_size.width!= size.width)||(dst_size.height!=size.height))
        {
            cvError(CV_StsUnmatchedSizes,"cvShiftDFT",
                "Source and Destination arrays must have the same sizes",
                __FILE__,__LINE__);
        }
        if (src_arr == dst_arr)
        {
            tmp = cvCreateMat(size.height/2,size.width/2,cvGetElemType(src_arr));
        }
        cx=size.width/2;//取出图像的原点
        cy=size.height/2;
        q1=cvGetSubRect(src_arr,&q1stub,cvRect(0,0,cx,cy));
        //取出图像的第一象限,由q1指针指向它
        q2=cvGetSubRect(src_arr,&q2stub,cvRect(cx,0,cx,cy));
        //取出图像的第二象限,由q2指针指向它
        q3=cvGetSubRect(src_arr,&q3stub,cvRect(cx,cy,cx,cy));
        //取出图像的第三象限,由q3指针指向它
        q4=cvGetSubRect(src_arr,&q4stub,cvRect(0,cy,cx,cy));
        //取出图像的第四象限,由q4指针指向它
       
        d1=cvGetSubRect(src_arr,&d1stub,cvRect(0,0,cx,cy));
        d2=cvGetSubRect(src_arr,&d2stub,cvRect(cx,0,cx,cy));
        d3=cvGetSubRect(src_arr,&d3stub,cvRect(cy,cy,cx,cy));
        d4=cvGetSubRect(src_arr,&d4stub,cvRect(0,cy,cx,cy));
        if (src_arr!=dst_arr)
        {
            if (!CV_ARE_TYPES_EQ(q1,d1))
            {
                cvError(CV_StsUnmatchedSizes,"cvShiftDFT",
                    "Source and Destination arrays must have the same sizes",
                    __FILE__,__LINE__);       
            }
            //以图像中心为原点,调整傅里叶变换图像的四个象限区,
            //即第一与第三象限交换,第二与第四象限交换
            cvCopy(q3,d1,0);
            cvCopy(q4,d2,0);
            cvCopy(q1,d3,0);
            cvCopy(q2,d4,0);
        }
        else
        {//若源矩阵和目的矩阵相同则直接在源矩阵中进行操作
            cvCopy(q3,tmp,0);
            cvCopy(q1,q3,0);
            cvCopy(tmp,q1,0);
            cvCopy(q4,tmp,0);
            cvCopy(q2,q4,0);
            cvCopy(tmp,q2,0);
        }
    }
    int main(int argc,char ** argv)
    {
        const char* filename =(argc>=2?argv[1]:"lena.jpg");
        IplImage *im;
        IplImage *realInput,*imaginaryInput,*complexInput;
        IplImage *image_Re,*image_Im;
        int dft_M,dft_N;
        CvMat *dft_A;
        CvMat tmp;
        double m,M;
        im = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE  );//加载图像
        if (!im)
        {
            return -1;
        }
        //分配空间
        realInput = cvCreateImage(cvGetSize(im),IPL_DEPTH_64F,1);//单通道
        imaginaryInput =cvCreateImage(cvGetSize(im),IPL_DEPTH_64F,1);//单通道
        complexInput = cvCreateImage(cvGetSize(im),IPL_DEPTH_64F,2);//双通道
        cvScale(im,realInput,1.0,0.0);
        //#define cvScale cvConvertScale=>readInput=im
        cvZero(imaginaryInput);
        //清空这个图像的内容
        cvMerge(realInput,imaginaryInput,NULL,NULL,complexInput);
        //混合这两个图像作为complexInput的两个通道
        /*得到最优DFT尺寸 */
        dft_M = cvGetOptimalDFTSize(im->height-1);
        dft_N = cvGetOptimalDFTSize(im->width-1);
       
        dft_A = cvCreateMat(dft_M,dft_N,CV_64FC2);
        image_Re = cvCreateImage(cvSize(dft_N,dft_M),IPL_DEPTH_64F,1);//实部
        image_Im = cvCreateImage(cvSize(dft_N,dft_M),IPL_DEPTH_64F,1);//虚部
        cvGetSubRect(dft_A,&tmp,cvRect(0,0,im->width,im->height));
        cvCopy(complexInput,&tmp,NULL);
        if( dft_A->cols > im->width )//若得到的最优DFT尺寸在宽度上大于原图,则重新取
        {
            cvGetSubRect(dft_A,&tmp,cvRect(im->width,0,dft_A->cols-im->width,im->height));
            cvZero(&tmp);
        }
        cvDFT(dft_A,dft_A,CV_DXT_FORWARD,complexInput->height);
       
        cvNamedWindow("win",0);
        cvNamedWindow("magnitude",0);
        cvShowImage("win",im);
       
        //分割出实部和虚部
        cvSplit(dft_A,image_Re,image_Im,0,0);
       
        //计算功率谱 Mag=sqrt(Re^2+Im^2)
        cvPow(image_Re,image_Re,2.0);
        cvPow(image_Im,image_Im,2.0);
        cvAdd(image_Re,image_Im,image_Re,NULL);//image_Re<=image_Re+image_Im
        cvPow(image_Re,image_Re,0.5);
        //计算log(1+Mag)
        cvAddS(image_Re,cvScalarAll(1.0),image_Re,NULL);
        cvLog(image_Re,image_Re);
        cvShiftDFT(image_Re,image_Re);
        cvMinMaxLoc(image_Re,&m,&M,NULL,NULL,NULL);
        cvScale(image_Re,image_Re,1.0/(M-m),1.0*(-m)/(M-m));
        cvShowImage("magnitude",image_Re);
        cvWaitKey(-1);
        return 0;
    } 

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/


                   作者:gnuhpc
                   出处:http://www.cnblogs.com/gnuhpc/
                   除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


    分享到:

  • 相关阅读:
    WSP部署错误—SharePoint管理框架中的对象“SPSolutionLanguagePack Name=0”依赖其他不存在的对象
    Elevate Permissions To Modify User Profile
    Error with Stsadm CommandObject reference not set to an instance of an object
    ASP.NET MVC3添加Controller时没有Scaffolding options
    测试使用Windows Live Writer写日志
    配置TFS 2010出现错误—SQL Server 登录的安全标识符(SID)与某个指定的域或工作组帐户冲突
    使用ADO.NET DbContext Generator出现错误—Unable to locate file
    CSS
    HTML DIV标签
    数据库
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2715888.html
Copyright © 2011-2022 走看看