二维图形的傅里叶变换

程序有内存泄漏,主要是mat_Row,mat_Col,dst_Row,dst_Col,谁有好办法。

// Fourier.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "math.h"
#include <cv.h>
#include <highgui.h>
#include "cxcore.h"

int main(int argc, char* argv[])
{
 IplImage *img;
 IplImage *simg;

CvMat *mat_R;
 CvMat *mat_I;
 CvMat *mat_SRC; 
 CvMat *mat_Row;
 CvMat *mat_Col;
 CvMat *dst;
 CvMat *dst_R;
 CvMat *dst_I;
 CvMat *dst_Row;
 CvMat *dst_Col;
 int i,j,k;
 double temp;
 int height,width,step,channels;

//载入一幅图片
 img=cvLoadImage("c:\\1.bmp",0);

//mat_R初始化
 mat_R=cvCreateMat(img->height,img->width,CV_64FC1);
 //mat_I初始化
 mat_I=cvCreateMat(img->height,img->width,CV_64FC1);
 //mat_SRC初始化
 mat_SRC=cvCreateMat(img->height,img->width,CV_64FC2);
 //将图片数据存入mat_R(实部)
 cvConvert(img,mat_R);
 //将虚部初始化为零
 cvZero(mat_I);
 //合并实部、虚部
 cvMerge(mat_R,mat_I,NULL,NULL,mat_SRC);
 //创建双通道double类型数组
 dst=cvCreateMat(img->height,img->width,CV_64FC2);
 dst_R=cvCreateMat(img->height,img->width,CV_64FC1);
 dst_I=cvCreateMat(img->height,img->width,CV_64FC1);
 //为循环变量赋值
 height=img->height;
 width=img->width;
 channels=2;
 step=channels*width;
 //局部变量,值为正一或负一
 int check;
 //将输入数据乘以(-1)^(i+j),用于中心化
 for(j=0;j<height;j++)
 {
  for(i=0;i<width;i++)
  {
   check=(i+j)%2>0?1:-1;
   for(k=0;k<channels;k++)
   {
    mat_SRC->data.db[j*step+i*channels+k]=check*mat_SRC->data.db[j*step+i*channels+k];
   }
  }
 }
 //创建一个mat用于临时存储一行数据
 CvMat mat_Header=cvMat(4,4,CV_64FC2);
 mat_Row=cvCreateMat(1,width,CV_64FC2);
 mat_Col=cvCreateMat(1,height,CV_64FC2);
 //创建一个dst用于临时存储一行数据
 dst_Row=cvCreateMat(1,width,CV_64FC2);
 dst_Col=cvCreateMat(height,1,CV_64FC2);
 //为循环变量赋值
 height=img->height;
 width=img->width;
 channels=2;
 step=channels*width;
 //行的傅里叶变换
 for(j=0;j<height;j++)
 {
  //取得第j行数据
  mat_Row=cvGetRow(mat_SRC,&mat_Header,j);
  //正向傅里叶变换
  cvDFT(mat_Row,dst_Row,CV_DXT_FORWARD);
  //执行循环,赋值到dst
  for(i=0;i<width;i++)
  {
   for(k=0;k<channels;k++)
   {
    dst->data.db[j*step+i*channels+k]=dst_Row->data.db[i*channels+k];
   }
  }
 }

//列的傅里叶变换
 for(i=0;i<width;i++)
 {
  //取得第i列
  mat_Col=cvGetCol(dst,&mat_Header,i);
   
  //正向傅里叶变换
  cvDFT(mat_Col,dst_Col,CV_DXT_FORWARD);
  //执行循环,赋值到dst
  for(j=0;j<height;j++)
  {
   for(k=0;k<channels;k++)
   {
    dst->data.db[j*step+i*channels+k]=dst_Col->data.db[j*channels+k];
   }
  }
 }
 
 //分成两个矩阵
 cvSplit(dst,dst_R,dst_I,NULL,NULL);

//创建临时指针指向dst_R,dst_I
 double *pR,*pI;
 pR=(double *)dst_R->data.ptr;
 pI=(double *)dst_I->data.ptr;
 //创建一张用于显示的图像
 simg=cvCreateImage(cvGetSize(img),8,1);
 //为循环变量赋值
 height=simg->height;
 width=simg->width;
 channels=1;
 step=channels*width;

for(j=0;j<height;j++)
 {
  for(i=0;i<width;i++)
  {
   for(k=0;k<channels;k++)
   {
    temp=pR[j*step+i*channels+k]*pR[j*step+i*channels+k]+pI[j*step+i*channels+k]*pI[j*step+i*channels+k];
    temp=temp/(height*width);
    simg->imageData[j*step+i*channels+k]=sqrt(temp);
   }
  }
 }

cvNamedWindow("Mar",CV_WINDOW_AUTOSIZE);
 cvShowImage("Mar",simg);
 cvWaitKey(0);
 
 cvReleaseMat(&mat_R);
 cvReleaseMat(&mat_I);
 cvReleaseMat(&mat_SRC);
 //cvReleaseMat(&mat_Row);//这里无法正常释放,为什么?
 //cvReleaseMat(&mat_Col);
 cvReleaseMat(&dst);
 cvReleaseMat(&dst_R);
 cvReleaseMat(&dst_I);
 cvReleaseImage(&img);
 cvReleaseImage(&simg);
 return 0;
}

时间: 2025-01-02 10:08:15

二维图形的傅里叶变换的相关文章

图形学_二维图形的剪裁_Sutherland-Hodgeman_Cohen—Sutherland

一.Cohen-Sutherland剪裁算法 1.基本思想 对于每条线段P1P2分为三种情况处理: (1)若P1P2完全在窗口内,则显示该线段P1P2. (2)若P1P2明显在窗口外,则丢弃该线段. (3)若线段不满足(1)或(2)的条件,则在交点处把线段分为两段.其中一段完全在窗口外,可弃之.然后对另一段重复上述处理. 为快速判断,采用如下编码方法: 将窗口边线两边沿长,得到九个区域,每一个区域都用一个四位二进制数标识,直线的端点都按其所处区域赋予相应的区域码,用来标识出端点相对于裁剪矩形边界

二维图形旋转公式的推导

关于二维图形旋转可能在非常多计算机图形学相关的书籍上都会介绍,然而真正理解公式推导过程的却讲得不多. 那么怎样推导出二维图形绕某一点旋转的公式呢?我在这里就将其推导过程简要的说明一下. 事实上推导过程比較简单,首先我们来看一幅图,看看怎样推导出二维图形绕原点进行旋转的公式. 上图画的比較粗略,只是能说明问题就够了.如果旋转前的点位于P处.旋转之后的点位于P'处. 怎样求旋转之后的点P'坐标? 在图中.旋转之前P的方向角是a,旋转之后P'的方向角就变为a+b,这里b就是旋转的角度.所谓方向角是改点

二维图形的矩阵变换(三)——在WPF中的应用矩阵变换

UIElement和RenderTransform 首先,我们来看看什么样的对象可以进行变换.在WPF中,用于呈现给用户的对象的基类为Visual类,但是Visual对象并不具有变换功能,具有变换功能的是它的子类UIElement.这个类也是非常底层的类了,几乎我们所有的常用控件都是继承自它,也就是说,基本上所有的UI对象都是可以应用变换的. 然后,我们在再来看看UIElement中变换种类.UIElement支持两种变换:RenderTransform和LayoutTransform,其中La

二维图形的矩阵变换(二)——WPF中的矩阵变换基础

在前文二维图形的矩阵变换(一)——基本概念中已经介绍过二维图像矩阵变换的一些基础知识,本文中主要介绍一下如何在WPF中进行矩阵变换. Matrix结构 在WPF中,用Matrix结构(struct类型)表示二维变换矩阵,它是一个3*3的数组,结构如下, 由于第三列是常量0,0,1,因此并不作为公开属性,可见的只有剩余六个属性. 构造变换 虽然Matrix类公开了这六个属性让我们设置,但是靠直接设置这六个属性来实现平移.旋转等变换对于我们来说实在太困难了,因此又增加了如下许多函数来帮助我们实现这一

二维图形的矩阵变换(一)——基本概念

基本的二维变换可包括旋转.缩放.扭曲,和平移四种,              而这些几何运算则可以转换为一些基本的矩阵运算: 这几个变换都是线性的,但平移运算不是线性的,不能通过2*2矩阵运算完成.若要将点 (2, 1)在 x 方向将其平移 3 个单位,在 y 方向将其平移 4 个单位. 可通过先使用矩阵乘法再使用矩阵加法来完成此操作. 综合这几种基本运算,数学家们将其统一为一个3*3矩阵,存储形式如下: 由于表示仿射变换的矩阵的第三列总是(0,0,1),在存储矩阵的时候,大多只存成一个2*3的

二维图形的几何变换【转】

转自:lab104_yifan http://blog.csdn.net/accelerator_/article/details/39253983 1.基本几何变换及变换矩阵 基本几何变换都是相对于坐标原点和坐标轴进行的几何变换,有平移.比例.旋转.反射和错切等. 1.1 平移变换 是指将p点沿直线路径从一个坐标位置移到另一个坐标位置的重定位过程.他是一种不产生变形而移动物体的刚体变换(rigid-body transformation),如下图所示. 图1-1 平移变换 推导: 求得平移变换

二维图形变换

5.1二维图形变化 一.向量 是具有长度和方向的实体 二.特殊的线性组合 (1)仿射组合 (2)凸组合(对仿射组合加以更多的限制) 三.向量的点积和叉积 (1)点积 两个向量夹角的余弦值等于两个单位向量的点积 (2)叉积 两个向量的叉积是另一个三维向量,且与两个向量均正交 利用叉积求平面的法向量,三点可确定一个平面 5.2 图形坐标系 1.世界坐标系 是一个公共坐标系,是现实中物体或场景的统一参考系 2.建模坐标系 又称局部坐标系,每个物体有自己的局部中心和坐标系 3.观察坐标系 从观察者的角度

openGL实现二维图形和三维图形

openGL是一个强大的底层图形库,其命令最初的时候使用C语言实现的.openGL定义了一个图形程序接口,常用于制作处理三维图像,功能强大,调用方便,在图像处理十分受欢迎. 实现图形主要使用的是openGL的一个工具包:GLUT. GLUT (pronounced like the glut in gluttony) is the OpenGL Utility Toolkit, a window system independent toolkit for writing OpenGL prog

QT 二维图形 原理、发展及应用

转载自 网易博客:sun的博客 http://zhouyang340.blog.163.com/blog/static/3024095920126710504178/ 2D绘图 Qt4中的2D绘图部分称为Arthur绘图系统.它由3个类支撑整个框架,QPainter,QPainterDevice和QPainterEngine.QPainter用来执行具体的绘图相关操作如画点,画线,填充,变换,alpha通道等.QPainterDevice是QPainter用来绘图的绘图设备,Qt中有几种预定义的