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.
Ich finde das 'fseek()' verdächtig. Wenn Sie sequentiell schreiben, warum suchen Sie überhaupt? – EOF
@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
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