简体   繁体   English

无法在频段顺序模式下写入像素块

[英]Unable to write pixel block in band sequential mode

I'm working with an ENVI image file (.hdr labbeled) with a interleave of the type bsq (band sequential). 我正在使用ENVI图像文件(.hdr labbeled),其交错类型为bsq(波段顺序)。 I'm trying to do a principal component transformation of an image about 350MB large. 我正在尝试对约350MB大的图像进行主成分转换。 In order to do that I had to proccess it separately in smaller memory blocks. 为此,我必须在较小的内存块中分别进行处理。 The code below works as expected if the file can be worked with in just one block of memory. 如果仅在一个内存块中可以使用文件,则下面的代码将按预期工作。 However, if it takes more than one iterarion, only the last block comes out as expected, ie, all the previous blocks are written as if they were a repetition of the same pixel over and over again. 但是,如果需要多次迭代,则只有最后一个块按预期方式出现,即,所有先前的块都被写入,就好像它们一次又一次地重复同一像素一样。

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;
    }

Here is the writing function. 这是书写功能。

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;
}

I've come to the conclusion that the unexpected behaviour is due to this function itself or for some inappropriate call to it in the pca_xform function. 我得出的结论是,意外行为是由于此函数本身或在pca_xform函数中对其进行了一些不适当的调用所致。 To do this, I've simply used the following code insted, which writes the pixels sequentially (bip interleave). 为此,我仅使用了insted的以下代码,该代码按顺序(bip交错)写入像素。

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

I would like, however, to keep my output file as a band sequential one. 但是,我希望将我的输出文件保持为波段顺序。 I've used a lot of time trying to find a solution, tweaking the code here and there, but the problem's solution still eludes me. 我花了很多时间试图找到解决方案,在这里和那里调整代码,但是问题的解决方案仍然使我难以理解。

I finally managed to find the source of the problem. 我终于设法找到问题的根源。 The problem was now as I was so inclined to believe in the position of the writing procedures in the file. 现在的问题出在我非常倾向于相信文件中编写程序的位置。 It was still, however in the io_bsq_write_pixel . 但是仍然在io_bsq_write_pixel Each time I called the function it would subsequentally call fwrite(file.new_filename, "w") . 每次我调用该函数时,它将随后调用fwrite(file.new_filename, "w") Opening the file in "w" mode erased all my previous work. “ w”模式打开文件会删除我以前的所有工作。 In order to fix this, I initialized the file before calling pca_xform and then changed the io_bsq_write_pixel 为了解决这个问题,我在调用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;
}

This way, using "r+b" and having initialized the file first, I guarantee that it will open the file for a simple update, without erasing my previous work. 这样,使用“ r + b”并首先初始化了文件,我保证它将打开文件进行简单更新,而不会删除我以前的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM