2

高速フーリエ変換を使用する fftw (fftw.org) の例を実装しました...これがコードです....

uint8_t から double に変換する画像を読み込みます (このコードは正常に動作します...)。

string bmpFileNameImage = "files/testDummyFFTWWithWisdom/onechannel_image.bmp"; 
BMPImage bmpImage(bmpFileNameImage);
vector<double>pixelColors; 
vector<uint8_t> image = bmpImage.copyBits();

toDouble(image,pixelColors,256,256, 1); 
int width = bmpImage.width();
int height = bmpImage.height();

知恵ファイルを使用してパフォーマンスを向上させます

FILE * file = fopen("wisdom.fftw", "r");
if (file) {
    fftw_import_wisdom_from_file(file);
    fclose(file);
} 

///*  fftw variables  */
fftw_complex *out;

double *wisdomInput = (double *) fftw_malloc(sizeof(double)*width*2*(height/2 +1 ));

const fftw_plan forward =fftw_plan_dft_r2c_2d(width,height, wisdomInput,reinterpret_cast<fftw_complex *>(wisdomInput),FFTW_PATIENT);
const fftw_plan inverse = fftw_plan_dft_c2r_2d(width, height,reinterpret_cast<fftw_complex *>(wisdomInput),wisdomInput, FFTW_PATIENT);

file = fopen("wisdom.fftw", "w");

if (file) {
    fftw_export_wisdom_to_file(file);
    fclose(file);
}

最後に、fftw ライブラリを実行します...最初の関数 ( fftw_execute_dft_r2c) でアクセス違反エラーが発生し、理由がわかりません... このチュートリアルを読みました: http://www.fftw.org/fftw3_doc/ Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data . 説明されているように (ny/2+1) で malloc を実行します。なぜ機能しないのかわかりません....さまざまなサイズをテストしています...

out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * width *(height / 2 + 1));
double *result =(double *)fftw_malloc(width * (height+2)  * sizeof(double));

fftw_execute_dft_r2c(forward,&pixelColors[0],out);
fftw_execute_dft_c2r(inverse,out,result);

よろしく。

4

3 に答える 3

1

修正したコードです。いくつかの間違いがありました:

  • 間違ったwidness.fftwファイルを読み取っていました(古いテストから...)。これで、常に新しい fftw_plan と新しいファイルが作成されます。
  • インプレースおよびアウトオブプレースパラメータを使用して fftw ライブラリがどのように機能するかを誤解していました。「インプレース」の正しいパディングのためにmallocを変更する必要がありました(malloc関数に+2を追加しました)。
  • 画像を復元するために、このリンクで説明されているように、そのサイズ ((幅 + 2) * 高さ) で割る必要がありました。

`

/* load image */
string bmpFileNameImage = "files/polyp.bmp";

BMPImage bmpImage(bmpFileNameImage);

int width = bmpImage.width();
int height = bmpImage.height();

vector<double> pixelColors;
vector<uint8_t> image = bmpImage.copyBits();
//get one channel from the image
Uint8ToDouble(image,pixelColors,bmpImage.width(),bmpImage.height(),1);

//We don't reuse old wisdom.fftw... It can be corrupt 
/*
FILE * file = fopen("wisdom.fftw", "r");
if (file) {
    fftw_import_wisdom_from_file(file);
    fclose(file);
} */

double *wisdomInput = (double *) fftw_malloc(sizeof(double)*height*(width+2));

const fftw_plan forward =fftw_plan_dft_r2c_2d(width,height,wisdomInput,reinterpret_cast<fftw_complex *>(wisdomInput),FFTW_PATIENT);
const fftw_plan inverse = fftw_plan_dft_c2r_2d(width,height,reinterpret_cast<fftw_complex *>(wisdomInput),wisdomInput, FFTW_PATIENT);
double *bitsColors =(double *)fftw_malloc((width) * height * sizeof(double));

for (int y = 0; y < height; y++) {
    for (int x = 0; x < width+2; x++) {
        if (x < width) {
            int currentIndex = ((y * width) + (x));
            bitsColors[currentIndex] = (static_cast<double>(result[y * (width+2) + x])) / (height*width);
        }
    }
}
fftw_free (wisdomInput);
fftw_free (out);
fftw_free (result);
fftw_free (bitsColors);

fftw_destroy_plan(forward);
fftw_destroy_plan(inverse);
fftw_cleanup();
}

`

于 2013-06-26T16:48:18.220 に答える
0
fftw_execute_dft_r2c(forward,&pixelColors[0],out);

あなたはここで何をしているの ?配列には既にポインターがあります。それを今すぐ動作するように変更しfftw_execute_dft_r2c(forward,pixelColors[0],out);てください。

于 2013-06-25T09:43:04.023 に答える
0

たぶん問題はここにあります( http://www.fftw.org/doc/New_002darray-Execute-Functions.html ):

……以下の条件を満たしていること。

  • 入力配列と出力配列は、同じ (インプレース) または異なる (アウトオブプレース) です (プランが元々インプレースまたはアウトオブプレースとして作成された場合)。

プランでは、インプレース変換パラメーターを使用しています (割り当てが悪いため、BTW:

double *wisdomInput = (double *) fftw_malloc(sizeof(double)*width*2*(height/2 +1 ));

次のようにする必要があります。

double *wisdomInput = (double *) fftw_malloc(sizeof(fftw_complex)*width*2*(height/2 +1 ));

出力にも適しています)。

fftw_execute_dft_r2cしかし、場違いなパラメーターで関数を呼び出しています。

于 2013-06-25T11:04:31.650 に答える