2016-04-04 7 views
0

Ich arbeite mit einer ENVI-Bilddatei (.hdr labeled) mit einer Verschachtelung vom Typ bsq (bandsequentiell). Ich versuche, eine Hauptkomponententransformation eines Bildes von etwa 350 MB groß zu machen. Um das zu tun, musste ich es separat in kleineren Speicherblöcken verarbeiten. Der folgende Code funktioniert wie erwartet, wenn mit der Datei in nur einem Speicherblock gearbeitet werden kann. Wenn es jedoch mehr als eine Iteration benötigt, kommt nur der letzte Block wie erwartet heraus, d. H. Alle vorhergehenden Blöcke werden so geschrieben, als ob sie eine Wiederholung desselben Pixels immer und immer wieder wären.Es ist nicht möglich, einen Pixelblock im bandsequentiellen Modus zu schreiben.

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

Hier ist die Schreibfunktion.

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

Ich bin zu dem Schluss gekommen, dass das unerwartete Verhalten dieser Funktion selbst oder für einen unangemessenen Anruf, um es in der pca_xform Funktion zurückzuführen ist. Um dies zu tun, habe ich einfach den folgenden Code verwendet, der die Pixel sequentiell schreibt (bip interleave).

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

Ich möchte jedoch, meine Ausgabedatei als ein Band sequentiell zu halten. Ich habe viel Zeit darauf verwendet, eine Lösung zu finden, indem ich den Code hier und da manipuliere, aber die Lösung des Problems entzieht sich mir immer noch.

+0

Ich finde das 'fseek()' verdächtig. Wenn Sie sequentiell schreiben, warum suchen Sie überhaupt? – EOF

+0

@EOF Ich benutze 'fseek()', damit ich die richtige Position finde, um mit dem Schreiben dieses Bandes zu beginnen. Angenommen, ich habe ein 2-bandiges 10MB-Bild als Ausgabe. Dies erlaubt mir, die ersten 2,5 MB (zB Block 1) von Band 1 zu schreiben, dann zu Band 2 zu gehen und die anderen 2,5 MB zu schreiben. Also habe ich Leerzeichen in der richtigen Position gelassen, um den zweiten Block von 5MB zu schreiben. – lfmc

+0

Ich weiß, das würde kompilieren verhindern, und ist nicht die Quelle Ihres Problems .... Auf dem letzten Codeausschnitt benötigen Sie eine schließende ')'. – ryyker

Antwort

0

Endlich habe ich die Ursache des Problems gefunden. Das Problem war jetzt, da ich so sehr geneigt war, an die Position der Schreibprozeduren in der Akte zu glauben. Es war aber immer noch in der io_bsq_write_pixel. Jedes Mal, wenn ich die Funktion anrief, rief sie nacheinander fwrite(file.new_filename, "w") an. Öffnen der Datei in "w" Modus löschte alle meine früheren Arbeiten. Um dies zu beheben, initialisiert ich die Datei vor pca_xform Aufruf und verändern dann die 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; 
} 

diese Weise mit „r + b“ und die Datei zuerst initialisiert hat, garantiere ich, dass es die geöffnet Datei für ein einfaches Update, ohne meine vorherige Arbeit zu löschen.

Verwandte Themen