基础知识

复数表示

C = R + jI

极坐标:C = |C|(cosθ + jsinθ)

欧拉公式:C = |C|e

有关更多的时域与复频域的知识可以学习复变函数与积分变换,本篇文章只给出DFT公式,性质,以及实现方法

二维离散傅里叶变换(DFT)

其中f(x,y)为原图像,F(u,v)为傅里叶变换以后的结果,根据欧拉公式可得,每个F(u,v)值都为复数,由实部和虚部组成

代码示例

 void dft(short** in_array, double** re_array, double** im_array, long height, long width)
{
double re, im, temp; for (int i = ; i < height; i++){
for (int j = ; j < width; j++){
re = ;
im = ; for (int x = ; x < height; x++){
for (int y = ; y < width; y++){
temp = (double)i * x / (double)height +
(double)j * y / (double)width;
re += in_array[x][y] * cos(- * pi * temp);
im += in_array[x][y] * sin(- * pi * temp);
}
} re_array[i][j] = re;
im_array[i][j] = im;
}
}
printf("dft done\n");
}

傅里叶谱

相角

功率谱

傅里叶变换频谱图

对于上面得两幅图案,在区间[0, M-1]中,变换数据由两个在点M/2处碰面的背靠背的半个周期组成

针对显示和滤波的目的,在该区间中有一个完整的变换周期更加方便,因为完整周期中数据是连续的

我们希望得到上图所示的图案

傅里叶变换的平移性质

因此对每个f(x, y)项乘以(-1)x+y可达目的

代码示例

 void fre_spectrum(short **in_array, short **out_array, long height, long width)
{
double re, im, temp;
int move; for (int i = ; i < height; i++){
for (int j = ; j < width; j++){
re = ;
im = ; for (int x = ; x < height; x++){
for (int y = ; y < width; y++){
temp = (double)i * x / (double)height +
(double)j * y / (double)width;
move = (x + y) % == ? : -;
re += in_array[x][y] * cos(- * pi * temp) * move;
im += in_array[x][y] * sin(- * pi * temp) * move;
}
} out_array[i][j] = (short)(sqrt(re*re + im*im) / sqrt(width*height));
if (out_array[i][j] > 0xff)
out_array[i][j] = 0xff;
else if (out_array[i][j] < )
out_array[i][j] = ;
}
}
}

执行结果

旋转性质

即f(x, y)旋转一个角度,F(u, v)旋转相同的角度

二维离散傅里叶反变换

代码示例

 void idft(double** re_array, double** im_array, short** out_array, long height, long width)
{
double real, temp; for (int i = ; i < height; i++){
for (int j = ; j < width; j++){
real = ; for (int x = ; x < height; x++){
for (int y = ; y < width; y++){
temp = (double)i * x / (double)height +
(double)j * y / (double)width; real += re_array[x][y] * cos( * pi * temp) -
im_array[x][y] * sin( * pi * temp);
}
} out_array[i][j] = (short)(real / sqrt(width*height));
if (out_array[i][j] > 0xff)
out_array[i][j] = 0xff;
else if (out_array[i][j] < )
out_array[i][j] = ;
}
}
printf("idft done\n");
}

经验证,图像经傅里叶变换,然后再反变换以后可恢复原图

改进

本篇文章只是按照二维离散傅里叶变换公式进行了实现,在测试的过程中发现,执行速度真的是非常慢,算法时间复杂度O(n4),等以后有时间再对这段代码进行优化。

c语言数字图像处理(六):二维离散傅里叶变换的更多相关文章

  1. c语言数字图像处理(二):图片放大与缩小-双线性内插法

    图像内插 假设一幅大小为500 * 500的图像扩大1.5倍到750 * 750,创建一个750 * 750 的网格,使其与原图像间隔相同,然后缩小至原图大小,在原图中寻找最接近的像素(或周围的像素) ...

  2. 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组

    学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...

  3. C语言中如何将二维数组作为函数的参数传递

    今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...

  4. 多尺度二维离散小波重构waverec2

    clc,clear all,close all; load woman; [c,s]=wavedec2(X,2,'haar');%进行2尺度二维离散小波分解.分解小波函数haar %多尺度二维离散小波 ...

  5. 单尺度二维离散小波重构(逆变换)idwt2

    clc,clear all,close all; load woman; %单尺度二维离散小波分解.分解小波函数haar [cA,cH,cV,cD]=dwt2(X,'haar'); %单尺度二维离散小 ...

  6. 多尺度二维离散小波分解wavedec2

    对X进行N尺度小波分解 [C,S]=wavedec2(X,N,'wname'); clc,clear all,close all; load woman; [c,s]=wavedec2(X,2,'db ...

  7. 单尺度二维离散小波分解dwt2

    clc,clear all,close all; load woman; [cA,cH,cV,cD]=dwt2(X,'haar');%单尺度二维离散小波分解.分解小波函数haar figure,ims ...

  8. 混沌数学之CircuitChaotic(二维离散电路混沌系统)

    相关软件参见:混沌数学之离散点集图形DEMO 相关代码: // http://wenku.baidu.com/link?url=yg_gE7LUXCg2mXRp-ZZdfRXXIkcNj8YOhvN7 ...

  9. java、python、golang等开发语言如何快速生成二维码?

    免费二维码生成途径非常多!比如比较有名的草料二维码,如果只是简单的使用,用它就足够了.但是如果想大规模的生成,那就不太合适了.再者很多工具都没办法在二维码中加入logo(像微信二维码一样). 接下来, ...

随机推荐

  1. C++暑期学习笔记

    # C++初步学习笔记 一.命名空间(namespace)相关 1 个人理解: 为了避免整合资源中存在的重名矛盾而采取的区别资源的措施: 2 命名空间的定义: 比如要定义一个命名空间A: namesp ...

  2. 第2次作业——APP的案例分析

    APP的案例分析 网易有道词典APP,使用这个软件有三年之久.唯独最爱的一点就是我每天都能听到不一样的英文歌看到创作歌手的来历,当然偶尔也会有其他国家的歌.起初使用这个软件的目的是用来查单词,每天积累 ...

  3. JDK1.6在LINUX下的安装配置[转]

    JDK1.6在LINUX下的安装是如何进行的呢,让我们开始我们的演示: Ubuntu Linux下jdk的安装与配置 1.JDK1.6安装准备 从sun公司网站www.sun.com下载linux版本 ...

  4. 【转】合格PHP工程师的知识结构

    PHP的运行环境 连环境都搞不起来,就是你有多么喜欢PHP,那也是白搭,开始我们大多会使用集成环境软件例如xampp,wamp.随着知识的增加慢慢要学会自己搭建运行环境,例如 Linux(Ubuntu ...

  5. CVE-2017-8046 复现与分析

    环境搭建 使用的项目为https://github.com/spring-guides/gs-accessing-data-rest.git里面的complete,直接用IDEA导入,并修改pom.x ...

  6. 在任务管理器中显示所有CPU内核性能

    在Windows7"任务管理器"的”性能“选项卡默认显示所有的CPU内核性能 在Windows10中可以通过设置来实现效果

  7. Django输入 中文参数保存异常解决方法

    WEB页面输入中文后保存,出现异常     cmd.exe打印如下信息: UnicodeEncodeError: 'ascii' codec can't encode characters in po ...

  8. java 项目开启mysql binlog参数后报500错误:

    问题: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and ...

  9. c++——inline内联函数

    1 inline内联函数 C++中的const常量可以替代宏常数定义,如: const int A = 3;  #define A 3 C++中是否有解决方案替代宏代码片段呢?(替代宏代码片段就可以 ...

  10. layer关闭当前窗口并刷新父窗口

    window.parent.location.reload(); var index = parent.layer.getFrameIndex(window.name); parent.layer.c ...