From c25e7d0d7c5ce33f99b99126de0fd426be193ec1 Mon Sep 17 00:00:00 2001 From: heziqi Date: Tue, 7 Oct 2014 08:18:14 +0800 Subject: [PATCH] speed of bip.baseline fixed --- envi/bil.h | 372 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ envi/bip.h | 13 ------------- envi/bsq.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 403 insertions(+), 13 deletions(-) diff --git a/envi/bil.h b/envi/bil.h index e69de29..2d8e421 100644 --- a/envi/bil.h +++ b/envi/bil.h @@ -0,0 +1,372 @@ +#include "../envi/envi.h" +#include "../envi/binary.h" +#include +#include + +namespace rts{ + +template + +class bil: public binary { + +protected: + + envi header; + +public: + + using binary::open; + using binary::file; + using binary::getSlice; + + //open a file, given the file and its header's names + bool open(std::string filename, std::string headername){ + + if (header.load(headername)==false){ + std::cout<<"ERROR: unable to load header file: "<(header.samples, header.lines, header.bands), header.header_offset); + return true; + + } + + //save one band of the file into the memory, and return the pointer + bool band_index( T * p, unsigned int page){ + + unsigned int L = header.samples * sizeof(T); //caculate the number of bytes in a sample line + unsigned int jump = header.samples * (header.bands - 1) * sizeof(T); + + if (page >= header.bands){ //make sure the bank number is right + std::cout<<"ERROR: page out of range"< wavelength ){ + band_index(p, page); + return true; + } + + while( header.wavelength[page] < wavelength ) + { + page++; + //if wavelength is larger than the last wavelength in header file + if (page == header.bands) { + band_index(p, header.bands-1); + return true; + } + } + if ( wavelength < header.wavelength[page] ) + { + p1=(T*)malloc(S); //memory allocation + p2=(T*)malloc(S); + band_index(p1, page - 1); + band_index(p2, page ); + for(unsigned i=0; i < XY; i++){ + double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]); + p[i] = (p2[i] - p1[i]) * r + p1[i]; + } + } + else //if the wavelength is equal to a wavelength in header file + { + band_index(p, page); + } + + return true; + } + + //get YZ line from the a Y slice, Y slice data should be already IN the MEMORY + bool getYZ(T* p, T* c, double wavelength) + { + unsigned int X = header.samples; //calculate the number of pixels in a sample + unsigned int B = header.bands; + unsigned int L = X * sizeof(T); + + unsigned page=0; //samples around the wavelength + T * p1; + T * p2; + + //get the bands numbers around the wavelength + + //if wavelength is smaller than the first one in header file + if ( header.wavelength[page] > wavelength ){ + memcpy(p, c, L); + return true; + } + + while( header.wavelength[page] < wavelength ) + { + page++; + //if wavelength is larger than the last wavelength in header file + if (page == B) { + memcpy(p, c + (B - 1) * X, L); + return true; + } + } + if ( wavelength < header.wavelength[page] ) + { + p1=(T*)malloc( L ); //memory allocation + p2=(T*)malloc( L ); + + memcpy(p1, c + (page - 1) * X, L); + memcpy(p2, c + page * X, L); + + for(unsigned i=0; i < X; i++){ + double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]); + p[i] = (p2[i] - p1[i]) * r + p1[i]; + } + } + else //if the wavelength is equal to a wavelength in header file + memcpy(p, c + page * X, L); + + return true; + } + + //save one pixel of the BIP file into the memory, and return the pointer + bool getSpectrum(T * p, unsigned x, unsigned y){ + + if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right + std::cout<<"ERROR: sample or line out of range"<= header.lines){ //make sure the line number is right + std::cout<<"ERROR: line out of range"< wls){ + + unsigned N = wls.size(); //get the number of baseline points + + std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file + std::string headername = outname + ".hdr"; //the header file name + + //simplify image resolution + unsigned int ZX = header.bands * header.samples; //calculate the number of points in a Y slice + unsigned int L = ZX * sizeof(T); //calculate the number of bytes of a Y slice + unsigned int B = header.bands; + unsigned int X = header.samples; + + T* c; //pointer to the current Y slice + c = (T*)malloc(L); //memory allocation + + T* a; //pointer to the two YZ lines surrounding the current YZ line + T* b; + + a = (T*)malloc(X * sizeof(T)); + b = (T*)malloc(X * sizeof(T)); + + + double ai, bi; //stores the two baseline points wavelength surrounding the current band + double ci; //stores the current band's wavelength + unsigned control=0; + + if (a == NULL || b == NULL || c == NULL){ + std::cout<<"ERROR: error allocating memory"; + exit(1); + } + // loop start correct every y slice + + for (unsigned k =0; k < header.lines; k++) + { + //get the current y slice + getY(c, k); + + //initialize lownum, highnum, low, high + ai = header.wavelength[0]; + //if no baseline point is specified at band 0, + //set the baseline point at band 0 to 0 + if(wls[0] != header.wavelength[0]){ + bi = wls[control]; + memset(a, (char)0, X * sizeof(T) ); + } + //else get the low band + else{ + control++; + getYZ(a, c, ai); + bi = wls[control]; + } + //get the high band + getYZ(b, c, bi); + + //correct every YZ line + + for(unsigned cii = 0; cii < B; cii++){ + + //update baseline points, if necessary + if( header.wavelength[cii] >= bi && cii != B - 1) { + //if the high band is now on the last BL point + if (control != N-1) { + + control++; //increment the index + + std::swap(a, b); //swap the baseline band pointers + + ai = bi; + bi = wls[control]; + getYZ(b, c, bi); + + } + //if the last BL point on the last band of the file? + else if ( wls[control] < header.wavelength[B - 1]) { + + std::swap(a, b); //swap the baseline band pointers + + memset(b, (char)0, X * sizeof(T) ); //clear the high band + + ai = bi; + bi = header.wavelength[B - 1]; + } + } + + //get the current YZ line + //band_index(c, cii);??????????????????????????????????? + /* + file.seekg( (k * header.bands * X + cii)* sizeof(T), std::ios::beg); + for(unsigned j = 0; j < X; j++) + { + file.read((char *)(c + j), sizeof(T)); + file.seekg((B - 1) * sizeof(T), std::ios::cur); + }*/ + + ci = header.wavelength[cii]; + + unsigned jump = cii * X; + //perform the baseline correction + for(unsigned i=0; i < X; i++) + { + double r = (double) (ci - ai) / (double) (bi - ai); + c[i + jump] =(float) ( c[i + jump] - (b[i] - a[i]) * r - a[i] ); + } + + }//loop for YZ line end + std::cout<(c), L); //write the corrected data into destination + }//loop for Y slice end + + header.save(headername); //save the new header file + + free(a); + free(b); + free(c); + target.close(); + return true; + + } + + // normalize the BIP file + bool normalize(std::string outname, double band) + { + unsigned int B = header.bands; //calculate the number of bands + unsigned int Y = header.lines; + unsigned int X = header.samples; + unsigned int ZX = header.bands * header.samples; + unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band + unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band + unsigned int L = ZX * sizeof(T); + + std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file + std::string headername = outname + ".hdr"; //the header file name + + T * c; //pointer to the current ZX slice + T * b; //pointer to the standard band + + b = (T*)malloc( S ); //memory allocation + c = (T*)malloc( L ); + + getBand(b, band); //get the certain band into memory + + for(unsigned j = 0; j < Y; j++) + { + getY(c, j); + for(unsigned i = 0; i < X; i++) + { + for(unsigned m = 0; m < B; m++) + { + c[m + i * B] = c[m + i * B] / b[i + j * X]; + } + } + target.write(reinterpret_cast(c), L); //write normalized data into destination + } + header.save(headername); //save the new header file + + free(b); + free(c); + target.close(); + return true; + } + + //convert BIP file to BSQ file and save it + bool bsq(std::string outname) + { + unsigned int S = header.samples * header.lines * sizeof(T); //calculate the number of bytes in a band + + std::ofstream target(outname.c_str(), std::ios::binary); + std::string headername = outname + ".hdr"; + + T * p; //pointer to the current band + p = (T*)malloc(S); + + for ( unsigned i = 0; i < header.bands; i++) + { + band_index(p, i); + target.write(reinterpret_cast(p), S); //write a band data into target file + } + header.interleave = rts::envi::interleaveType::BSQ; //change the type of file in header file + header.save(headername); + + free(p); + target.close(); + return true; + } + + }; +} \ No newline at end of file diff --git a/envi/bip.h b/envi/bip.h index 981a1ce..caaaeca 100644 --- a/envi/bip.h +++ b/envi/bip.h @@ -241,8 +241,6 @@ public: //I have not used it so far bool getSpectrum(T * p, unsigned x, unsigned y){ - unsigned int i; - if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right std::cout<<"ERROR: sample or line out of range"< wls){ unsigned N = wls.size(); //get the number of baseline points @@ -357,15 +354,6 @@ public: } } - //get the current YZ line - //band_index(c, cii); - file.seekg( (k * header.bands * X + cii)* sizeof(T), std::ios::beg); - for(unsigned j = 0; j < X; j++) - { - file.read((char *)(c + j), sizeof(T)); - file.seekg((B - 1) * sizeof(T), std::ios::cur); - } - ci = header.wavelength[cii]; //perform the baseline correction @@ -376,7 +364,6 @@ public: } }//loop for YZ line end - target.write(reinterpret_cast(c), L); //write the corrected data into destination }//loop for Y slice end diff --git a/envi/bsq.h b/envi/bsq.h index 39032f0..324e189 100644 --- a/envi/bsq.h +++ b/envi/bsq.h @@ -275,6 +275,37 @@ public: target.close(); return true; } + + //convert BSQ file to BIL file and save it + bool bil(std::string outname) + { + //simplify image resolution + unsigned int L = header.samples * header.bands * sizeof(T); //calculate the number of bytes of a ZX slice + unsigned int jump = (header.lines - 1) * header.samples * sizeof(T); + + std::ofstream target(outname.c_str(), std::ios::binary); + std::string headername = outname + ".hdr"; + + T * p; //pointer to the current spectrum + p = (T*)malloc(L); + + for ( unsigned i = 0; i < header.lines; i++) + { + file.seekg(header.samples * i * sizeof(T), std::ios::beg); + for ( unsigned j = 0; j < header.bands; j++ ) + { + file.read((char *)(p + j * header.samples), sizeof(T) * header.samples); + file.seekg(jump, std::ios::cur); //go to the next band + } + target.write(reinterpret_cast(p), L); //write XZ slice data into target file + } + header.interleave = rts::envi::interleaveType::BIL; //change the type of file in header file + header.save(headername); + + free(p); + target.close(); + return true; + } }; -- libgit2 0.21.4