fftw 将零频移到图像中心
fftw shift zero-frequency to image center
我正在努力研究应用于图像的 FFTW 结果。
我可以对图像进行傅里叶变换和傅里叶逆变换,我相信这两个函数都能正常工作。现在我正在尝试分析傅里叶变换的结果并尝试对其应用过滤器等
目前我对 FT 结果感到困惑。据我所知,零频率应该在左上角。如果我想检查频率是否友好,我应该将它移到图像中心。我至少测试了两种方法。 FFTW FAQ 网页上描述了一种方法,图像中的所有像素在傅里叶变换之前都乘以 (-1)^(i + j),其中 i 和 j 是像素的索引。
图像乘以(-1)^(i+j)
,则其大小为
但实际上,它应该是这样的(我在imagej中做的)imagej中的傅立叶变换:
我也试过在计算出它的大小后用我的代码来切换它们,但得到了类似的错误结果。
void ftShift2D(double * d, int w, int h)
{
int nw = w/2;
int nh = h/2;
if ( w%2 != 0) {nw++;}
if ( h%2 != 0) {nh++;}
printf("%d, %d\n", nw, nh);
for (int i = 0; i < nh ; i++)
{
for(int j = 0; j < nw; j++)
{
int t1 = i * w + j;
int t2 = (i + nh + 1) * w + j + nw;
swapXY<double>(d[t1], d[t2]);
}
for (int k = nw; k < w; k++)
{
int t1 = i * w + k;
int t2 = (i + nh + 1 ) * w + k - nw;
swapXY<double>(d[t1], d[t2]);
}
}
}
我了解 FFTW 中 FT 结果的布局,如他们网站中所述。
我也检查了输出,这个布局可以确认,只有上半部分有数据,其余为0。因此,似乎解释了为什么上面使用的两种方法不起作用。我正在尝试设计新方法将零频率移动到图像中心。你能给我一个更好的方法吗?
我坚持这个,旨在使用过滤器,这样会更容易理解。如果零频没有移到中心,你们能不能给我另一个建议,比如我可以在频域上对其应用高斯滤波器。
非常感谢。
输入图像是:
FT和IFT代码为
void Imgr2c(double * d, fftw_complex * df, int w, int h)
{
fftw_plan p = fftw_plan_dft_r2c_2d(h, w, d, df, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void Imgc2r(fftw_complex * in, double * ftReverse, int w, int h)
{
fftw_plan p = fftw_plan_dft_c2r_2d(h, w, in, ftReverse, FFTW_ESTIMATE);
fftw_execute(p);
int l = w * h;
for (int i = 0; i < l; i++)
{
ftReverse[i] /= l;
}
fftw_destroy_plan(p);
}
[Spektre 编辑]
大致应该是这样的:
你可能想看看我是怎么做到的:
https://github.com/kvahed/codeare/blob/master/src/matrix/ft/DFT.hpp
完成这项工作的功能在底部。如果有任何问题,请随时与我私下联系。
我找到我的问题了!我没有深入了解FFTW中DFT的输出布局。经过一些测试,我发现宽度尺寸应该w/2+∀1,而高度尺寸没有改变。执行 FT、IFT 和移动原点的代码没有问题。我需要做的是在尝试访问时更改维度。
magnitude after DFT
magnitude after shifting the origin
干杯,
药网
我正在努力研究应用于图像的 FFTW 结果。
我可以对图像进行傅里叶变换和傅里叶逆变换,我相信这两个函数都能正常工作。现在我正在尝试分析傅里叶变换的结果并尝试对其应用过滤器等
目前我对 FT 结果感到困惑。据我所知,零频率应该在左上角。如果我想检查频率是否友好,我应该将它移到图像中心。我至少测试了两种方法。 FFTW FAQ 网页上描述了一种方法,图像中的所有像素在傅里叶变换之前都乘以 (-1)^(i + j),其中 i 和 j 是像素的索引。
图像乘以(-1)^(i+j)
,则其大小为
但实际上,它应该是这样的(我在imagej中做的)imagej中的傅立叶变换:
我也试过在计算出它的大小后用我的代码来切换它们,但得到了类似的错误结果。
void ftShift2D(double * d, int w, int h)
{
int nw = w/2;
int nh = h/2;
if ( w%2 != 0) {nw++;}
if ( h%2 != 0) {nh++;}
printf("%d, %d\n", nw, nh);
for (int i = 0; i < nh ; i++)
{
for(int j = 0; j < nw; j++)
{
int t1 = i * w + j;
int t2 = (i + nh + 1) * w + j + nw;
swapXY<double>(d[t1], d[t2]);
}
for (int k = nw; k < w; k++)
{
int t1 = i * w + k;
int t2 = (i + nh + 1 ) * w + k - nw;
swapXY<double>(d[t1], d[t2]);
}
}
}
我了解 FFTW 中 FT 结果的布局,如他们网站中所述。 我也检查了输出,这个布局可以确认,只有上半部分有数据,其余为0。因此,似乎解释了为什么上面使用的两种方法不起作用。我正在尝试设计新方法将零频率移动到图像中心。你能给我一个更好的方法吗?
我坚持这个,旨在使用过滤器,这样会更容易理解。如果零频没有移到中心,你们能不能给我另一个建议,比如我可以在频域上对其应用高斯滤波器。
非常感谢。
输入图像是:
FT和IFT代码为
void Imgr2c(double * d, fftw_complex * df, int w, int h)
{
fftw_plan p = fftw_plan_dft_r2c_2d(h, w, d, df, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
}
void Imgc2r(fftw_complex * in, double * ftReverse, int w, int h)
{
fftw_plan p = fftw_plan_dft_c2r_2d(h, w, in, ftReverse, FFTW_ESTIMATE);
fftw_execute(p);
int l = w * h;
for (int i = 0; i < l; i++)
{
ftReverse[i] /= l;
}
fftw_destroy_plan(p);
}
[Spektre 编辑]
大致应该是这样的:
你可能想看看我是怎么做到的: https://github.com/kvahed/codeare/blob/master/src/matrix/ft/DFT.hpp 完成这项工作的功能在底部。如果有任何问题,请随时与我私下联系。
我找到我的问题了!我没有深入了解FFTW中DFT的输出布局。经过一些测试,我发现宽度尺寸应该w/2+∀1,而高度尺寸没有改变。执行 FT、IFT 和移动原点的代码没有问题。我需要做的是在尝试访问时更改维度。
magnitude after DFT
magnitude after shifting the origin 干杯,
药网