Commit 88c3e6360038b1fab492c1c15a69d5fcc793df77

Authored by heziqi
1 parent 421219ba

Ziqi added big.h

Showing 1 changed file with 271 additions and 0 deletions   Show diff stats
envi/bip.h 0 → 100644
  1 +#include "../envi/envi.h"
  2 +#include "../envi/binary.h"
  3 +#include <cstring>
  4 +#include <utility>
  5 +
  6 +namespace rts{
  7 +
  8 +template <typename T>
  9 +
  10 +class bip: public binary<T> {
  11 +
  12 +protected:
  13 +
  14 + envi header;
  15 +
  16 +public:
  17 +
  18 + using binary<T>::open;
  19 + using binary<T>::file;
  20 + using binary<T>::getSlice;
  21 +
  22 + //open a file, given the file and its header's names
  23 + bool open(std::string filename, std::string headername){
  24 +
  25 + if (header.load(headername)==false){
  26 + std::cout<<"ERROR: unable to load header file: "<<headername<<std::endl;
  27 + return false;
  28 + }
  29 +
  30 + open(filename, vec<unsigned int>(header.samples, header.lines, header.bands), header.header_offset);
  31 + return true;
  32 +
  33 + }
  34 +
  35 + //save one band of the file into the memory, and return the pointer
  36 + bool band_index( T * p, unsigned int page){
  37 +
  38 + if (page >= header.bands){ //make sure the bank number is right
  39 + std::cout<<"ERROR: page out of range"<<std::endl;
  40 + return false;
  41 + }
  42 +
  43 + getSlice(p, 0, page);
  44 + return true;
  45 + }
  46 +
  47 + bool getBand( T * p, double wavelength){
  48 +
  49 + unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band
  50 +
  51 + unsigned page=0; //bands around the wavelength
  52 + T * p1;
  53 + T * p2;
  54 +
  55 + //get the bands numbers around the wavelength
  56 +
  57 + //if wavelength is smaller than the first one in header file
  58 + if ( header.wavelength[page] > wavelength ){
  59 + band_index(p, page);
  60 + return true;
  61 + }
  62 +
  63 + while( header.wavelength[page] < wavelength )
  64 + {
  65 + page++;
  66 + //if wavelength is larger than the last wavelength in header file
  67 + if (page == header.bands) {
  68 + band_index(p, header.bands-1);
  69 + return true;
  70 + }
  71 + }
  72 + if ( wavelength < header.wavelength[page] )
  73 + {
  74 + p1=(T*)malloc( XY * sizeof(T)); //memory allocation
  75 + p2=(T*)malloc( XY * sizeof(T));
  76 + band_index(p1, page - 1);
  77 + band_index(p2, page );
  78 + for(unsigned i=0; i < XY; i++){
  79 + double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]);
  80 + p[i] = (p2[i] - p1[i]) * r + p1[i];
  81 + }
  82 + }
  83 + else //if the wavelength is equal to a wavelength in header file
  84 + {
  85 + band_index(p, page);
  86 + }
  87 +
  88 + free(p1);
  89 + free(p2);
  90 + return true;
  91 + }
  92 +
  93 + //save one pixel of the BIP file into the memory, and return the pointer
  94 + bool getSpectrum(T * p, unsigned x, unsigned y){
  95 +
  96 + unsigned int i;
  97 +
  98 + if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right
  99 + std::cout<<"ERROR: sample or line out of range"<<std::endl;
  100 + return false;
  101 + }
  102 +
  103 + file.seekg((x + y * header.samples) * header.bands * sizeof(T), std::ios::beg); //point to the certain sample and line
  104 +
  105 + file.read((char *)p, sizeof(T) * header.bands);
  106 +
  107 + return true;
  108 + }
  109 + // not finished yet
  110 + //(BIP) baseline correction
  111 + bool baseline(std::string outname, std::vector<double> wls )
  112 + {
  113 + unsigned N = wls.size(); //get the number of baseline points
  114 +
  115 + std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
  116 + std::string headername = outname + ".hdr"; //the header file name
  117 +
  118 + //simplify image resolution
  119 + unsigned int B = header.bands; //calculate the number of bands
  120 + unsigned int L = B * sizeof(T);
  121 +
  122 + T* c; //pointer to the current spectrum
  123 + c = (T*)malloc(L);
  124 +
  125 + }
  126 +
  127 +
  128 + /*
  129 + //(BSQ)baseline correction and save it into file
  130 +
  131 + bool baseline(std::string outname, std::vector<double> wls )
  132 + {
  133 + unsigned N = wls.size(); //get the number of baseline points
  134 +
  135 + std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
  136 + std::string headername = outname + ".hdr"; //the header file name
  137 +
  138 + //simplify image resolution
  139 + unsigned int B = header.bands; //calculate the number of bands
  140 + unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band
  141 + unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band
  142 +
  143 + double ai, bi; //stores the two baseline points wavelength surrounding the current band
  144 + double ci; //stores the current band's wavelength
  145 +// unsigned aii, bii; //stores the two baseline points number surrounding the current band
  146 + unsigned control=0;
  147 +
  148 + T * a; //pointers to the high and low band images
  149 + T * b;
  150 + T * c; //pointer to the current image
  151 +
  152 + a = (T*)malloc( S ); //memory allocation
  153 + b = (T*)malloc( S );
  154 + c = (T*)malloc( S );
  155 +
  156 + if (a == NULL || b == NULL || c == NULL){
  157 + std::cout<<"ERROR: error allocating memory";
  158 + exit(1);
  159 + }
  160 +
  161 +
  162 + //initialize lownum, highnum, low, high
  163 + ai=header.wavelength[0];
  164 +
  165 + //if no baseline point is specified at band 0,
  166 + //set the baseline point at band 0 to 0
  167 + if(wls[0] != header.wavelength[0]){
  168 + bi = wls[control];
  169 + memset(a, (char)0, S);
  170 + }
  171 + //else get the low band
  172 + else{
  173 + control += 1;
  174 + getBand(a, ai);
  175 + bi = wls[control];
  176 + }
  177 + //get the high band
  178 + getBand(b, bi);
  179 +
  180 + //correct every band
  181 + for(unsigned cii = 0; cii < B; cii++){
  182 +
  183 + //update baseline points, if necessary
  184 + if( header.wavelength[cii] >= bi && cii != B - 1) {
  185 + //if the high band is now on the last BL point?
  186 + if (control != N-1) {
  187 +
  188 + control++; //increment the index
  189 +
  190 + std::swap(a, b); //swap the baseline band pointers
  191 +
  192 + ai = bi;
  193 + bi = wls[control];
  194 + getBand(b, bi);
  195 +
  196 + }
  197 + //if the last BL point on the last band of the file?
  198 + else if ( wls[control] < header.wavelength[B - 1]) {
  199 +
  200 + std::swap(a, b); //swap the baseline band pointers
  201 +
  202 + memset(b, (char)0, S); //clear the high band
  203 +
  204 + ai = bi;
  205 + bi = header.wavelength[B - 1];
  206 + }
  207 + }
  208 +
  209 + //get the current band
  210 + band_index(c, cii);
  211 + ci = header.wavelength[cii];
  212 +
  213 + //perform the baseline correction
  214 + for(unsigned i=0; i < XY; i++){
  215 + double r = (double) (ci - ai) / (double) (bi - ai);
  216 + c[i] =(float) ( c[i] - (b[i] - a[i]) * r - a[i] );
  217 + }
  218 +
  219 + target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination
  220 +
  221 + }
  222 +
  223 + header.save(headername); //save the new header file
  224 +
  225 + free(a);
  226 + free(b);
  227 + free(c);
  228 + target.close();
  229 + return true;
  230 + }
  231 +*/
  232 + // normalize the BSQ file
  233 + bool normalize(std::string outname, double band)
  234 + {
  235 + unsigned int B = header.bands; //calculate the number of bands
  236 + unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band
  237 + unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band
  238 +
  239 + std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
  240 + std::string headername = outname + ".hdr"; //the header file name
  241 +
  242 + T * b; //pointers to the certain wavelength band
  243 + T * c; //pointer to the current image
  244 +
  245 + b = (T*)malloc( S ); //memory allocation
  246 + c = (T*)malloc( S );
  247 +
  248 + getBand(b, band); //get the certain band into memory
  249 +
  250 + for(unsigned j = 0; j < B; j++)
  251 + {
  252 + band_index(c, j); //get the current band into memory
  253 + for(unsigned i = 0; i < XY; i++)
  254 + {
  255 + c[i] = c[i] / b[i];
  256 + }
  257 + target.write(reinterpret_cast<const char*>(c), S); //write normalized data into destination
  258 + std::cout<<j<<std::endl;
  259 + }
  260 +
  261 + header.save(headername); //save the new header file
  262 +
  263 + free(b);
  264 + free(c);
  265 + target.close();
  266 + return true;
  267 + }
  268 +
  269 +
  270 + };
  271 +}
0 272 \ No newline at end of file
... ...