

C言語でブレの画像処理プログラムを参考文献をもとに作成しました。 (CPUで行う)  
そのFFT部分をcufftライブラリを用いて処理を行おうと思っています。 (FFT部分を置き換えてGPUで行う)

[code]

    unsigned char imageIN[画素数][画素数]
    
[/code]

↓ これに画像のデータを入れてfloat型に変換

[code]

    for(i=0; i<幅; i++){
      for(j=0; j<幅; j++){
        data[i][j] = (float)imageIN[i][j];
        jdata[i][j] = 0.0;
      }
    }
    
[/code]

という感じに画像のデータを入れ、cufftライブラリがc言語のみで作ったものとFFT部を比較しました。  
するとCUFFTライブラリがうまく実行されていないようでした。

* * *

本題  
どのようにしたらcufftライブラリを実行できるのでしょうか、（抽象的ですが一応聞きたいことは下にまとめました。）  
（下のプログラムは他をある程度省略して、質問したい部分です。（逆方向FFTはコメントアウト））

[code]

    int main(int argc, char **argv){
      int i,k,d;
      int n=512;                                           //画像の１辺のサイズ
      float *v=NULL;
      cufftComplex  *dv;
      cufftHandle    plan;
    
      cudaMalloc((void **)&dv, n*n*sizeof(float2));        //デバイス・メモリの確保
      cudaMallocHost((void **)&v, n*n*sizeof(float2));     //ホスト・メモリの確保
      for(i=0; i<n*n*2; i++)  v[i] = (float)(i % (n-1));   //データの初期化
    
      load_image_data();                      //原画像の読み込み
      make_original_data();                   //元のデータを作成する
    
      // ここで v に画像のデータを入れる？
      cudaMemcpy(dv,v,n*n*sizeof(double2), cudaMemcpyHostToDevice);  //ホストからデバイスへ転送
      cufftPlan2d(&plan,n,n,CUFFT_R2C);       //n×nの２次元FFTの準備
      cufftExecC2C(plan,dv,dv,CUFFT_FORWARD); //順方向への変換
    
      cudaMemcpy(data, dv, n*n*sizeof(double2), cudaMemcpyDeviceToHost);
                                      //デバイスからホストへ転送
      //cufftDestroy(plan);           //資源を解放
      //（blurはCPUで行いたい）
      blur();                         //周波数領域でのぼけフィルタリング
    
      /*
      cudaMemcpy(dv,v,n*n*sizeof(double2), cudaMemcpyHostToDevice);//ホストからデバイスへ転送
      cufftPlan2d(&plan,n,n,CUFFT_C2R);          //n×nの２次元FFTの準備
      cufftExecC2C(plan, dv, dv, CUFFT_INVERSE); //逆方向への変換
      cufftDestroy(plan);     //資源を解放
      cudaMemcpy(v, dv, n*n*sizeof(double2), cudaMemcpyDeviceToHost);
                              //デバイスからホストへ転送
      */
    
      cudaFree(v);
      save_image_data(); //出力画像を保存する
      return 0;
    }
    
[/code]

* * *

  * このような処理を行うときは２次元FFTでよいのでしょうか。
  * cufftComplex は構造体として考えてもよいのでしょうか。
  * また、画像データの代入の仕方はどのように行えばよいでしょうか。
  * 他に悪いところがあれば教えていただきたいです。

一応色々試してみたのですが、知識が及ばず迷走して悩んでいます。  
よろしくお願いします。

![VS2010にて](https://i.stack.imgur.com/lmNDt.png)

誤解を生みそうな表現がありましたので一部（ ）で追加しました。


CC BY-SA 3.0
2015-01-31T09:09:59.813
5657
2015-02-03T15:53:00.713
2015-01-31T20:02:49.113
7979
7979
question
c cuda
CUDAによるFFT部分をライブラリでの置き換え


質問者です。  
皆様のご協力で、解決しました！

今後僕のような人の為に変更点を書かせて下さい。

* * *

float *v=NULL; → float2 *v;  
このようにすることで v の構造体を作成することができる。

* * *
[code]

    for(i=0; i<n*n*2; i++)  v[i] = (float)(i % (n-1));   //データの初期化
                            //↓ に変更
    for(j=0; j<n; j++){for(i=0;i<n;i++){v[j*n+i] = make_cuComplex(data[j][i], jdata[j][i])}};   //データの代入
    
[/code]

こうすることでvの構造体（x,y）に値を簡単に代入することができる。  
また、取る容量をn*n*2とせず、float2で取り、バグの元を防ぐ。

* * *
[code]

      blur();　→ blur(v);
      save_image_data();  →  save_image_data(v);
    
[/code]

グローバル関数を多用してたのでアドレスに変更。

CPU→GPU→CPUに移り、その後またGPUに移る前に一度使ったら領域解放がいるのかな？と思ってましたが、  
領域解放は最後にまとめてで大丈夫でした。

* * *

後は自分の質問に対して、  
- 画像は確かに2次元FFTを用いればよい  
- cufftComplex はfloatの構造体です。  
- 画像データの代入はmake_cuComplex(実部データ, 虚部データ)で行えばよい

* * *

+α  
![画像の説明をここに入力](https://i.stack.imgur.com/GNDfC.png)

デバイスメモリの中身もデバッガで直接確認できるようです。

* * *

編集でわかりやすくしてくださった方々  
親身になって教えてくださった方々にとても感謝しております。  
自分もできるだけ回答者に回れるように勉強します。


CC BY-SA 3.0
2015-02-03T15:53:00.713
5886
2015-02-03T15:53:00.713
7979
5657
answer