//编辑...

我稍微编辑我的问题,以解决专门使用两种图像的工作问题。我有一个基本结构,它适用于平方灰度图像,尺寸为256x256或1024x1024,但看不到如何概括为任意大小的图像。 FFT函数似乎希望您包含宽度和高度的log2,但是它不清楚如何解压缩结果数据,或者数据不只是扰乱。我想要做明显的事情是将NPOT图像中置于较大的黑色图像中,然后在查看数据时忽略这些位置中的任何值。但想知道是否有一个不太尴尬的方式与NPOT数据一起使用。

// ...结束编辑

我对加速框架文档有点麻烦。我通常会使用fftw3,但我无法在实际的iOS设备上编译它(请参阅它问题)。任何人都可以使用加速器指向超级简单的实现,这与以下内容相同:

1)将图像数据转换为可以传递以加速FFT方法的适当数据结构。
在FFTW3中,在最简单的情况下,使用灰度图像,这涉及将无符号字节放入“FFTW_COMPLEX”阵列中,这只是两个浮点数的结构,一个保持真实值,另一个浮动,另一个浮动(以及虚构的位置每个像素初始化为零)。

2)采用此数据结构并对其执行FFT。

3)打印出幅度和相位。

4)对其执行IFFT。

5)从IFFT的数据中重新创建原始图像。

虽然这是一个非常基本的例子,但我无法使用Apple网站的文档遇到问题。所以在这里的pi答案非常有用,但我仍然是有些困惑如何使用加速来使用灰度(或颜色)2D图像来执行此基本功能。

无论如何,任何指针或尤其是处理2D图像的简单工作代码都会非常有帮助!

\\\编辑\\\

好的,在花一段时间后潜入文档和一些非常有用的代码以及 pkmital的github repo ,我有一些工作代码,我以为我发布的1)我花了一段时间来弄明白,因为我有几个剩下的问题...

初始化FFT“计划”。假设平方电源 - 两个图像:

#include <Accelerate/Accelerate.h>
...
UInt32 N = log2(length*length);
UInt32 log2nr = N / 2; 
UInt32 log2nc = N / 2;
UInt32 numElements = 1 << ( log2nr + log2nc );
float SCALE = 1.0/numElements;
SInt32 rowStride = 1; 
SInt32 columnStride = 0;
FFTSetup setup = create_fftsetup(MAX(log2nr, log2nc), FFT_RADIX2);
.

以字节数组传递到一个平方电源 - 两个灰度映像,并将其转换为复杂的_split:

COMPLEX_SPLIT in_fft;
in_fft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
in_fft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );

for ( UInt32 i = 0; i < numElements; i++ ) {
    if (i < t->width * t->height) {
      in_fft.realp[i] = t->data[i] / 255.0;
      in_fft.imagp[i] = 0.0;
    }
}
.

在变换图像数据上运行FFT,然后抓住幅度和相位:

COMPLEX_SPLIT out_fft;
out_fft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
out_fft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );

fft2d_zop ( setup, &in_fft, rowStride, columnStride, &out_fft, rowStride, columnStride, log2nc, log2nr, FFT_FORWARD );

magnitude = (float *) malloc(numElements * sizeof(float));
phase = (float *) malloc(numElements * sizeof(float));

for (int i = 0; i < numElements; i++) {
   magnitude[i] = sqrt(out_fft.realp[i] * out_fft.realp[i] + out_fft.imagp[i] * out_fft.imagp[i]) ;
   phase[i] = atan2(out_fft.imagp[i],out_fft.realp[i]);
}
. 现在,您可以在Out_FFT数据上运行IFFT以获取原始图像...

COMPLEX_SPLIT out_ifft;
out_ifft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
out_ifft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
fft2d_zop (setup, &out_fft, rowStride, columnStride, &out_ifft, rowStride, columnStride, log2nc, log2nr, FFT_INVERSE);   

vsmul( out_ifft.realp, 1, SCALE, out_ifft.realp, 1, numElements );
vsmul( out_ifft.imagp, 1, SCALE, out_ifft.imagp, 1, numElements );
.

或者您可以在幅度上运行IFFT以获取自相关...

COMPLEX_SPLIT in_ifft;
in_ifft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
in_ifft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
for (int i = 0; i < numElements; i++) {
  in_ifft.realp[i] = (magnitude[i]);
  in_ifft.imagp[i] = 0.0;
}

fft2d_zop ( setup, &in_fft, rowStride, columnStride, &out_ifft, rowStride, columnStride, log2nc, log2nr, FFT_INVERSE );      

vsmul( out_ifft.realp, 1, SCALE, out_ifft.realp, 1, numElements );
vsmul( out_ifft.imagp, 1, SCALE, out_ifft.imagp, 1, numElements );
.

最后,您可以将IFFT结果放回图像阵列:

for ( UInt32 i = 0; i < numElements; i++ ) {
  t->data[i] = (int) (out_ifft.realp[i] * 255.0);
}     
.

我还没有想出如何使用加速框架来处理非功率的图像。如果我在设置中分配足够的内存,那么我可以执行FFT,然后是IFFT获取我的原始图像。但是,如果尝试进行自相关(具有FFT的幅度),那么我的图像会得到旺盛的结果。我不确定适当地填充图像的最佳方式,所以希望有人知道如何做到这一点。 (或共享VDSP_CONV方法的工作版本!)

有帮助吗?

解决方案

我会说为了在任意图像大小上执行工作,您必须做的就是适当地将输入值阵列尺寸尺寸为2。

硬部分是将原始图像数据和填写的内容放置的位置。您真正尝试从图像到图像或数据我的数据至关重要。

在下面的联系PDF中,特别注意段落高于12.4.2 http://www.mathcs.org/java/programs/fft /fftinfo/c12-4.pdf

虽然上面谈到沿着2个轴的操纵,我们可以在第二维尔之前和追随第二维度之前的类似思路。如果我是正确的,那么这个例子可以应用(这绝不是一个精确的算法):

假设我们有一个900到900的图像: 首先,我们可以将图像分成512,256,128和4的垂直条带。 然后,我们将处理每行4 1d FFT,一个用于前512像素,下一个用于以下256像素,下次为128,然后剩下的最后128个。由于FFT的输出基本上是流行的频率,然后可以简单地添加这些(从频率仅透视,而不是角偏移)。 然后我们可以向第二个维度推动相同的技术。此时我们将考虑每个输入像素而无需实际填充。

这真的只是为了思想的食物,我还没有尝试过这个,确实应该自己研究这个。如果你现在真的在做这种工作,那么你可能有更多的时间就是这一点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top