fft3d,交换切片,需要转置?

时间:2015-09-29 14:31:36

标签: c++ matlab swap transpose fftw

我需要使用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

1 个答案:

答案 0 :(得分:1)

由于您使用fftshift而缺少ifftshift,因此正在进行交换。我建议您阅读fftshift documentation hereifftshift documentation hereifftshiftfftshift的逆移位操作。如果您使用fftshift移动矢量或矩阵,则应使用ifftshift来取消它或其ifft的输出,反之亦然。在this MathWorks thread中有一个很好的讨论正确的方法。

每次调用ifft时,都应首先使用fftshift移动参数,然后使用ifftshift移动输出以获得正确的结果。使用fft时,您应使用ifftshift移动输入,并使用fftshift移动输出。

如果输入是偶数大小,则这种区别无关紧要,因为在这种情况下fftshiftifftshift是它们自己的反转。但是,您的输入的维度为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