c语言数字图像处理(六):二维离散傅里叶变换
基础知识
复数表示
C = R + jI
极坐标:C = |C|(cosθ + jsinθ)
欧拉公式:C = |C|ejθ
有关更多的时域与复频域的知识可以学习复变函数与积分变换,本篇文章只给出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语言数字图像处理(六):二维离散傅里叶变换的更多相关文章
- c语言数字图像处理(二):图片放大与缩小-双线性内插法
图像内插 假设一幅大小为500 * 500的图像扩大1.5倍到750 * 750,创建一个750 * 750 的网格,使其与原图像间隔相同,然后缩小至原图大小,在原图中寻找最接近的像素(或周围的像素) ...
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- 多尺度二维离散小波重构waverec2
clc,clear all,close all; load woman; [c,s]=wavedec2(X,2,'haar');%进行2尺度二维离散小波分解.分解小波函数haar %多尺度二维离散小波 ...
- 单尺度二维离散小波重构(逆变换)idwt2
clc,clear all,close all; load woman; %单尺度二维离散小波分解.分解小波函数haar [cA,cH,cV,cD]=dwt2(X,'haar'); %单尺度二维离散小 ...
- 多尺度二维离散小波分解wavedec2
对X进行N尺度小波分解 [C,S]=wavedec2(X,N,'wname'); clc,clear all,close all; load woman; [c,s]=wavedec2(X,2,'db ...
- 单尺度二维离散小波分解dwt2
clc,clear all,close all; load woman; [cA,cH,cV,cD]=dwt2(X,'haar');%单尺度二维离散小波分解.分解小波函数haar figure,ims ...
- 混沌数学之CircuitChaotic(二维离散电路混沌系统)
相关软件参见:混沌数学之离散点集图形DEMO 相关代码: // http://wenku.baidu.com/link?url=yg_gE7LUXCg2mXRp-ZZdfRXXIkcNj8YOhvN7 ...
- java、python、golang等开发语言如何快速生成二维码?
免费二维码生成途径非常多!比如比较有名的草料二维码,如果只是简单的使用,用它就足够了.但是如果想大规模的生成,那就不太合适了.再者很多工具都没办法在二维码中加入logo(像微信二维码一样). 接下来, ...
随机推荐
- php 上传大文件主要涉及配置upload_max_filesize和post_max_size两个选项。
今天在做上传的时候出现一个非常怪的问题,有时候表单提交可以获取到值,有时候就获取不到了,连普通的字段都获取不到了,苦思冥想还没解决,群里人问我upload_max_filesize的值改了吗,我说改了 ...
- 代码覆盖率测试及 GitHub 自动化集成
本文对应项目为 learn-coverage-test,可以对照项目案例进行阅读. 覆盖率测试 在写代码的时候,我们有时候会进行代码测试以保证我们代码的可执行性.但是测试代码只能保证测试案例能够通过, ...
- PHPExcel 导入
首先: //包含excel的类库require APPPATH . 'third_party/PHPExcel.php';require APPPATH . 'third_party/PHPExcel ...
- 2339: [HNOI2011]卡农
Description 首先去除顺序不同算一种的麻烦,就是最后答案除以总片段数\(2^m-1\) 设\(f_i\)表示安排\(i\)个片段的合法种类 那么对于任何一个包含\(i-1\)个片段的序列(除 ...
- Day9 JSP
JSP概述 JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP实际上就是Servlet. jsp = html + ...
- python基础整理7——爬虫——爬虫开发工具
HTTP代理神器Fiddler Fiddler是一款强大Web调试工具,它能记录所有客户端和服务器的HTTP请求. Fiddler启动的时候,默认IE的代理设为了127.0.0.1:8888,而其他浏 ...
- Linux搜索查找命令
Linux搜索查找指令 find,用于在文件树中查找文件并作相应的处理 -name:按照文件名查找文件 -perm:按照文件权限查找文件 -user:按照文件属主来查找文件 -size:按照指定的文件 ...
- [整理记录备忘]oracle数据库相关问题与解决
检查死锁方式 用dba用户执行以下语句,可以查看到被死锁的语句. select sql_text from v$sql where hash_value in (select sql_hash_val ...
- git 代码分支合并merge提交新修改远程以及本地分支
第一步:创建本地分支 点击右键选择TortoiseGit,选择Create Branch…,在Branch框中填写新分支的名称(若选中”switch to new branch”则直接转到新分支上,省 ...
- java面向对象之个人总结
面向对象有三大特性:继承,封装,多态 1.继承: (1)继承的特点:A,java支持单根继承,不支持多根继承 B,java支持多层继承(继承体系) (2)细节注意:A.子类只能继承父类的非私有成员(成 ...