Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 前向FFT图像和后向FFT图像以获得相同的结果_C++_C_Image Processing_Fft_Fftw - Fatal编程技术网

C++ 前向FFT图像和后向FFT图像以获得相同的结果

C++ 前向FFT图像和后向FFT图像以获得相同的结果,c++,c,image-processing,fft,fftw,C++,C,Image Processing,Fft,Fftw,我正在尝试使用来自的库对图像进行FFT,以便在频域中进行卷积。但我不知道如何让它工作。 为了理解如何做到这一点,我尝试将图像作为像素颜色数组进行前向FFT,然后对其进行后向FFT,以获得相同的像素颜色数组。我是这样做的: fftw_plan planR, planG, planB; fftw_complex *inR, *inG, *inB, *outR, *outG, *outB, *resultR, *resultG, *resultB; //Allocate arrays. inR =

我正在尝试使用来自的库对图像进行FFT,以便在频域中进行卷积。但我不知道如何让它工作。 为了理解如何做到这一点,我尝试将图像作为像素颜色数组进行前向FFT,然后对其进行后向FFT,以获得相同的像素颜色数组。我是这样做的:

fftw_plan planR, planG, planB;
fftw_complex *inR, *inG, *inB, *outR, *outG, *outB, *resultR, *resultG, *resultB;

//Allocate arrays.
inR = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);
inG = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);
inB = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);

outR = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);
outG = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);
outB = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);

resultR = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);
resultG = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);
resultB = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width * width);

//Fill in arrays with the pixelcolors.
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int currentIndex = ((y * width) + (x)) * 3;
        inR[y * width + x][0] = pixelColors[currentIndex];
        inG[y * width + x][0] = pixelColors[currentIndex + 1];
        inB[y * width + x][0] = pixelColors[currentIndex + 2];
    }
}

//Forward plans.
planR = fftw_plan_dft_2d(width, width, inR, outR, FFTW_FORWARD, FFTW_MEASURE);
planG = fftw_plan_dft_2d(width, width, inG, outG, FFTW_FORWARD, FFTW_MEASURE);
planB = fftw_plan_dft_2d(width, width, inB, outB, FFTW_FORWARD, FFTW_MEASURE);

//Forward FFT.
fftw_execute(planR);
fftw_execute(planG);
fftw_execute(planB);

//Backward plans.
planR = fftw_plan_dft_2d(width, width, outR, resultR, FFTW_BACKWARD, FFTW_MEASURE);
planG = fftw_plan_dft_2d(width, width, outG, resultG, FFTW_BACKWARD, FFTW_MEASURE);
planB = fftw_plan_dft_2d(width, width, outB, resultB, FFTW_BACKWARD, FFTW_MEASURE);

//Backward fft
fftw_execute(planR);
fftw_execute(planG);
fftw_execute(planB);

//Overwrite the pixelcolors with the result.
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int currentIndex = ((y * width) + (x)) * 3;
        pixelColors[currentIndex] = resultR[y * width + x][0];
        pixelColors[currentIndex + 1] = resultG[y * width + x][0];
        pixelColors[currentIndex + 2] = resultB[y * width + x][0];
    }
}
fftw\u平面图,平面图,平面图B;
fftw_复合体*inR、*inG、*inB、*outR、*outG、*outB、*resultR、*resultG、*resultB;
//分配数组。
inR=(fftw_复合体*)fftw_malloc(尺寸(fftw_复合体)*宽度*宽度);
inG=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*宽度*宽度);
inB=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*宽度*宽度);
outR=(fftw_复合体*)fftw_malloc(尺寸(fftw_复合体)*宽度*宽度);
outG=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*宽度*宽度);
outB=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*宽度*宽度);
结果=(fftw_复合体*)fftw_malloc(大小(fftw_复合体)*宽度*宽度);
结果=(fftw_复合体*)fftw_malloc(大小(fftw_复合体)*宽度*宽度);
resultB=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*宽度*宽度);
//用像素颜色填充数组。
对于(int y=0;y

有人能给我举个例子,说明如何使用FFTW对图像进行前向FFT,然后对图像进行后向FFT,以获得相同的结果吗?我看了很多例子,展示了如何使用FFTW进行FFT,但我不知道它如何适用于我的情况,我有一个代表图像的像素颜色数组。

在进行前向FFT后再进行逆FFT时,需要注意的一点是,这通常会导致对最终结果应用N的比例因子,即,为了匹配原始像素值,需要将结果图像像素值除以N。(N是FFT的大小。)因此,您的输出循环可能如下所示:

//Overwrite the pixelcolors with the result.
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int currentIndex = ((y * width) + (x)) * 3;
        pixelColors[currentIndex] = resultR[y * width + x][0] / (width * height);
        pixelColors[currentIndex + 1] = resultG[y * width + x][0] / (width * height);
        pixelColors[currentIndex + 2] = resultB[y * width + x][0] / (width * height);
    }
}
//Fill in arrays with the pixelcolors.
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int currentIndex = ((y * width) + (x)) * 3;
        inR[y * width + x][0] = (double)pixelColors[currentIndex];
        inR[y * width + x][1] = 0.0;
        inG[y * width + x][0] = (double)pixelColors[currentIndex + 1];
        inG[y * width + x][1] = 0.0;
        inB[y * width + x][0] = (double)pixelColors[currentIndex + 2];
        inB[y * width + x][1] = 0.0;
    }
}
//用结果覆盖像素颜色。
对于(int y=0;y
还要注意的是,您可能希望先进行实到复的FFT,然后再进行复到实的IFFT(在内存和性能方面都更有效)。目前,虽然看起来您在两个方向上都在进行复杂到复杂的操作,这很好,但您没有正确填充输入数组。如果您要坚持从复杂到复杂,那么您可能希望将输入循环更改为以下内容:

//Overwrite the pixelcolors with the result.
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int currentIndex = ((y * width) + (x)) * 3;
        pixelColors[currentIndex] = resultR[y * width + x][0] / (width * height);
        pixelColors[currentIndex + 1] = resultG[y * width + x][0] / (width * height);
        pixelColors[currentIndex + 2] = resultB[y * width + x][0] / (width * height);
    }
}
//Fill in arrays with the pixelcolors.
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int currentIndex = ((y * width) + (x)) * 3;
        inR[y * width + x][0] = (double)pixelColors[currentIndex];
        inR[y * width + x][1] = 0.0;
        inG[y * width + x][0] = (double)pixelColors[currentIndex + 1];
        inG[y * width + x][1] = 0.0;
        inB[y * width + x][0] = (double)pixelColors[currentIndex + 2];
        inB[y * width + x][1] = 0.0;
    }
}
//用像素颜色填充数组。
对于(int y=0;y
i、 e.像素值进入复数输入值的实部,虚部需要归零


还有一件事需要注意:当你最终完成这项工作时,你会发现性能非常糟糕——相对于实际FFT所花费的时间,创建计划需要很长时间。其思想是只创建一次计划,但使用它执行许多FFT。因此,您需要将平面创建与实际FFT代码分开,并将其放入初始化例程或构造函数或其他任何程序中。

但如果使用realToComplex或Complextore函数,请注意图像将存储在尺寸矩阵中[高度x(宽度/2+1)]如果你想在频域做一些中间计算,它们会变得更难…

它不起作用的原因是fftw_plan_dft_2d()做了一些基准测试,以找到最佳算法并在过程中更改输入数据,因此你必须在fftw_plan_dft_2d()之后而不是之前填充输入数据。

确实如此。另一个选项是使用
FFTW\u估计值
而不是
FFTW\u度量值
,这样数组将不会被覆盖。