使用fftw3对图片进行fft2操作

在matlab中有个非常好用的二维傅里叶变换函数fft2,c++没有只能自己重写但是时间效率远远不如matlab,可以通过调用fftw3库来进行fft2函数的重写。

64位编译好的fftw3库:链接:https://pan.baidu.com/s/1-0LYnkh0pNsZCDewk3RS9w 
提取码:zvgz 
 

记得使用fftw3库之前要把环境配好,include、lib都要配好。

fft2方法:

输入 :自定义的复数矩阵src,图片长宽nr和nc以及标识符inverse,当inverse=1时函数为二维傅里叶变换,当inverse=0时函数为二维傅里叶逆变换即为ifft2

输出:傅里叶变换后的复数矩阵dst

void fft2(complex1 **src, complex1 **dst, int nr, int nc, bool inverse)
{
	fftw_complex *signal_img = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nr*nc);
	fftw_complex *out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nr*nc);


	for (int i = 0; i < nr; i++)
	{
		for (int j = 0; j < nc; j++)
		{
			signal_img[i*nc + j][0] = src[i][j].r;
			signal_img[i*nc + j][1] = src[i][j].i;

		}
	}
	fftw_plan signal_forward_plan;
	if (inverse)
	{
		signal_forward_plan = fftw_plan_dft_2d(nr, nc, signal_img, out, FFTW_FORWARD, FFTW_ESTIMATE);
		fftw_execute(signal_forward_plan);
		
		for (int i = 0; i < nr; i++)
		{
			for (int j = 0; j < nc; j++)
			{
				dst[i][j] = complex1(out[i*nc + j][0], out[i*nc + j][1]);
			}
		}
	}
	else
	{
		signal_forward_plan = fftw_plan_dft_2d(nr, nc, signal_img, out, FFTW_BACKWARD, FFTW_ESTIMATE);
		fftw_execute(signal_forward_plan);
		
		for (int i = 0; i < nr; i++)
		{
			for (int j = 0; j < nc; j++)
			{
				dst[i][j] = complex1(out[i*nc + j][0] / (double)(nr*nc), out[i*nc + j][1] / (double)(nr*nc));
			}
		}
		
	}
	fftw_destroy_plan(signal_forward_plan);
	fftw_free(signal_img);
	fftw_free(out);

}

程序主函数

#include <iostream>
#include "opencv2/core/core.hpp"  
#include "opencv2/highgui/highgui.hpp"  
#include "opencv2/imgproc/imgproc.hpp"  
#include<math.h>
#include<fftw3.h>
struct complex1 {
	double r;
	double i;

	complex1(double real = 0, double imag = 0)
	{
		r = real;
		i = imag;
	}
	double abs() { return sqrt(r*r + i * i); }
	complex1 operator-(const complex1 &o) { return complex1(r - o.r, i - o.i); }
	complex1 operator*=(const complex1 &o) {
		return complex1(r * o.r - i * o.i, r*o.i + i * o.r);
	}
	complex1 &operator/=(const double o) {
		r /= o;
		i /= o;
		return *this;
	}
	complex1 &operator+=(const complex1 &o) {
		r += o.r;
		i += o.i;
		return *this;
	}
	complex1 &conj(const complex1 &o)
	{
		r = o.r;
		i = -o.i;
		return *this;
	}
	

};//定义一个复数
int main()
{
     cv::Mat Image_refernce = cv::imread("C:\\Users\\25353\\Desktop\\123\\GF4_PMS_E119.8_N33.7_20160625_L1A0000117115_band_1.tif", cv::IMREAD_UNCHANGED);//输入一张图片,我这是16位深的图片。
    //图像的长宽
	int nr = Image_refernce.rows;
	int nc = Image_refernce.cols;
    complex1 **buf1ft = new complex1*[nr], **x = new complex1*[nr];
	for (int i = 0; i < nr; i++) {
		buf1ft[i] = new complex1[nc];
		x[i] = new complex1[nc];
	}
    for (int i = 0; i < nr; i++) {
		for (int j = 0; j < nc; j++) {
		
			x[i][j] = complex1(Image_refernce.at<ushort>(i, j), 0);//将像素值转换成复数complex1格式
		}
	}
    fft2(x, buf1ft, nr, nc, 1);//二维傅里叶变换
    for (int i = 0; i < nr; i++)
	{
		delete[] buf1ft[i];
		delete[] x[i];
	}
	delete[] buf1ft;
	delete[] x;
	
    return 0;
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要将C++中的fftw3库实现与Matlab中的fft函数相对应,您需要注意以下几点: 1. Matlab中的fft函数默认使用复数(包含实部和虚部)作为输入和输出,而fftw3库默认只支持实数的FFT计算。因此,在使用fftw3库实现FFT时,您需要将实数数组转换成复数数组,或者使用fftw3库中的一些特殊函数(例如fftw_plan_dft_r2c_1d)来实现实数FFT。 2. Matlab中的fft函数默认使用基于2的幂的FFT算法,而fftw3库支持多种FFT算法。因此,在使用fftw3库实现FFT时,您需要选择与Matlab中FFT算法相同的算法。 3. Matlab中的fft函数默认将FFT输出按照频率从小到大排列,而fftw3库默认将FFT输出按照频率从0到n-1排列。因此,在使用fftw3库实现FFT时,您需要将输出数组重新排列。 基于以上几点,以下是一个示例代码,可以在C++中使用fftw3库实现与Matlab中fft函数相对应的FFT计算: ```c++ #include <iostream> #include <fftw3.h> #include <cmath> using namespace std; int main() { int n = 1024; double* in = (double*)fftw_malloc(sizeof(double) * n); fftw_complex* out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * n); // 初始化输入数组 for(int i = 0; i < n; i++) { in[i] = sin(2 * M_PI * i / n); } // 创建计算计划 fftw_plan plan = fftw_plan_dft_r2c_1d(n, in, out, FFTW_ESTIMATE); // 执行计算计划 fftw_execute(plan); // 重新排列输出数组 for(int i = 0; i < n / 2; i++) { double real = out[i][0]; double imag = out[i][1]; out[i][0] = out[i + n / 2][0]; out[i][1] = out[i + n / 2][1]; out[i + n / 2][0] = real; out[i + n / 2][1] = imag; } // 打印输出数组 for(int i = 0; i < n; i++) { cout << out[i][0] << " + " << out[i][1] << "i" << endl; } // 销毁计算计划和数组 fftw_destroy_plan(plan); fftw_free(in); fftw_free(out); return 0; } ``` 在以上代码中,我们使用fftw_plan_dft_r2c_1d函数创建了一个实数FFT的计算计划,使用fftw_execute函数执行计算计划,然后重新排列输出数组,最后打印输出数组。您可以根据您的需求修改输入数组,计算计划的选项,以及处理输出数组的方式。希望能对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值