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'가 호출 될 때마다 'inverse'에 false를 전달합니다. 이것은 의도적입니까? – Obicere
예, '앞으로'푸리에이므로 의도적 인 것입니다. 반전은 "참된"통과와 거의 동일합니다. 2 차원 푸리에에서는 첫 번째 전달 후 열이있는 행을 변경해야하므로 두 번 호출해야합니다. – mgrzellak
디버깅을위한 제안. 왜 Lena 대신에 단순한 이미지를 시도하지 않습니까? 아이디어를 보려면 www.fmwconcepts.com/misc_tests/FFT_tests/index.html – VladP