c代码实现 ifft运算_二维FFT,IFFT,c语言实现 | 学步园
学习DIP第6天
网上关于FFT的实例有很多,具体也可以参照上一篇,其实Matlab,OpenCV都可以很轻松的实现相关操作,但是对于学习其原理,还是自己操作下比较好。
二维FFT的是实现方法是先对行做FFT将结果放回该行,然后再对列做FFT结果放在该列,计算完所有的列以后,结果就是响应的二维FFT。
本次所有操作都是对基2的数据进行的操作。
二维IFFT网上很少见到,操作过程是:上述的傅里叶变换结果,先对每列做一维IFFT,结果放在该列,取复数矩阵其共轭,然后再按照每行做一维IFFT,其结果放在该行,即为最终结果。上代码:
1D.c:
//
// 1D.c
// Fourer
//
// Created by 谭升 on 14/11/25.
// Copyright (c) 2014年 谭升. All rights reserved.
//
#include "Fourer.h"
int isBase2(int size_n){
int k=size_n;
int z=0;
while (k/=2) {
z++;
}
k=z;
if(size_n!=(1<
return -1;
else
return k;
}
//复数基本运算
///
void Add_Complex(Complex * src1,Complex *src2,Complex *dst){
dst->imagin=src1->imagin+src2->imagin;
dst->real=src1->real+src2->real;
}
void Sub_Complex(Complex * src1,Complex *src2,Complex *dst){
dst->imagin=src1->imagin-src2->imagin;
dst->real=src1->real-src2->real;
}
void Multy_Complex(Complex * src1,Complex *src2,Complex *dst){
double r1=0.0,r2=0.0;
double i1=0.0,i2=0.0;
r1=src1->real;
r2=src2->real;
i1=src1->imagin;
i2=src2->imagin;
dst->imagin=r1*i2+r2*i1;
dst->real=r1*r2-i1*i2;
}
void Copy_Complex(Complex * src,Complex *dst){
dst->real=src->real;
dst->imagin=src->imagin;
}
void Show_Complex(Complex * src,int size_n){
if(size_n==1){
if(src->imagin>=0.0)
printf("%lf+%lfj ",src->real,src->imagin);
else
printf("%lf%lfj ",src->real,src->imagin);
}
else if(size_n>1){
for(int i=0;i
if(src[i].imagin>=0.0){
printf("%lf+%lfj ",src[i].real,src[i].imagin);
}
else
printf("%lf%lfj ",src[i].real,src[i].imagin);
}
}
//计算WN
///
void getWN(double n,double size_n,Complex * dst){
double x=2.0*M_PI*n/size_n;
dst->imagin=-sin(x);
dst->real=cos(x);
}
//随机初始化输入
///
void setInput(double * data,int n){
printf("Setinput signal:\n");
srand((int)time(0));
for(int i=0;i
data[i]=rand()%VALUE_MAX;
}
}
//标准DFT
///
void DFT(double * src,Complex * dst,int size){
for(int m=0;m
double real=0.0;
double imagin=0.0;
for(int n=0;n
double x=M_PI*2*m*n;
real+=src[n]*cos(x/size);
imagin+=src[n]*(-sin(x/size));
}
dst[m].imagin=imagin;
dst[m].real=real;
}
}
//IDT,复原傅里叶
///
void IDFT(Complex *src,Complex *dst,int size){
for(int m=0;m
double real=0.0;
double imagin=0.0;
for(int n=0;n
double x=M_PI*2*m*n/size;
real+=src[n].real*cos(x)-src[n].imagin*sin(x);
imagin+=src[n].real*sin(x)+src[n].imagin*cos(x);
}
real/=SIZE;
imagin/=SIZE;
if(dst!=NULL){
dst[m].real=real;
dst[m].imagin=imagin;
}
}
}
//FFT前,对输入数据重新排序
///
int FFTReal_remap(double * src,int size_n){
if(size_n==1)
return 0;
double * temp=(double *)malloc(sizeof(double)*size_n);
for(int i=0;i
if(i%2==0)
temp[i/2]=src[i];
else
temp[(size_n+i)/2]=src[i];
for(int i=0;i
src[i]=temp[i];
free(temp);
FFTReal_remap(src, size_n/2);
FFTReal_remap(src+size_n/2, size_n/2);
return 1;
}
int FFTComplex_remap(Complex * src,int size_n){
if(size_n==1)
return 0;
Complex * temp=(Complex *)malloc(sizeof(Complex)*size_n);
for(int i=0;i
if(i%2==0)
Copy_Complex(&src[i],&(temp[i/2]));
else
Copy_Complex(&(src[i]),&(temp[(size_n+i)/2]));
for(int i=0;i
Copy_Complex(&(temp[i]),&(src[i]));
free(temp);
FFTComplex_remap(src, size_n/2);
FFTComplex_remap(src+size_n/2, size_n/2);
return 1;
}
//FFT公式
///
void FFT(Complex * src,Complex * dst,int size_n){
int k=size_n;
int z=0;
while (k/=2) {
z++;
}
k=z;
if(size_n!=(1<
exit(0);
Complex * src_com=(Complex*)malloc(sizeof(Complex)*size_n);
if(src_com==NULL)
exit(0);
for(int i=0;i
Copy_Complex(&src[i], &src_com[i]);
}
FFTComplex_remap(src_com, size_n);
for(int i=0;i
z=0;
for(int j=0;j
if((j/(1<
Complex wn;
getWN(z, size_n, &wn);
Multy_Complex(&src_com[j], &wn,&src_com[j]);
z+=1<
Complex temp;
int neighbour=j-(1<
temp.real=src_com[neighbour].real;
temp.imagin=src_com[neighbour].imagin;
Add_Complex(&temp, &src_com[j], &src_com[neighbour]);
Sub_Complex(&temp, &src_com[j], &src_com[j]);
}
else
z=0;
}
}
for(int i=0;i
Copy_Complex(&src_com[i], &dst[i]);
}
free(src_com);
}
void RealFFT(double * src,Complex * dst,int size_n){
int k=size_n;
int z=0;
while (k/=2) {
z++;
}
k=z;
if(size_n!=(1<
exit(0);
Complex * src_com=(Complex*)malloc(sizeof(Complex)*size_n);
if(src_com==NULL)
exit(0);
for(int i=0;i
src_com[i].real=src[i];
src_com[i].imagin=0;
}
FFTComplex_remap(src_com, size_n);
for(int i=0;i
z=0;
for(int j=0;j
if((j/(1<
Complex wn;
getWN(z, size_n, &wn);
Multy_Complex(&src_com[j], &wn,&src_com[j]);
z+=1<
Complex temp;
int neighbour=j-(1<
temp.real=src_com[neighbour].real;
temp.imagin=src_com[neighbour].imagin;
Add_Complex(&temp, &src_com[j], &src_com[neighbour]);
Sub_Complex(&temp, &src_com[j], &src_com[j]);
}
else
z=0;
}
}
for(int i=0;i
Copy_Complex(&src_com[i], &dst[i]);
}
free(src_com);
}
//IFFT实现
void IFFT(Complex * src,Complex * dst,int size_n){
for(int i=0;i
src[i].imagin=-src[i].imagin;
FFTComplex_remap(src, size_n);
int z,k;
if((z=isBase2(size_n))!=-1)
k=isBase2(size_n);
else
exit(0);
for(int i=0;i
z=0;
for(int j=0;j
if((j/(1<
Complex wn;
getWN(z, size_n, &wn);
Multy_Complex(&src[j], &wn,&src[j]);
z+=1<
Complex temp;
int neighbour=j-(1<
Copy_Complex(&src[neighbour], &temp);
Add_Complex(&temp, &src[j], &src[neighbour]);
Sub_Complex(&temp, &src[j], &src[j]);
}
else
z=0;
}
}
for(int i=0;i
dst[i].imagin=(1./size_n)*src[i].imagin;
dst[i].real=(1./size_n)*src[i].real;
}
}
2D.c
//
// 2D.c
// Fourer
//
// Created by 谭升 on 14/11/25.
// Copyright (c) 2014年 谭升. All rights reserved.
//
#include "Fourer.h"
/*
*/
int DFT2D(double *src,Complex *dst,int size_w,int size_h){
for(int u=0;u
for(int v=0;v
double real=0.0;
double imagin=0.0;
for(int i=0;i
for(int j=0;j
double I=src[i*size_w+j];
double x=M_PI*2*((double)i*u/(double)size_w+(double)j*v/(double)size_h);
real+=cos(x)*I;
imagin+=-sin(x)*I;
}
}
dst[u*size_w+v].real=real;
dst[u*size_w+v].imagin=imagin;
}
}
return 0;
}
/*
*/
int IDFT2D(Complex *src,Complex *dst,int size_w,int size_h){
for(int i=0;i
for(int j=0;j
double real=0.0;
double imagin=0.0;
for(int u=0;u
for(int v=0;v
double R=src[u*size_w+v].real;
double I=src[u*size_w+v].imagin;
double x=M_PI*2*((double)i*u/(double)size_w+(double)j*v/(double)size_h);
real+=R*cos(x)-I*sin(x);
imagin+=I*cos(x)+R*sin(x);
}
}
dst[i*size_w+j].real=(1./(size_w*size_h))*real;
dst[i*size_w+j].imagin=(1./(size_w*size_h))*imagin;
}
}
return 0;
}
/*
*/
void ColumnVector(Complex * src,Complex * dst,int size_w,int size_h){
for(int i=0;i
Copy_Complex(&src[size_w*i], &dst[i]);
}
/*
*/
void IColumnVector(Complex * src,Complex * dst,int size_w,int size_h){
for(int i=0;i
Copy_Complex(&src[i],&dst[size_w*i]);
}
/*
*/
int FFT2D(double *src,Complex *dst,int size_w,int size_h){
if(isBase2(size_w)==-1||isBase2(size_h)==-1)
exit(0);
Complex *temp=(Complex *)malloc(sizeof(Complex)*size_h*size_w);
if(temp==NULL)
return -1;
for(int i=0;i
RealFFT(&src[size_w*i], &temp[size_w*i], size_w);
}
Complex *Column=(Complex *)malloc(sizeof(Complex)*size_h);
if(Column==NULL)
return -1;
for(int i=0;i
ColumnVector(&temp[i], Column, size_w, size_h);
FFT(Column, Column, size_h);
IColumnVector(Column, &temp[i], size_w, size_h);
}
for(int i=0;i
Copy_Complex(&temp[i], &dst[i]);
free(temp);
free(Column);
return 0;
}
/*
*/
int IFFT2D(Complex *src,Complex *dst,int size_w,int size_h){
if(isBase2(size_w)==-1||isBase2(size_h)==-1)
exit(0);
Complex *temp=(Complex *)malloc(sizeof(Complex)*size_h*size_w);
if(temp==NULL)
return -1;
Complex *Column=(Complex *)malloc(sizeof(Complex)*size_h);
if(Column==NULL)
return -1;
for(int i=0;i
ColumnVector(&src[i], Column, size_w, size_h);
IFFT(Column, Column, size_h);
IColumnVector(Column, &src[i], size_w, size_h);
}
for(int i=0;i
src[i].imagin=-src[i].imagin;
for(int i=0;i
IFFT(&src[size_w*i], &temp[size_w*i], size_w);
}
for(int i=0;i
Copy_Complex(&temp[i], &dst[i]);
free(temp);
free(Column);
return 0;
}
结果:
c代码实现 ifft运算_二维FFT,IFFT,c语言实现 | 学步园相关推荐
- python实现归一化去噪_二维FFT的归一化处理
首先,需要注意的是,这个问题与1D和2D fft之间的差异无关,而是与总功率和平均功率如何随阵列中元素的数量而变化有关.在 当您说9的因子来自a中的元素比b中的元素多9倍时,您说得非常正确.令人困惑的 ...
- 【经典算法实现 44】理解二维FFT快速傅里叶变换 及 IFFT快速傅里叶逆变换(迭代法 和 递归法)
[经典算法实现 44]理解二维FFT快速傅里叶变换 及 IFFT快速傅里叶逆变换(迭代法 和 递归法) 一.二维FFTFFTFFT快速傅里叶变换 公式推导 二.二维FFTFFTFFT 及 IFFTIF ...
- TMS320C6455二维FFT和IFFT实现
目录 FFT原理简介 DSPLib配置 图像数据生成 DSPLib中的FFT和IFFT 二维FFT和IFFT实现 图像分析工具(Image Analyzer) 测试结果 相关资源链接 参考资料: Ra ...
- 二维码简介_二维码基本概念_二维码基本原理
一.二维码简介_二维码基本概念_二维码基本原理 1.二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Ba ...
- C# 传递数组参数_一维数组_二维数组
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 一行代码实现自制炫酷二维码
一行代码实现自制炫酷二维码 文章目录 一行代码实现自制炫酷二维码 一.简介 二.安装模块 三.制作二维码 1.导入模块 2.选择一个链接生成二维码 3.生成动态的二维码 一.简介 现在,二维码十分的普 ...
- wrcoef2函数_二维离散小波变换函数使用总结
前言 地球物理信号不止有地表检波器接收的一维信号!当把检波器排列为一个阵列时,将它们各自记录的信号集合在一起就是一个二维信号.有些背景噪声:在一维信号中体现的是随机性,但有可能在二维信号中就显示出很强 ...
- jquery二维码生成插件_二维码生成器
jquery二维码生成插件_二维码生成器 下载地址:jquery生成二维码.rar 转载于:https://www.cnblogs.com/wifi/articles/3176529.html
- java二维数组扫雷,C语言二维数组实现扫雷游戏
#include //使用二维数组实现 扫雷 int main() { char ui[8][8]={ '+','+','+','+','+','+','+','+', '+','+','+','+' ...
最新文章
- C++中的 c_str() 函数
- Python常用模块之time模块
- java poi doc转docx_Java 插入Word分页符、分节符
- Java基础—序列化底层原理
- 数据库连接池-连接的关闭内幕
- 图片和文件上传js剖析
- JavaScript之eval() 函数
- JAVA并发,线程异常捕获
- python unittest教程_Python Unittest原理及基本使用方法
- 汇编--查找第一个非0字符的五种方法
- python 多and or执行顺序
- 零基础入门语义分割-Task5 模型训练与验证
- mysql库的user表误删除或mysql的管理员密码丢失的解决方法
- 去除TCP/IP筛选
- 今天给同学写5个数据结构算法的题...感觉很有价值的几个题..感兴趣的坐下。。...
- date日期格式化 java,Java日期格式化常用方法
- PPC手机QQ2008 最新版下载
- 机器学习十大算法实现代码汇总(python)----线性回归、逻辑回归、决策树、支持向量机、朴素贝叶斯、K邻近算法、K-均值算法、随机森林、降低维度算法、梯度增强算法
- pink-jQuery
- 进程和线程常见的19个问题
热门文章
- Neo4j技能树学习之路
- java go to语句_Java用()来实现go to语句所特有的一些功能。A.breakB.defaultC.contin...
- 分体式耳机是什么意思?2021年高音质分体式蓝牙耳机推荐
- 局域网内VSS无法连接的一个“恶心他妈给恶心开门”的问题
- 阿ken的HTML、CSS的学习笔记_CSS3选择器(笔记四)
- 魅族2014发布会简单总结
- Android屏幕常亮防息屏
- 如何将交叉引用参考文献批量变为上标
- 解决Windows无法NFS启动imx6ull开发板的问题
- 常用MOSFET管型号