c-无法在带顺序模式下写入像素块

  • 本文关键字:像素 模式 顺序 c gis gsl envi
  • 更新时间 :
  • 英文 :


我正在处理一个具有bsq(带序列)类型交错的ENVI图像文件(.hdr-labbelled)。我正在尝试对大约350MB大的图像进行主成分转换。为了做到这一点,我不得不在较小的内存块中单独处理它。如果文件可以在一个内存块中处理,那么下面的代码可以正常工作。然而,如果它需要多个迭代,那么只有最后一个块如预期的那样出现,即,所有先前的块都被写入,就好像它们是同一像素的重复一样。

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("Transformingn");
      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: %sn", 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函数中对其进行了不适当的调用。为了做到这一点,我只简单地使用了下面的代码insted,它按顺序写入像素(bip-interleave)。

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

但是,我希望将我的输出文件保留为带序列文件。我花了很多时间试图找到解决方案,在这里和那里调整代码,但问题的解决方案仍然无法解决。

我终于找到了问题的根源。现在的问题是,我太倾向于相信文件中的写作程序的位置了。然而,它仍然在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: %sn", 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"并首先初始化文件后,我保证它会打开文件进行简单的更新,而不会擦除我以前的工作。

最新更新