0
画像に2D FFT変換を実装する必要があります(コースの一部としてライブラリを使用することはできません)。私は画像をロードして保存するのにCImg
を使います。C++画像2D高速フーリエ変換
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:
あなたが見ることができるように、それはレナの色を持っていますが、似ていませんレナ私たちを手伝ってくれますか?間違いはありますか?
最初のコードスニペットでは、「FastFourier1D」と「FastFourier1D」の両方が呼び出されたときに、 'inverse'に' false'を渡します。これは意図的ですか? – Obicere
はい、 "前方"フーリエであるため意図的です。逆は、 "真の"合格とほぼ同じです。 2Dフーリエでは、最初のパスの後に列で行を変更する必要があるため、2回呼び出す必要があります。 – mgrzellak
デバッグのための単なる提案です。なぜLenaの代わりに簡単な画像を試してみませんか?これを参考にしてください:www.fmwconcepts.com/misc_tests/FFT_tests/index.html – VladP