Commit 11f177d5e4f7a3a6c4938ba837e59a120e16fe21

Authored by heziqi
1 parent dcdf1276

Ziqi added functions in biq.h

Showing 1 changed file with 291 additions and 102 deletions   Show diff stats
envi/bip.h
... ... @@ -40,7 +40,14 @@ public:
40 40 return false;
41 41 }
42 42  
43   - getSlice(p, 0, page);
  43 + //binary::getSlice(p, 0, page); //I met some problems when I called this function?????
  44 + file.seekg(page * sizeof(T), std::ios::beg);
  45 + for (unsigned i = 0; i < header.samples * header.lines; i++)
  46 + {
  47 + file.read((char *)(p + i), sizeof(T));
  48 + file.seekg( (header.bands - 1) * sizeof(T), std::ios::cur);
  49 + }
  50 +
44 51 return true;
45 52 }
46 53  
... ... @@ -89,15 +96,156 @@ public:
89 96 free(p2);
90 97 return true;
91 98 }
  99 + //get YZ line from the a Y slice, Y slice data should be already IN the MEMORY
  100 + bool getYZ(T* p, T* c, double wavelength)
  101 + {
  102 + unsigned int X = header.samples; //calculate the number of pixels in a sample
  103 + unsigned int B = header.bands;
  104 +
  105 + unsigned page=0; //samples around the wavelength
  106 + T * p1;
  107 + T * p2;
  108 +
  109 + //get the bands numbers around the wavelength
  110 +
  111 + //if wavelength is smaller than the first one in header file
  112 + if ( header.wavelength[page] > wavelength ){
  113 + for(unsigned j = 0; j < header.samples; j++)
  114 + {
  115 + p[j] = c[j * B];
  116 + }
  117 + return true;
  118 + }
  119 +
  120 + while( header.wavelength[page] < wavelength )
  121 + {
  122 + page++;
  123 + //if wavelength is larger than the last wavelength in header file
  124 + if (page == B) {
  125 + for(unsigned j = 0; j < header.samples; j++)
  126 + {
  127 + p[j] = c[(j + 1) * B - 1];
  128 + }
  129 + return true;
  130 + }
  131 + }
  132 + if ( wavelength < header.wavelength[page] )
  133 + {
  134 + p1=(T*)malloc( X * sizeof(T)); //memory allocation
  135 + p2=(T*)malloc( X * sizeof(T));
  136 + //band_index(p1, page - 1);
  137 + for(unsigned j = 0; j < X; j++)
  138 + {
  139 + p1[j] = c[j * B + page - 1];
  140 + }
  141 + //band_index(p2, page );
  142 + for(unsigned j = 0; j < X; j++)
  143 + {
  144 + p2[j] = c[j * B + page];
  145 + }
  146 +
  147 + for(unsigned i=0; i < X; i++){
  148 + double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]);
  149 + p[i] = (p2[i] - p1[i]) * r + p1[i];
  150 + }
  151 + }
  152 + else //if the wavelength is equal to a wavelength in header file
  153 + {
  154 + //band_index(p, page);
  155 + for(unsigned j = 0; j < X; j++)
  156 + {
  157 + p[j] = c[j * B + page];
  158 + }
  159 + }
  160 +
  161 + return true;
  162 + }
  163 + //given a y and a wavelength, return the y-band data
  164 + //I do not use it right now, to accelerate the processing speed, I try to read a YZ whole slice into memory first, and then we can call "getYZ"
  165 + bool get_x_wavelength(T * p, unsigned y, double wavelength)
  166 + {
  167 + unsigned int X = header.samples; //calculate the number of pixels in a sample
  168 +
  169 + unsigned page=0; //samples around the wavelength
  170 + T * p1;
  171 + T * p2;
  172 +
  173 + //get the bands numbers around the wavelength
  174 +
  175 + //if wavelength is smaller than the first one in header file
  176 + if ( header.wavelength[page] > wavelength ){
  177 + file.seekg( y * header.bands * header.samples * sizeof(T), std::ios::beg);
  178 + for(unsigned j = 0; j < header.samples; j++)
  179 + {
  180 + file.read((char *)(p + j), sizeof(T));
  181 + file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  182 + }
  183 + return true;
  184 + }
  185 +
  186 + while( header.wavelength[page] < wavelength )
  187 + {
  188 + page++;
  189 + //if wavelength is larger than the last wavelength in header file
  190 + if (page == header.bands) {
  191 + file.seekg( (y * header.bands * header.samples + header.bands - 1)* sizeof(T), std::ios::beg);
  192 + for(unsigned j = 0; j < header.samples; j++)
  193 + {
  194 + file.read((char *)(p + j), sizeof(T));
  195 + file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  196 + }
  197 + return true;
  198 + }
  199 + }
  200 + if ( wavelength < header.wavelength[page] )
  201 + {
  202 + p1=(T*)malloc( X * sizeof(T)); //memory allocation
  203 + p2=(T*)malloc( X * sizeof(T));
  204 + //band_index(p1, page - 1);
  205 + file.seekg( (y * header.bands * header.samples + page - 1)* sizeof(T), std::ios::beg);
  206 + for(unsigned j = 0; j < header.samples; j++)
  207 + {
  208 + file.read((char *)(p1 + j), sizeof(T));
  209 + file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  210 + }
  211 + //band_index(p2, page );
  212 + file.seekg( (y * header.bands * header.samples + page)* sizeof(T), std::ios::beg);
  213 + for(unsigned j = 0; j < header.samples; j++)
  214 + {
  215 + file.read((char *)(p2 + j), sizeof(T));
  216 + file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  217 + }
  218 +
  219 + for(unsigned i=0; i < header.samples; i++){
  220 + double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]);
  221 + p[i] = (p2[i] - p1[i]) * r + p1[i];
  222 + }
  223 + }
  224 + else //if the wavelength is equal to a wavelength in header file
  225 + {
  226 + //band_index(p, page);
  227 + file.seekg( (y * header.bands * header.samples + page) * sizeof(T), std::ios::beg);
  228 + for(unsigned j = 0; j < header.samples; j++)
  229 + {
  230 + file.read((char *)(p + j), sizeof(T));
  231 + file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  232 + }
  233 + }
  234 +
  235 + //free(p1);
  236 + //free(p2);
  237 + return true;
  238 + }
92 239  
93 240 //save one pixel of the BIP file into the memory, and return the pointer
  241 + //I have not used it so far
94 242 bool getSpectrum(T * p, unsigned x, unsigned y){
95 243  
96 244 unsigned int i;
97 245  
98 246 if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right
99 247 std::cout<<"ERROR: sample or line out of range"<<std::endl;
100   - return false;
  248 + exit(1);
101 249 }
102 250  
103 251 file.seekg((x + y * header.samples) * header.bands * sizeof(T), std::ios::beg); //point to the certain sample and line
... ... @@ -106,158 +254,176 @@ public:
106 254  
107 255 return true;
108 256 }
109   - // not finished yet
110   - //(BIP) baseline correction
111   - bool baseline(std::string outname, std::vector<double> wls )
  257 +
  258 + //given a Y ,return a ZX slice
  259 + bool getY(T * p, unsigned y)
112 260 {
  261 + if ( y >= header.lines){ //make sure the line number is right
  262 + std::cout<<"ERROR: line out of range"<<std::endl;
  263 + exit(1);
  264 + }
  265 +
  266 + file.seekg(y * header.bands * header.samples * sizeof(T), std::ios::beg);
  267 + file.read((char *)p, sizeof(T) * header.bands * header.samples);
  268 +
  269 + return true;
  270 +
  271 + }
  272 +
  273 + //(BIP) baseline correction
  274 + //processing speed is too slow
  275 + bool baseline(std::string outname, std::vector<double> wls){
  276 +
113 277 unsigned N = wls.size(); //get the number of baseline points
114 278  
115 279 std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
116 280 std::string headername = outname + ".hdr"; //the header file name
117 281  
118 282 //simplify image resolution
119   - unsigned int B = header.bands; //calculate the number of bands
120   - unsigned int L = B * sizeof(T);
  283 + unsigned int ZX = header.bands * header.samples; //calculate the number of points in a Y slice
  284 + unsigned int L = ZX * sizeof(T); //calculate the number of bytes of a Y slice
  285 + unsigned int B = header.bands;
  286 + unsigned int X = header.samples;
121 287  
122   - T* c; //pointer to the current spectrum
123   - c = (T*)malloc(L);
124   -
125   - }
  288 + T* c; //pointer to the current Y slice
  289 + c = (T*)malloc(L); //memory allocation
126 290  
  291 + T* a; //pointer to the two YZ lines surrounding the current YZ line
  292 + T* b;
127 293  
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
  294 + a = (T*)malloc(X * sizeof(T));
  295 + b = (T*)malloc(X * sizeof(T));
137 296  
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 297  
143 298 double ai, bi; //stores the two baseline points wavelength surrounding the current band
144 299 double ci; //stores the current band's wavelength
145   -// unsigned aii, bii; //stores the two baseline points number surrounding the current band
146 300 unsigned control=0;
147 301  
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 302 if (a == NULL || b == NULL || c == NULL){
157 303 std::cout<<"ERROR: error allocating memory";
158 304 exit(1);
159 305 }
160   -
161   -
162   - //initialize lownum, highnum, low, high
163   - ai=header.wavelength[0];
164   -
165   - //if no baseline point is specified at band 0,
  306 + // loop start correct every y slice
  307 +
  308 + for (unsigned k =0; k < header.lines; k++)
  309 + {
  310 + //get the current y slice
  311 + getY(c, k);
  312 +
  313 + //initialize lownum, highnum, low, high
  314 + ai = header.wavelength[0];
  315 + //if no baseline point is specified at band 0,
166 316 //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);
  317 + if(wls[0] != header.wavelength[0]){
  318 + bi = wls[control];
  319 + memset(a, (char)0, X * sizeof(T) );
  320 + }
  321 + //else get the low band
  322 + else{
  323 + control++;
  324 + getYZ(a, c, ai);
  325 + bi = wls[control];
  326 + }
  327 + //get the high band
  328 + getYZ(b, c, bi);
  329 +
  330 + //correct every YZ line
  331 +
  332 + for(unsigned cii = 0; cii < B; cii++){
195 333  
  334 + //update baseline points, if necessary
  335 + if( header.wavelength[cii] >= bi && cii != B - 1) {
  336 + //if the high band is now on the last BL point?
  337 + if (control != N-1) {
  338 +
  339 + control++; //increment the index
  340 +
  341 + std::swap(a, b); //swap the baseline band pointers
  342 +
  343 + ai = bi;
  344 + bi = wls[control];
  345 + getYZ(b, c, bi);
  346 +
  347 + }
  348 + //if the last BL point on the last band of the file?
  349 + else if ( wls[control] < header.wavelength[B - 1]) {
  350 +
  351 + std::swap(a, b); //swap the baseline band pointers
  352 +
  353 + memset(b, (char)0, X * sizeof(T) ); //clear the high band
  354 +
  355 + ai = bi;
  356 + bi = header.wavelength[B - 1];
  357 + }
196 358 }
197   - //if the last BL point on the last band of the file?
198   - else if ( wls[control] < header.wavelength[B - 1]) {
199 359  
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];
  360 + //get the current YZ line
  361 + //band_index(c, cii);
  362 + file.seekg( (k * header.bands * X + cii)* sizeof(T), std::ios::beg);
  363 + for(unsigned j = 0; j < X; j++)
  364 + {
  365 + file.read((char *)(c + j), sizeof(T));
  366 + file.seekg((B - 1) * sizeof(T), std::ios::cur);
206 367 }
207   - }
208   -
209   - //get the current band
210   - band_index(c, cii);
211   - ci = header.wavelength[cii];
212 368  
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   - }
  369 + ci = header.wavelength[cii];
  370 +
  371 + //perform the baseline correction
  372 + for(unsigned i=0; i < X; i++)
  373 + {
  374 + double r = (double) (ci - ai) / (double) (bi - ai);
  375 + c[i * B + cii] =(float) ( c[i * B + cii] - (b[i] - a[i]) * r - a[i] );
  376 + }
  377 +
  378 + }//loop for YZ line end
218 379  
219   - target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination
  380 + target.write(reinterpret_cast<const char*>(c), L); //write the corrected data into destination
  381 + }//loop for Y slice end
220 382  
221   - }
222   -
223 383 header.save(headername); //save the new header file
224 384  
225 385 free(a);
226 386 free(b);
227 387 free(c);
228 388 target.close();
229   - return true;
  389 + return true;
  390 +
230 391 }
231   -*/
232   - // normalize the BSQ file
  392 +
  393 + // normalize the BIP file
233 394 bool normalize(std::string outname, double band)
234 395 {
235 396 unsigned int B = header.bands; //calculate the number of bands
  397 + unsigned int Y = header.lines;
  398 + unsigned int X = header.samples;
  399 + unsigned int ZX = header.bands * header.samples;
236 400 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
  401 + unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band
  402 + unsigned int L = ZX * sizeof(T);
238 403  
239 404 std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
240 405 std::string headername = outname + ".hdr"; //the header file name
241 406  
242   - T * b; //pointers to the certain wavelength band
243   - T * c; //pointer to the current image
  407 + T * c; //pointer to the current ZX slice
  408 + T * b; //pointer to the standard band
244 409  
245 410 b = (T*)malloc( S ); //memory allocation
246   - c = (T*)malloc( S );
  411 + c = (T*)malloc( L );
247 412  
248 413 getBand(b, band); //get the certain band into memory
249 414  
250   - for(unsigned j = 0; j < B; j++)
  415 + for(unsigned j = 0; j < Y; j++)
251 416 {
252   - band_index(c, j); //get the current band into memory
253   - for(unsigned i = 0; i < XY; i++)
  417 + getY(c, j);
  418 + for(unsigned i = 0; i < X; i++)
254 419 {
255   - c[i] = c[i] / b[i];
  420 + for(unsigned m = 0; m < B; m++)
  421 + {
  422 + c[m + i * B] = c[m + i * B] / b[i + j * X];
  423 + }
256 424 }
257   - target.write(reinterpret_cast<const char*>(c), S); //write normalized data into destination
258   - std::cout<<j<<std::endl;
  425 + target.write(reinterpret_cast<const char*>(c), L); //write normalized data into destination
259 426 }
260   -
261 427 header.save(headername); //save the new header file
262 428  
263 429 free(b);
... ... @@ -266,6 +432,29 @@ public:
266 432 return true;
267 433 }
268 434  
  435 + //convert BIP file to BSQ file and save it
  436 + bool bsq(std::string outname)
  437 + {
  438 + unsigned int S = header.samples * header.lines * sizeof(T); //calculate the number of bytes in a band
  439 +
  440 + std::ofstream target(outname.c_str(), std::ios::binary);
  441 + std::string headername = outname + ".hdr";
  442 +
  443 + T * p; //pointer to the current band
  444 + p = (T*)malloc(S);
  445 +
  446 + for ( unsigned i = 0; i < header.bands; i++)
  447 + {
  448 + band_index(p, i);
  449 + target.write(reinterpret_cast<const char*>(p), S); //write a band data into target file
  450 + }
  451 + header.interleave = rts::envi::interleaveType::BSQ; //change the type of file in header file
  452 + header.save(headername);
  453 +
  454 + free(p);
  455 + target.close();
  456 + return true;
  457 + }
269 458  
270 459 };
271 460 }
272 461 \ No newline at end of file
... ...