C++ 图像二维快速傅里叶变换

C++ Image 2D Fast Fourier Transform

我必须对图像实施 2D FFT 变换(我不能使用库为我做这件事 - 课程的一部分)。我使用 CImg 加载和保存图像。我做了以下代码:

CImg<Complex> FastFourier(CImg<unsigned char> &originalImage)
{
    //check size in the main.cpp
    CImg<Complex> resultantImage = TransformToComplex(originalImage);
    vector< vector< vector< Complex > > > vectorImage = imageToVector(resultantImage);
    //cout << "Transform to complex" << endl;
    int size = originalImage.width();

    for(int i = 0; i < size; i++)
        FastFourier1D(vectorImage[i], false);

    vectorImage = rotateVector(vectorImage);

    for(int i = 0; i < size; i++)
       FastFourier1D(vectorImage[i], false);

    vectorImage = rotateVector(vectorImage);

    resultantImage = vectorToImage(vectorImage);

    return resultantImage;
}

并且:

void FastFourier1D(vector< vector< Complex > > &input, bool inverse)
{
    int size = input.size();
    double angle;

    if(size <= 1)
        return;

    int channels = input[0].size();
    vector< vector< Complex > > even;
    vector< vector< Complex > > odd;

    for(int i = 0; i < size; i+=2)
    {
        vector< Complex > tempEven;
        vector< Complex > tempOdd;
        for(int channelIterator = 0; channelIterator < channels; channelIterator++)
        {
            tempEven.push_back(input[i][channelIterator]);
            tempOdd.push_back(input[i + 1][channelIterator]);
        }

        even.push_back(tempEven);
        odd.push_back(tempOdd);
    }

    FastFourier1D(even, inverse);
    FastFourier1D(odd, inverse);

    for(int channelIterator = 0; channelIterator < channels; channelIterator++)
    {
        for(int i = 0; i < size / 2; i++)
        {
           if(inverse == false)
               angle = -2.0 * (double)PI * (double)i / (double)size;
           else
               angle = 2.0 * (double)PI * (double)i / (double)size;

           double real = cos(angle);
           double imaginary = sin(angle);

           Complex W;
           W.setRP(real);
           W.setIP(imaginary);

           W = W * odd[i][channelIterator];

           input[i][channelIterator] = even[i][channelIterator] + W;
           input[(size / 2) + i][channelIterator] = even[i][channelIterator] - W;
       }
    }
}

然而结果并不好。输入图像:

FFT(没有任何变换):

反向 FFT:

如你所见,它有 lena 的颜色,但看起来不像 lena。你可以帮帮我吗?有没有错?

我发现答案是我 Complex class 中乘法运算符的错误实现。

Complex Complex::operator*(const Complex& a)
{
    Complex number;
    double RP = realPart * a.getRP() - imaginaryPart * a.getIP(); // this line was wrong
    double IP = realPart * a.getIP() + imaginaryPart * a.getRP();
    number.setRP(RP);
    number.setIP(IP);
    return number;
}

real part中,我忘记了minus。现在整个实现正在运行,傅里叶成功地将图像转换为频域并将逆转换为空间域。