我正在使用矩阵乘法在Matlab中实现2D离散傅里叶变换。
我意识到这可以是一个可分离的操作,所以我创建了一维DFT的矩阵,并将其与输入图像的列相乘,然后与图像的行相乘。
然而,得到的2D DFT的值与使用MATLAB中的内置函数(即fft2
)计算的DFT有很大差异。因此,当执行逆DFT以重新创建图像时,所得到的图像不能正确地重建(即,它与原始图像不同,但如果我使用fft2
函数则它是相同的)。
这是我写的代码。
%% signal is a matrix of MxN size
function res=myDFT(signal)
signal=double(signal);
l=size(signal,1);
x=[1:l];
%% u and x are matrices of MxM size
[x u]=meshgrid(x,x);
M1=l-1;
pre_dft=exp(1i*(-2*pi)./M1)/sqrt(M1);
pre_dft=(pre_dft.^(u.*x));
%the below matrix will be multiplied with the rows of the signal
post_dft=pre_dft;
% res is the resultant DFT of the signal matrix
% 1D DFT matrix is first multiplied with columns and then the
% rows of signal matrix
res=pre_dft*signal*post_dft;
end
如果有人可以指出编辑我的代码有用的任何内容或指出我理论上的理解中存在缺陷,我将非常感激。
答案 0 :(得分:1)
好的,你有一些我们需要解决的错误...如果你希望这个工作与fft2
在MATLAB中的工作方式完全一样。
fft
且最终fft2
有无规范化因子。在计算DFT矩阵的第一部分时,您可以删除该除法语句。此外,DFT矩阵的第一部分,在指数中,您需要除以信号的总长度,而不是除以1的长度。
您计算从{1}到meshgrid
的{{1}},但是电源操作要求您从l
开始。因此,在进行功效计算之前,您需要将0
和u
减去1。
正如您已经注意到的,2D FFT是可分离的,可以通过首先对行执行1D FFT,然后是列来完成。不幸的是,您正在进行的操作并不正确。 x
需要转置,因为您希望在列上应用生成的中间操作。
因此,对于我上面提到的所有修正,您更正的代码是:
post_dft
使用一些随机数据测试上述内容,并与function res=myDFT(signal)
signal=double(signal);
l=size(signal,1);
x=[1:l];
[x, u]=meshgrid(x,x);
%// Error #1
pre_dft=exp(1i*(-2*pi)./l); %// Change
%// Error #2
pre_dft=(pre_dft.^((u-1).*(x-1))); %// Change
%// Error #3
post_dft = pre_dft.'; %// Change
res = pre_dft*signal*post_dft;
end
进行比较:
fft2
rng(123123);
in = rand(7);
out1 = myDFT(in);
out2 = fft2(in);
包含已更正的自定义实现,而out1
包含MATLAB的out2
算法的结果。我们得到:
fft2
对我来说很好看!