2016-04-04 36 views
0

私は、bsq(バンドシーケンシャル)タイプのインターリーブを持つENVI画像ファイル(.hdr labbeled)で作業しています。私は約350MBの画像の主成分変換をしようとしています。これを行うために、私は別々に小さなメモリブロックでそれを処理しなければなりませんでした。次のコードは、ファイルを1ブロックのメモリで処理できる場合、期待どおりに機能します。しかし、2つ以上の反復が必要な場合は、最後のブロックだけが期待通りに出てくる、すなわち、前のブロックはすべて同じピクセルの繰り返しであるかのように書き込まれる。ピクセルブロックをバンドシーケンシャルモードで書き込むことができません

extern void pca_xform(envi_header file){ 

    #define BLOCK_SIZE 3000000 

      /*Calculates covariance_matrix, eigen_matrix, mean_vector 
    and allocates pixel_vector and xform_pixel_vector*/ 

     int size = (file.lines)*(file.samples), i; 

     printf("Transforming\n"); 

     int n = size/BLOCK_SIZE; 
     int r = size - ((BLOCK_SIZE)*n); 
     int block; 

     for(i=0,block=0;i<n+1;++i,++block){ 
     int actual_size = BLOCK_SIZE; 
     if(i==n){ 
      actual_size = r; 
     } 
     int k; 
     io_bsq_read_pixel(file, i*BLOCK_SIZE, actual_size, pixel_vector); 
     for(k=0;k<actual_size;++k){ 
      pca_normalize_pixel_vector(mean_vector, pixel_vector[k]); 
     } 
     for(k=0;k<actual_size;++k){ 
      pca_xform_pixel_vector(file, eigen_matrix, pixel_vector[k], xform_pixel_vector[k]); 
     } 
     io_bsq_write_pixel(file, i*BLOCK_SIZE, actual_size, xform_pixel_vector); 
     } 

     return; 
    } 

ここに書き込み機能があります。

extern void io_bsq_write_pixel(envi_header file, int start, int number, gsl_vector** pixel_vector){ 
    FILE* fp = fopen(file.new_filename, "wb"); 
    if(!fp){ 
    fprintf(stderr, "Failed to open target: %s\n", file.new_filename); 
    exit(EXIT_FAILURE); 
    } 
    int size = (file.samples) * (file.lines); 
    int i, j; 
    double d; 
    for(i=0;i<file.bands;++i){ 
    fseek(fp, sizeof(double)*((size*i)+start), SEEK_SET); 
    for(j=0;j<number;++j){ 
     d = gsl_vector_get(pixel_vector[j], i); 
     fwrite(&d, sizeof(double), 1, fp); 
    } 
    } 
    fclose(fp); 
    return; 
} 

私は予期しない動作が、この関数自体またはpca_xform機能で、それにはいくつかの不適切な呼び出しのために起因することを結論に達しました。これを行うために、私は単にピクセルを順次書き込む(bipインターリーブ)以下のコードinstedを使いました。

for(i=0;i<size:++i){ 
    gsl_vector_fwrite(fp, xform_pixel_vector[i]); 
} 

出力ファイルをバンド順番に保つことをお勧めします。私は解決策を見つけようと多くの時間を費やしてきましたが、こことそこでコードを調整しましたが、問題の解決策はまだ私を逃しています。

+0

私は 'fseek()'が不審であることがわかりました。あなたが順番に書いているなら、どうしてあなたは何を求めているのですか? – EOF

+0

@EOF私は 'fseek()'を使って、そのバンドの書き込みを開始する正しい位置を見つけることができます。出力として2バンドの10MBイメージがあるとします。これにより、バンド1の最初の2,5MB(たとえばブロック1)を書き込んだり、2番のバンドに行き、もう一方の2,5MBを書き込んだりできます。そこで、5MBの2番目のブロックを書き込むために空白を正しい位置に残しました。 – lfmc

+0

私はこれがコンパイルを妨げ、問題の原因ではないことを知っています....最後のコードスニペットでは ')'が必要です。 – ryyker

答えて

0

私はついにこの問題の原因を見つけることができました。この問題は、私がファイル内での手続きの立場を信じるようになったときのようになりました。しかし、それでもなお、io_bsq_write_pixelであった。私がその関数を呼び出すたびに、後でfwrite(file.new_filename, "w")と呼ぶでしょう。 "w"モードでファイルを開くと、以前のすべての作業が消去されました。この問題を解決するために、私はpca_xformを呼び出す前に、ファイルを初期化し、その後、この方法では、io_bsq_write_pixel

extern void io_bsq_write_pixel(envi_header file, int start, int number, gsl_vector** pixel_vector){ 
    FILE* fp = fopen(file.new_filename, "r+b"); 
    if(!fp){ 
    fprintf(stderr, "Failed to open target: %s\n", file.new_filename); 
    exit(EXIT_FAILURE); 
    } 
    int size = (file.samples) * (file.lines); 
    int i, j; 
    double d; 
    for(i=0;i<file.bands;++i){ 
    fseek(fp, sizeof(double)*((size*i)+start), SEEK_SET); 
    for(j=0;j<number;++j){ 
     d = gsl_vector_get(pixel_vector[j], i); 
     fwrite(&d, sizeof(double), 1, fp); 
    } 
    } 
    fclose(fp); 
    return; 
} 

を変更し、を「R + B」を使用して最初のファイルを初期化した、私はそれがオープンすることを保証します私の前の作業を消去することなく、単純な更新のためのファイル。

関連する問題