#ifndef STIM_BSQ_H #define STIM_BSQ_H #include "../envi/envi_header.h" #include "../envi/binary.h" #include "../envi/bil.h" #include #include #include namespace rts{ template class bsq: public binary { protected: //envi_header header; std::vector w; //band wavelengths unsigned int offset; public: using binary::open; using binary::file; using binary::getSlice; using binary::R; //open a file, given the file name and dimensions bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int B, unsigned int header_offset, std::vector wavelengths){ //copy the wavelengths to the BSQ file structure w = wavelengths; //copy the wavelengths to the structure offset = header_offset; return open(filename, vec(X, Y, B), header_offset); return false; } //retrieve one band (specified by the band index) bool band_index( T * p, unsigned int page){ if (page >= R[2]){ //make sure the bank number is right std::cout<<"ERROR: page out of range"< wavelength ){ band_index(p, page); return true; } while( w[page] < wavelength ) { page++; //if wavelength is larger than the last wavelength in header file if (page == R[2]) { getSlice(p, 2, R[2]-1); return true; } } if ( wavelength < w[page] ) { p1=(T*)malloc( XY * sizeof(T)); //memory allocation p2=(T*)malloc( XY * sizeof(T)); band_index(p1, page - 1); band_index(p2, page ); for(unsigned i=0; i < XY; i++){ double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); p[i] = (p2[i] - p1[i]) * r + p1[i]; } } else //if the wavelength is equal to a wavelength in header file { getSlice(p, 2, page); } return true; } //save one pixel of the file into the memory, and return the pointer bool spectrum(T * p, unsigned x, unsigned y){ unsigned int i; if ( x >= R[0] || y >= R[1]){ //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 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 B = R[2]; //calculate the number of bands unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band double ai, bi; //stores the two baseline points wavelength surrounding the current band double ci; //stores the current band's wavelength // unsigned aii, bii; //stores the two baseline points number surrounding the current band unsigned control=0; T * a; //pointers to the high and low band images T * b; T * c; //pointer to the current image a = (T*)malloc( S ); //memory allocation b = (T*)malloc( S ); c = (T*)malloc( S ); if (a == NULL || b == NULL || c == NULL){ std::cout<<"ERROR: error allocating memory"; exit(1); } //initialize lownum, highnum, low, high ai=w[0]; //if no baseline point is specified at band 0, //set the baseline point at band 0 to 0 if(wls[0] != w[0]){ bi = wls[control]; memset(a, (char)0, S); } //else get the low band else{ control += 1; band(a, ai); bi = wls[control]; } //get the high band band(b, bi); //correct every band for(unsigned cii = 0; cii < B; cii++){ //update baseline points, if necessary if( w[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]; band(b, bi); } //if the last BL point on the last band of the file? else if ( wls[control] < w[B - 1]) { std::swap(a, b); //swap the baseline band pointers memset(b, (char)0, S); //clear the high band ai = bi; bi = w[B - 1]; } } //get the current band band_index(c, cii); ci = w[cii]; //perform the baseline correction for(unsigned i=0; i < XY; i++){ double r = (double) (ci - ai) / (double) (bi - ai); c[i] =(T) ( c[i] - (b[i] - a[i]) * r - a[i] ); } target.write(reinterpret_cast(c), S); //write the corrected data into destination } //header.save(headername); //save the new header file free(a); free(b); free(c); target.close(); return true; } // normalize the BSQ file bool normalize(std::string outname, double w) { unsigned int B = R[2]; //calculate the number of bands unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file std::string headername = outname + ".hdr"; //the header file name T * b; //pointers to the certain wavelength band T * c; //pointer to the current image b = (T*)malloc( S ); //memory allocation c = (T*)malloc( S ); band(b, w); //get the certain band into memory for(unsigned j = 0; j < B; j++) { band_index(c, j); //get the current band into memory for(unsigned i = 0; i < XY; i++) { c[i] = c[i] / b[i]; } target.write(reinterpret_cast(c), S); //write normalized data into destination } //header.save(headername); //save the new header file free(b); free(c); target.close(); return true; } //convert BSQ file to BIP file and save it bool bip(std::string outname) { std::string temp = outname + "_temp"; std::string headtemp = temp + ".hdr"; //first creat a temporary bil file and convert bsq file to bil file bil(temp); rts::bil n; if(n.open(temp, R[0], R[1], R[2], offset, w)==false){ //open infile std::cout<<"ERROR: unable to open input file"<(p), L); //write XZ slice data into target file } //header.interleave = rts::envi_header::BIL; //change the type of file in header file //header.save(headername); free(p); target.close(); return true; } //create mask file bool mask(unsigned char* p, double mask_band, double threshold){ T* temp = (T*)malloc(R[0] * R[1] * sizeof(T)); //allocate memory for the certain band band(temp, mask_band); for (unsigned int i = 0; i < R[0] * R[1]; i++) { if (temp[i] < threshold) p[i] = 0; else p[i] = 255; } return true; } //close the file bool close(){ file.close(); return true; } }; } #endif