【发布时间】:2017-12-31 01:06:34
【问题描述】:
我必须在图像上实现 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。你可以帮帮我吗?有错吗?
【问题讨论】:
-
在您的第一个代码 sn-p 中,两次调用
FastFourier1D,您将false传递给inverse。这是故意的吗? -
是的,这是有意的,因为它是“前向”傅立叶。 Inverse 与传递的“true”几乎相同。我必须调用它两次,因为在 2D 傅里叶中,我必须在第一次通过后用列更改行。
-
只是一个调试建议。为什么不尝试更简单的图像而不是 Lena?见这个想法:www.fmwconcepts.com/misc_tests/FFT_tests/index.html
-
如果这不是作业,您可以使用
std::complex代替您自己的课程。 -
谢谢,正如我在答案中所写,我发现我的乘法运算符有错误的实现。现在,一切正常。