FFTW错误的2D图像反向变换[有Qt]

时间:2017-03-30 10:08:30

标签: c++ qt fft fftw ifft

我在Qt中创建了一个应用程序,它允许我打开图像并使用FFTW库进行2D FFT变换。问题是我无法通过反向转换检索正确的像素值。但是,让我们从开始开始吧。

这就是我使用

的FFTW功能
void FFTInterface::FFTW(int rows, int cols, QColor **imageInput,fftw_complex * in, fftw_complex * out)
{
    fftw_plan g;

    g = fftw_plan_dft_2d(rows, cols, in, out, FFTW_FORWARD, FFTW_MEASURE);

    int k = 0;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            in[k][0] = imageInput[i][j].red();
            in[k][1] = 0.0;
            k++;
         }
     }
     fftw_execute(g);
     fftw_destroy_plan(g);
}

rows,cols 是图片的大小, imageInput 是QColor的数组,它保留像素值(灰度), out 是fftw_complex,输入和输出数组的对象。

这个函数给我一些结果,必须显示。要做到这一点,我做了一些scalling。首先,我对每个值使用abs()函数,以确保它具有正值。之后,我缩放结果。

void FFTInterface::Abs(fftw_complex *out, int rows, int cols)
{
    int k = 0;
    for(int i = 0; i < rows; i++){
        for(int j = 0; j<cols; j++){
            out[k][0] = abs(out[k][0]);
            out[k][1] = abs(out[k][1]);
            k++;
        }
    }
}
void FFTInterface::Scale(fftw_complex * in,int rows, int cols)
{
    float c = 255.0 / log(1+Max(in,rows,cols));

    int k = 0;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            in[k][0] = c*log(1+in[k][0]);
            in[k][1] = c*log(1+in[k][0]);
            k++;
        }
    }
}

这个过程给了我一些我需要的东西。图像看起来不错。但我有问题将图像恢复为原始图像。 BACKWARD的功能如下所示

void FFTInterface::IFFTW(int rows, int cols, fftw_complex * in, fftw_complex * out)
{
    fftw_plan g;
    g = fftw_plan_dft_2d(rows, cols, in, out, FFTW_BACKWARD, FFTW_MEASURE);

    int k = 0;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            in[k][1] = 0.0;
            k++;
         }
    }

    fftw_execute(g);
    fftw_destroy_plan(g);
}

我发现某个地方没有规范化(结果非常大)。为了标准化我只是将值除以N(256,512等) - 图像的宽度或高度(它总是一个正方形),但值与原始值不同。

你知道我遗失的地方吗? Scalling?我应该使用库中的其他fft方法?我坚持了。

1 个答案:

答案 0 :(得分:2)

通过获取绝对值并缩放复杂组件以显示图像,您正在修改数据,使得逆变换不再为您提供原始输入。为避免此问题,我建议您在缩放之前创建要显示的数据的副本。另外,请确保不要忘记逆变换的输入应该是正向变换的输出(或者可能是信号处理链中的最后一个输出)。

在伪代码中你可以这样做:

interface.FFTW(rows, cols, imageInput, in, out);

size_t N = rows*cols;
fftw_complex* todisplay = fftw_malloc(N);
std::copy(out, out+N, todisplay);
interface.Abs(todisplay);
interface.Scale(todisplay);
... display "todisplay" on your Qt user interface
fftw_free(todislay);

interface.IFFTW(rows, cols, out, reconstructed);