【OpenCV学习】DFT变换

简介: 作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ #include "cv.h" #include "highgui.h" #include "cxcore.

作者: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 中国大陆”许可协议授权。


分享到:

目录
相关文章
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
OpenCV与AI深度学习之常用AI名词解释学习
AGI:Artificial General Intelligence (通用人工智能):是指具备与人类同等或超越人类的智能,能够表现出正常人类所具有的所有智能行为。又被称为强人工智能。
137 2
|
6月前
|
计算机视觉
opencv之形态变换
opencv之形态变换
|
5月前
|
计算机视觉 Python
opencv 处理图像去噪的几种方法学习
OpenCV 提供了多种图像去噪的方法,以下是一些常见的去噪技术以及相应的 Python 代码示例: 均值滤波:使用像素邻域的灰度均值代替该像素的值。
70 0
|
6月前
|
算法 计算机视觉
【Qt&OpenCV 图像的形态学变换 morpholgyEx】
【Qt&OpenCV 图像的形态学变换 morpholgyEx】
38 0
|
6月前
|
机器学习/深度学习 开发框架 TensorFlow
### 如何系统化学习OpenCV4
### 如何系统化学习OpenCV4
43 0
|
7月前
|
存储 编解码 算法
【OpenCV】-霍夫变换
【OpenCV】-霍夫变换
|
7月前
|
算法 计算机视觉 Python
【OpenCV】-算子(Sobel、Canny、Laplacian)学习
【OpenCV】-算子(Sobel、Canny、Laplacian)学习
216 2
|
7月前
|
计算机视觉 Python
轻松掌握opencv的8种图像变换
轻松掌握opencv的8种图像变换
|
7月前
|
计算机视觉
【OpenCV】-仿射变换
【OpenCV】-仿射变换
|
7月前
|
存储 计算机视觉
OpenCV—学习基本绘图
OpenCV—学习基本绘图