C++实现离散傅里叶变换,附源代码

本文探讨了一维离散傅立叶变换(DFT)和快速傅里叶变换(FFT)的高效实现,包括中心化技巧的优化、算法选择、一维DFT函数的自定义和FFT的选用。通过实例展示了如何处理图像频谱,涉及线性拉伸和对数变换,以及空域与频谱的对应关系和对数变换的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.函数调用

在这里插入图片描述

2.算法设计

2.1中心化

实现中心化的代码块中不使用pow函数,使用位运算判断奇偶,可大大优化。

//中心化
for(band=0;band<n_band;band++)
	for(row=0; row<n_row; ++row){
		for(col=0; col<n_col; ++col){
			index=coo2ind(band,row,col);
			complex_data[index]=input_data[index]*(((row*col)&(0x01))?-1:1);//此处不用pow函数,可大大优化
			}
		}

2.2 选择DFT还是FFT

由于对话框中可以选择是否采用快速傅里叶变换(FFT),所以在此处定义函数指针,选择是采用DFT还是FFT。

//选择是否采用FFT
	void (*dft_fun)(vector<complex<double>>&, bool);
	if (isFFT)
		dft_fun = FFT::fft;
	else
		dft_fun = MyDFT::dft;

2.3一维DFT

一维DFT函数由自己实现的,核心代码如下:

void MyDFT::dft(std::vector<std::complex<double>>& vec, bool inverse)
{
	size_t n = vec.size();
	vec_copy.assign(vec.begin(), vec.end());

	std::complex<double> temp;
	for (size_t i = 0; i < n; ++i)
	{
		temp=0;
		for (size_t j = 0; j < n; ++j)
		{
			temp += vec_copy[j] * std::polar(1.0,(inverse?1:-1)*2*PI*i*j/n);//由欧拉公式
		}
		vec[i] = (inverse ? temp/(double)n : temp);
	}
}

完整代码https://blog.csdn.net/qq_20115319/article/details/111998342
函数参数bool inverse控制是否为反变换,这样一个DFT函数可同时处理正变换和反变换,提高了代码重用率。
由欧拉公式可得:e^iθ=cos⁡θ +i×sinθ
在傅里叶变换中将θ=-2πxy/N代入上面欧拉公式,即有上面注释一行的形式。

2.4一维FFT

一维FFT的代码来源于https://www.nayuki.io/page/free-small-fft-in-multiple-languages

2.5 处理结果

原图
在这里插入图片描述

频谱线性拉伸
在这里插入图片描述

频谱对数变换结果

在这里插入图片描述

2.6 结果讨论

解释:①对数变换能使频谱显示效果更好的原因;②空域图像与频谱图的对应关系。

① 傅里叶变换的频谱值的范围通常为[0,106],相比于线性拉伸,对数变换能够将更多较小的灰度值映射到较大的亮度显示。
② 频率域的方向性体现为与空域中灰度变化的方向垂直。空域图中空域边缘部分和细节对应频域的高频分量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值