单变量离散傅里叶变换DFT原理及实现

        一、单变量离散傅里叶变换

              离散傅里叶变换公式:

                                                   F(\mu )=\sum_{t=0}^{n}f(t)e^{-j2\pi \mu t/n}

              根据公式,单变量离散傅里叶变是换将一维数组变换为傅里叶频率。设定一个大小为N的数组,t为X轴上的变量,取值为[0,n-1],f(t)为t=x出的值,计算机处理时,t即为输入数组下标index,f(t)为index对应位置数组中的值。

              当μ=0时:

                                                   F(\mu )=\sum_{t=0}^{n}f(t)

             相当于整个输入数组直接求和。由于傅里叶变换计算涉及复数,可以将输入数组变换为复数形式,f(t)作为复数实部,虚部为0。根据欧拉公式:

                                                  e^{j\theta }=cos\theta +jsin\theta

            在进行实际使用时,可将傅里叶变换为如下形式:

                                                  F(\mu )=\sum_{t=0}^{n}f(t)[cos(2\pi \mu t/n)-jsin(2\pi \mu t/n)]

            由于j为虚数,在实际计算过程中j=√-1是没有代入的,只需要计算复数的实部和虚数实部即可。

            傅里叶变换核心代码:

           

public Complex[] dft(Complex[] C) {
		int n = C.length;
		if (n == 1) {
			return C;
		}
		Complex[] result = new Complex[n];
		for (int i = 0; i < n; i++) {
			result[i] = new Complex(0, 0);
			for (int j = 0; j < n; j++) {
				double p = -2 * i * j * Math.PI / n;
				Complex m = new Complex(Math.cos(p), Math.sin(p));
				result[i] = result[i].add(C[j].multiply(m));
			}
		}
		return result;
	}

            代码中,i相当于公式中的μ,j相当于t。

        二、中心化

              为了便于分析和操作需要将输入数组进行中心化,中心化公式:f’(t) = f(t)*(-1)t,即根据数组下标奇偶数,将下标为奇数的数乘以-1,把整个数组分为以0为中心的数组序列。

             中心化代码:

             

public Complex[] dftShift(Complex[] C) {
		int n = C.length;
		Complex[] result = new Complex[n];
		for(int i = 0; i < n; i++) {
			Complex m = new Complex(Math.pow(-1, i),0);
			result[i] = C[i].multiply(m);
		}
		return result;
	}

        三、傅里叶谱

               傅里叶谱,即傅里叶变换后的频谱图,频谱计算也就是计算复数模长。

               复数模长计算公式:|C|=a2+b2

        四、逆傅里叶变换

             

逆傅里叶变换公式:

                                                 F(\mu )=1/n\sum_{t=0}^{n}f(t)e^{-j2\pi \mu t/n}

            傅里叶变换本质上就是把数据从时域/空间域变换到频率域,而逆傅里叶变换就是把数据再从频率域变换回时域/空间域。

            逆傅里叶变换实现代码:

            

public Complex[] iDFT(Complex[] C) {
		int n = C.length;
		if (n == 1) {
			return C;
		}
		Complex[] result = new Complex[n];
		for (int i = 0; i < n; i++) {
			result[i] = new Complex(0, 0);
			for (int j = 0; j < n; j++) {
				double p = 2 * i * j * Math.PI / n;
				Complex m = new Complex(Math.cos(p), Math.sin(p));
				result[i] = result[i].add(C[j].multiply(m));
			}
			result[i] = new Complex(result[i].getRealPart() / n, result[i].getImaginePart() / n);
		}
		return result;
	}

      五、离散傅里叶变换实现代码

public class DFT {
	/**
	 * 计算离散傅里叶变换
	 * 
	 * @param x
	 * @return
	 */
	public Complex[] dft(Complex[] C) {
		int n = C.length;
		if (n == 1) {
			return C;
		}
		Complex[] result = new Complex[n];
		for (int i = 0; i < n; i++) {
			result[i] = new Complex(0, 0);
			for (int j = 0; j < n; j++) {
				double p = -2 * i * j * Math.PI / n;
				Complex m = new Complex(Math.cos(p), Math.sin(p));
				result[i] = result[i].add(C[j].multiply(m));
			}
		}
		return result;
	}

	/**
	 * 逆离散傅里叶变换
	 * 
	 * @param C
	 * @return
	 */
	public Complex[] iDFT(Complex[] C) {
		int n = C.length;
		if (n == 1) {
			return C;
		}
		Complex[] result = new Complex[n];
		for (int i = 0; i < n; i++) {
			result[i] = new Complex(0, 0);
			for (int j = 0; j < n; j++) {
				double p = 2 * i * j * Math.PI / n;
				Complex m = new Complex(Math.cos(p), Math.sin(p));
				result[i] = result[i].add(C[j].multiply(m));
			}
			result[i] = new Complex(result[i].getRealPart() / n, result[i].getImaginePart() / n);
		}
		return result;
	}
	
	//中心化
	public Complex[] dftShift(Complex[] C) {
		int n = C.length;
		Complex[] result = new Complex[n];
		for(int i = 0; i < n; i++) {
			Complex m = new Complex(Math.pow(-1, i),0);
			result[i] = C[i].multiply(m);
		}
		return result;
	}
}

            测试代码:

public static void main(String[] args) throws Exception{
		File in = new File("E:\\桌面\\1.jpg");
		File out = new File("E:\\桌面\\4.txt");
		BufferedImage image = ImageIO.read(in);
		int width = image.getWidth();
		int height = image.getHeight();
		int length = width * height;
		Complex[] C = new Complex[length];
//将二维图片转为一维数组
		for(int i = 0; i < width; i++) {
			for(int j = 0; j < height; j++) {
				int rgb = image.getRGB(i, j);
				int index = i * height + j;
				C[index] = new Complex(rgb & 0xff, 0);
			}
		}
		C = new DFT().dftShift(C);//中心化
		Complex[] result = new DFT().dft(C);
		Writer writer = new FileWriter(out);
		for(int i = 0; i < length; i++) {
			writer.write(Double.toString(result[i].absValue()));//计算频谱
			writer.write("\r\n");
		}
		writer.close();
}

            测试图像:

           频谱图:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 在MATLAB中,可以使用`fft`函数来实现离散傅里变换DFT),其中`fft`函数的输入为一个向量或矩阵,输出为相应的DFT结果。 具体实现步骤如下: 1. 首先,将输入信号x转换为长度为N的向量,其中N为DFT的长度。如果x的长度小于N,则可以使用MATLAB中的`padarray`函数在后面补零,使其长度达到N。 2. 对转换后的向量x应用`fft`函数,得到DFT结果X。 3. 由于DFT的输出结果是复数,因此可以使用`abs`函数计算X的幅值谱,使用`angle`函数计算X的相位谱。 下面是一个实现示例: ```matlab % 定义输入信号x x = [1 2 3 4]; % 定义DFT的长度N N = 8; % 在x后面补零,使其长度达到N x_padded = padarray(x, [0 N-length(x)], 0, 'post'); % 计算x_padded的DFT结果X X = fft(x_padded); % 计算X的幅值谱和相位谱 X_abs = abs(X); X_phase = angle(X); ``` 该代码会输出X的幅值谱和相位谱。注意,由于DFT的对称性,只需要输出前一半结果即可。 ### 回答2: 在MATLAB中使用离散傅里变换(Discrete Fourier Transform, DFT)进行频域分析,可以按照以下步骤实现: 1. 首先,需要定义输入信号。可以使用MATLAB提供的函数来生成或加载信号。例如,可以使用`sin`或`cos`函数生成一个正弦波信号,或使用`audioread`函数加载一个音频文件。 2. 接下来,使用MATLAB提供的`fft`函数计算离散傅里变换。`fft`函数接受一个向量作为输入,并返回变换后的频谱。可以使用快速傅里变换(Fast Fourier Transform, FFT)算法来进行计算,这样可以提高计算速度。 3. 可以选择对变换后的频谱进行幅度谱或相位谱分析,或者对频谱进行滤波、谱估计等操作,以实现不同的信号处理目标。 4. 最后,可以使用`ifft`函数进行逆变换,将频域信号重新转换为时域信号。逆变换的结果将与输入信号相同。 需要注意的是,MATLAB中的`fft`函数默认使用基2的FFT算法,如果输入信号的长度不是2的幂次方,会进行零填充。如果需要指定变换点数,可以使用`fft`函数的参数进行设置。此外,还可以使用`fftshift`函数将频谱重新排序,使得频谱的零频率位于中心位置。 总之,MATLAB提供了强大的信号处理工具箱,通过使用离散傅里变换和相关函数,可以实现信号的频域分析和处理。 ### 回答3: 离散傅里变换(DFT)是一种将时域信号转换为频域信号的数学工具。它在数字信号处理和频谱分析中具有广泛的应用。MATLAB是一种流行的科学计算软件,可以用于编写和执行数学和工程计算。 要在MATLAB中实现离散傅里变换,可以使用MATLAB内置的函数fft。以下是一个简的示例代码: ```matlab % 输入信号 x = [1, 2, 3, 4]; % 计算离散傅里变换 X = fft(x); % 输出变换结果 disp(X); ``` 在这个示例中,我们定义了一个输入信号x,它是一个包含4个元素的向量。然后,我们使用fft函数对输入信号进行离散傅里变换,将结果存储在变量X中。最后,我们使用disp函数输出变换结果。 要注意的是,离散傅里变换的结果是一个复数向量,其中包含了信号的频域表示。实部表示信号幅度,虚部表示信号相位。 通过使用MATLAB的fft函数,我们可以方便地实现离散傅里变换,并获得信号在频域的表示。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TheMatrixs

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值