画像を処理するためにC++言語でDFT (離散フーリエ変換)を実装したいと考えています。
理論を勉強していると、2D DFT を2 つの 1D DFT部分に分割できることがわかりました。まず、行ごとに 1D DFT を実行し、次に列ごとに実行します。もちろん、複素数の演算を行う必要があります。
ここでいくつかの問題が発生します。これは、複素数の実部と虚部をどこで使用するかわからないためです。入力画像ピクセルの値は、虚数部を 0 に設定した実数部として扱う必要があることをどこかで見つけました。
私はそれを実装しましたが、結果の画像が間違っていると思います。
誰かが私を助けてくれたら幸いです。
画像の読み取りと保存には、CImg ライブラリを使用します。
void DFT (CImg<unsigned char> image)
{
int w=512;
int h=512;
int rgb=3;
complex <double> ***obrazek=new complex <double>**[w];
for (int b=0;b<w;b++) //making 3-dimensional table to store DFT values
{
obrazek[b]=new complex <double>*[h];
for (int a=0;a<h;a++)
{
obrazek[b][a]=new complex <double>[rgb];
}
}
CImg<unsigned char> kopia(image.width(),image.height(),1,3,0);
complex<double> sum=0;
complex<double> sum2=0;
double pi = 3.14;
for (int i=0; i<512; i++){
for (int j=0; j<512; j++){
for (int c=0; c<3; c++){
complex<double> cplx(image(i,j,c), 0);
obrazek[i][j][c]=cplx;
}}}
for (int c=0; c<3; c++) //for rows
{
for (int y=0; y<512; y++)
{
sum=0;
for (int x=0; x<512; x++)
{
sum+=(obrazek[x][y][c].real())*cos((2*pi*x*y)/512)-(obrazek[x][y][c].imag())*sin((2*pi*x*y)/512);
obrazek[x][y][c]=sum;
}
}
}
for (int c=0; c<3; c++) //for columns
{
for (int y=0; y<512; y++)//r
{
sum2=0;
for (int x=0; x<512; x++)
{
sum2+=(obrazek[y][x][c].real())*cos((2*pi*x*y)/512)-(obrazek[y][x][c].imag())*sin((2*pi*x*y)/512);
obrazek[y][x][c]=sum2;
}
}
}
for (int i=0; i<512; i++){
for (int j=0; j<512; j++){
for (int c=0; c<3; c++){
kopia(i,j,c)=obrazek[i][j][c].real();
}}}
CImgDisplay image_disp(kopia,"dft");
while (!image_disp.is_closed() )
{
image_disp.wait();
}
saving(kopia);
}