我需要使用fftw库在c ++中执行两步ifft3d。
1st step: a one dimensional ifft across third dimension, creating a "hybrid_kspace"
...
[some operations with hybrid_kspace]
...
2nd step: a two dimensional ifft over horizontal slices of hybrid_kspace.
根据这个(https://cmb.ornl.gov/members/z8g/csproject-report.pdf),我必须进行某种转置操作,但我真的没有这个。
所以我试着在Matlab中研究这个问题,并且发生了一些比较奇怪的事情(参见代码)。第一张和最后一张Clown3D图像被交换了,我不明白为什么。
load clown;
Z=5;
Clown3D=repmat(X,[1,1,Z]);
white=max(Clown3D(:));
Clown3D(100,:,1)=white; %1 white row
Clown3D([70,130],:,2)=white; %2 white row
Clown3D([50 100 150],:,3)=white; %3 white row
Clown3D([40 80 120 160],:,4)=white; %4 white row
Clown3D([30 60 90 120 150],:,5)=white; %5 white row
%Original 3d image
for ii=1:Z
figure, imagesc(Clown3D(:,:,ii)), colormap gray
end
%into fourier space
Kspace=fftshift(fftn(fftshift(Clown3D)));
%2-step ifft3d
K_hybrid3D = fftshift(ifft(fftshift(Kspace,3),[],3),3);
ReconClown3D=zeros(size(Clown3D));
for ii=1:Z
B=squeeze(K_hybrid3D(:,:,ii));
A = fftshift(ifftn(fftshift(B)));
ReconClown3D(:,:,ii)=A;
end
for ii=1:Z
figure, imagesc(abs(ReconClown3D(:,:,ii))), colormap gray
end
%classic ifft3d
ReconClown3DCalssic=fftshift(ifftn(fftshift(Kspace)));
for ii=1:Z
figure, imagesc(abs(ReconClown3DCalssic(:,:,ii))), colormap gray
end
答案 0 :(得分:1)
由于您使用fftshift
而缺少ifftshift
,因此正在进行交换。我建议您阅读fftshift
documentation here和ifftshift
documentation here。 ifftshift
是fftshift
的逆移位操作。如果您使用fftshift
移动矢量或矩阵,则应使用ifftshift
来取消它或其ifft
的输出,反之亦然。在this MathWorks thread中有一个很好的讨论正确的方法。
每次调用ifft
时,都应首先使用fftshift
移动参数,然后使用ifftshift
移动输出以获得正确的结果。使用fft
时,您应使用ifftshift
移动输入,并使用fftshift
移动输出。
如果输入是偶数大小,则这种区别无关紧要,因为在这种情况下fftshift
和ifftshift
是它们自己的反转。但是,您的输入的维度为5,这是导致问题的原因。
由于fft
的不同维度的混合,这对你实施'2步'ifft3d的部分有点冒险。看起来你依次在进行3D fft
,1D ifft
和2D ifft
。我在代码中包含了一个“修复”,但不遵循之前的建议。相反,它使用fftshift
作为3D fft
的输入和输出。
要修复代码,您应修改前面所述的涉及移位的行。结果代码如下:
load clown;
Z=5;
Clown3D=repmat(X,[1,1,Z]);
white=max(Clown3D(:));
Clown3D(100,:,1)=white; %1 white row
Clown3D([70,130],:,2)=white; %2 white row
Clown3D([50 100 150],:,3)=white; %3 white row
Clown3D([40 80 120 160],:,4)=white; %4 white row
Clown3D([30 60 90 120 150],:,5)=white; %5 white row
%Original 3d image
for ii=1:Z
figure, imagesc(Clown3D(:,:,ii)), colormap gray
end
%into fourier space
%this line is kept as is; modifying it causes swapping.
Kspace=fftshift(fftn(fftshift(Clown3D)));
%2-step ifft3d
%Modified to include ifftshift, although it shouldn't matter here
K_hybrid3D = ifftshift(ifft(fftshift(Kspace,3),[],3),3);
ReconClown3D=zeros(size(Clown3D));
for ii=1:Z
B=squeeze(K_hybrid3D(:,:,ii));
%Modified to include ifftshift, although it shouldn't matter here
A = ifftshift(ifftn(fftshift(B)));
ReconClown3D(:,:,ii)=A;
end
for ii=1:Z
figure, imagesc(abs(ReconClown3D(:,:,ii))), colormap gray
end
%classic ifft3d
%Modified to include ifftshift, and it DOES matter here.
ReconClown3DCalssic=ifftshift(ifftn(fftshift(Kspace)));
for ii=1:Z
figure, imagesc(abs(ReconClown3DCalssic(:,:,ii))), colormap gray
end