Commit 798cea97b3b181a1fe8adf06738fac398abf8daf

Authored by David Mayerich
1 parent c1078e19

added progress bars to making masks, fixed overflow error in baseline correction

stim/envi/bil.h
... ... @@ -230,7 +230,7 @@ public:
230 230  
231 231 /// @param outname is the name of the output file used to store the resulting baseline-corrected data.
232 232 /// @param wls is the list of baseline points based on band labels.
233   - bool baseline(std::string outname, std::vector<double> wls, bool PROGRESS = false){
  233 + bool baseline(std::string outname, std::vector<double> wls, unsigned char* mask = NULL, bool PROGRESS = false){
234 234  
235 235 unsigned N = wls.size(); //get the number of baseline points
236 236  
... ... @@ -345,7 +345,7 @@ public:
345 345 /// @param outname is the name of the output file used to store the resulting baseline-corrected data.
346 346 /// @param w is the label specifying the band that the hyperspectral image will be normalized to.
347 347 /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers.
348   - bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false)
  348 + bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false)
349 349 {
350 350 unsigned int B = Z(); //calculate the number of bands
351 351 unsigned int ZX = Z() * X();
... ... @@ -371,7 +371,7 @@ public:
371 371 {
372 372 for(unsigned m = 0; m < X(); m++)
373 373 {
374   - if( b[m + j * X()] < t )
  374 + if( mask != NULL && !mask[m + j * X()] )
375 375 c[m + i * X()] = (T)0.0;
376 376 else
377 377 c[m + i * X()] = c[m + i * X()] / b[m + j * X()];
... ... @@ -792,16 +792,16 @@ public:
792 792 /// @param mask_band is the band used to specify the mask
793 793 /// @param threshold is the threshold used to determine if the mask value is true or false
794 794 /// @param p is a pointer to a pre-allocated array at least X * Y in size
795   - bool build_mask(double mask_band, double threshold, unsigned char* p){
  795 + bool build_mask(double mask_band, double threshold, unsigned char* p, bool PROGRESS = false){
796 796  
797 797 T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band
798   - band(temp, mask_band);
  798 + band(temp, mask_band, PROGRESS);
799 799  
800 800 for (unsigned int i = 0; i < X() * Y(); i++) {
801   - if (temp[i] < threshold)
802   - p[i] = 0;
803   - else
804   - p[i] = 255;
  801 + if (temp[i] < threshold)
  802 + p[i] = 0;
  803 + else
  804 + p[i] = 255;
805 805 }
806 806  
807 807 free(temp);
... ...
stim/envi/bip.h
... ... @@ -31,13 +31,13 @@ protected:
31 31 std::vector<double> w; //band wavelength
32 32 unsigned int offset; //header offset
33 33  
34   - unsigned long X(){
  34 + unsigned long long X(){
35 35 return R[1];
36 36 }
37   - unsigned long Y(){
  37 + unsigned long long Y(){
38 38 return R[2];
39 39 }
40   - unsigned long Z(){
  40 + unsigned long long Z(){
41 41 return R[0];
42 42 }
43 43  
... ... @@ -318,10 +318,9 @@ public:
318 318  
319 319 /// @param outname is the name of the output file used to store the resulting baseline-corrected data.
320 320 /// @param wls is the list of baseline points based on band labels.
321   - bool baseline(std::string outname, std::vector<double> base_pts, bool PROGRESS = false){
  321 + bool baseline(std::string outname, std::vector<double> base_pts, unsigned char* mask = NULL, bool PROGRESS = false){
322 322  
323 323 std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
324   - std::string headername = outname + ".hdr"; //the header file name
325 324  
326 325 unsigned long long N = X() * Y(); //calculate the total number of pixels to be processed
327 326 unsigned long long B = Z(); //get the number of bands
... ... @@ -334,30 +333,36 @@ public:
334 333 double alpha;
335 334 unsigned long long ai, bi; //surrounding baseline point band indices
336 335 for(unsigned long long n = 0; n < N; n++){ //for each pixel in the image
337   - pixel(s, n); //retrieve the spectrum s
338   - base_vals = interp_spectrum(s, base_pts); //get the values at each baseline point
339   -
340   - ai = bi = 0;
341   - aw = w[0]; //initialize the current baseline points (assume the spectrum starts at 0)
342   - av = s[0];
343   - bw = base_pts[0];
344   - for(unsigned long long b = 0; b < B; b++){ //for each band in the spectrum
345   - while(bi < base_pts.size() && base_pts[bi] < w[b]) //while the current wavelength is higher than the second baseline point
346   - bi++; //move to the next baseline point
347   - if(bi < base_pts.size()){
348   - bw = base_pts[bi]; //set the wavelength for the upper bound baseline point
349   - bv = base_vals[bi]; //set the value for the upper bound baseline point
350   - }
351   - if(bi == base_pts.size()){ //if we have passed the last baseline point
352   - bw = w[B-1]; //set the outer bound to the last spectral band
353   - bv = s[B-1];
354   - }
355   - if(bi != 0){
356   - ai = bi - 1; //set the lower bound baseline point index
357   - aw = base_pts[ai]; //set the wavelength for the lower bound baseline point
358   - av = base_vals[ai]; //set the value for the lower bound baseline point
  336 + if(mask != NULL && !mask[n]){ //if the pixel isn't masked
  337 + memset(sbc, 0, sizeof(T) * B); //set the baseline corrected spectrum to zero
  338 + }
  339 + else{
  340 +
  341 + pixel(s, n); //retrieve the spectrum s
  342 + base_vals = interp_spectrum(s, base_pts); //get the values at each baseline point
  343 +
  344 + ai = bi = 0;
  345 + aw = w[0]; //initialize the current baseline points (assume the spectrum starts at 0)
  346 + av = s[0];
  347 + bw = base_pts[0];
  348 + for(unsigned long long b = 0; b < B; b++){ //for each band in the spectrum
  349 + while(bi < base_pts.size() && base_pts[bi] < w[b]) //while the current wavelength is higher than the second baseline point
  350 + bi++; //move to the next baseline point
  351 + if(bi < base_pts.size()){
  352 + bw = base_pts[bi]; //set the wavelength for the upper bound baseline point
  353 + bv = base_vals[bi]; //set the value for the upper bound baseline point
  354 + }
  355 + if(bi == base_pts.size()){ //if we have passed the last baseline point
  356 + bw = w[B-1]; //set the outer bound to the last spectral band
  357 + bv = s[B-1];
  358 + }
  359 + if(bi != 0){
  360 + ai = bi - 1; //set the lower bound baseline point index
  361 + aw = base_pts[ai]; //set the wavelength for the lower bound baseline point
  362 + av = base_vals[ai]; //set the value for the lower bound baseline point
  363 + }
  364 + sbc[b] = s[b] - lerp(w[b], av, aw, bv, bw); //perform the baseline correction and save the new value
359 365 }
360   - sbc[b] = s[b] - lerp(w[b], av, aw, bv, bw); //perform the baseline correction and save the new value
361 366 }
362 367  
363 368 if(PROGRESS) progress = (double)(n+1) / N * 100; //set the current progress
... ... @@ -378,7 +383,7 @@ public:
378 383 /// @param outname is the name of the output file used to store the resulting baseline-corrected data.
379 384 /// @param w is the label specifying the band that the hyperspectral image will be normalized to.
380 385 /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers.
381   - bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false)
  386 + bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false)
382 387 {
383 388 std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
384 389 std::string headername = outname + ".hdr"; //the header file name
... ... @@ -390,7 +395,7 @@ public:
390 395 for(unsigned long long n = 0; n < N; n++){ //for each pixel in the image
391 396 pixel(s, n); //retrieve the spectrum s
392 397 nv = interp_spectrum(s, w); //find the value of the normalization band
393   - if(abs(nv) <= t) //if the normalization band is below threshold
  398 + if(mask != NULL && !mask[n]) //if the normalization band is below threshold
394 399 memset(s, 0, sizeof(T) * B); //set the output to zero
395 400 else{
396 401 for(unsigned long long b = 0; b < B; b++){ //for each band in the spectrum
... ... @@ -784,16 +789,16 @@ public:
784 789 /// @param mask_band is the band used to specify the mask
785 790 /// @param threshold is the threshold used to determine if the mask value is true or false
786 791 /// @param p is a pointer to a pre-allocated array at least X * Y in size
787   - bool build_mask(double mask_band, double threshold, unsigned char* p){
  792 + bool build_mask(double mask_band, double threshold, unsigned char* p, bool PROGRESS = false){
788 793  
789 794 T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band
790   - band(temp, mask_band);
  795 + band(temp, mask_band, PROGRESS);
791 796  
792 797 for (unsigned int i = 0; i < X() * Y();i++) {
793   - if (temp[i] < threshold)
794   - p[i] = 0;
795   - else
796   - p[i] = 255;
  798 + if (temp[i] < threshold)
  799 + p[i] = 0;
  800 + else
  801 + p[i] = 255;
797 802 }
798 803  
799 804 free(temp);
... ...
stim/envi/bsq.h
... ... @@ -172,9 +172,8 @@ public:
172 172  
173 173 /// @param outname is the name of the output file used to store the resulting baseline-corrected data.
174 174 /// @param wls is the list of baseline points based on band labels.
175   - bool baseline(std::string outname, std::vector<double> wls, bool PROGRESS = false )
  175 + bool baseline(std::string outname, std::vector<double> wls, unsigned char* mask = NULL, bool PROGRESS = false )
176 176 {
177   - if(PROGRESS) progress = 0;
178 177 unsigned N = wls.size(); //get the number of baseline points
179 178  
180 179 std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
... ... @@ -257,8 +256,12 @@ public:
257 256  
258 257 //perform the baseline correction
259 258 for(unsigned i=0; i < XY; i++){
260   - double r = (double) (ci - ai) / (double) (bi - ai);
261   - c[i] =(T) ( c[i] - (b[i] - a[i]) * r - a[i] );
  259 + if(mask != NULL && !mask[i]) //if the pixel is excluded by a mask
  260 + c[i] = 0; //set the value to zero
  261 + else{
  262 + double r = (double) (ci - ai) / (double) (bi - ai);
  263 + c[i] =(T) ( c[i] - (b[i] - a[i]) * r - a[i] );
  264 + }
262 265 }
263 266  
264 267 target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination
... ... @@ -282,7 +285,7 @@ public:
282 285 /// @param outname is the name of the output file used to store the resulting baseline-corrected data.
283 286 /// @param w is the label specifying the band that the hyperspectral image will be normalized to.
284 287 /// @param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers.
285   - bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false)
  288 + bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false)
286 289 {
287 290 unsigned int B = Z(); //calculate the number of bands
288 291 unsigned int XY = X() * Y(); //calculate the number of pixels in a band
... ... @@ -304,7 +307,7 @@ public:
304 307 band_index(c, j); //get the current band into memory
305 308 for(unsigned i = 0; i < XY; i++)
306 309 {
307   - if(b[i] < t)
  310 + if(mask != NULL && !mask[i])
308 311 c[i] = (T)0.0;
309 312 else
310 313 c[i] = c[i] / b[i];
... ... @@ -698,16 +701,18 @@ public:
698 701 /// @param mask_band is the band used to specify the mask
699 702 /// @param threshold is the threshold used to determine if the mask value is true or false
700 703 /// @param p is a pointer to a pre-allocated array at least X * Y in size
701   - bool build_mask(double mask_band, double threshold, unsigned char* p = NULL){
  704 + bool build_mask(double mask_band, double threshold, unsigned char* p = NULL, bool PROGRESS = false){
702 705  
703 706 T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band
704 707 band(temp, mask_band);
705 708  
706 709 for (unsigned int i = 0; i < X() * Y(); i++) {
707   - if (temp[i] < threshold)
708   - p[i] = 0;
709   - else
710   - p[i] = 255;
  710 + if (temp[i] < threshold)
  711 + p[i] = 0;
  712 + else
  713 + p[i] = 255;
  714 +
  715 + if(PROGRESS) progress = (double) (i+1) / (X() * Y());
711 716 }
712 717  
713 718 free(temp);
... ...
stim/envi/envi.h
... ... @@ -213,31 +213,31 @@ public:
213 213 /// @param outfile is the name of the normalized file to be output
214 214 /// @param band is the band label to be output
215 215 /// @param threshold is a threshold value specified such that normalization will only be done to values in the band > threshold (preventing division by small numbers)
216   - bool normalize(std::string outfile, double band, double threshold = 0.0, bool PROGRESS = false){
  216 + bool normalize(std::string outfile, double band, unsigned char* mask = NULL, bool PROGRESS = false){
217 217  
218 218 if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
219 219 if(header.data_type ==envi_header::float32)
220   - return ((bsq<float>*)file)->normalize(outfile, band, threshold, PROGRESS);
  220 + return ((bsq<float>*)file)->normalize(outfile, band, mask, PROGRESS);
221 221 else if(header.data_type == envi_header::float64)
222   - return ((bsq<double>*)file)->normalize(outfile,band, threshold, PROGRESS);
  222 + return ((bsq<double>*)file)->normalize(outfile,band, mask, PROGRESS);
223 223 else
224 224 std::cout<<"ERROR: unidentified data type"<<std::endl;
225 225 }
226 226  
227 227 else if(header.interleave == envi_header::BIL){ //if the infile is bil file
228 228 if(header.data_type ==envi_header::float32)
229   - return ((bil<float>*)file)->normalize(outfile, band, threshold, PROGRESS);
  229 + return ((bil<float>*)file)->normalize(outfile, band, mask, PROGRESS);
230 230 else if(header.data_type == envi_header::float64)
231   - return ((bil<double>*)file)->normalize(outfile,band, threshold, PROGRESS);
  231 + return ((bil<double>*)file)->normalize(outfile,band, mask, PROGRESS);
232 232 else
233 233 std::cout<<"ERROR: unidentified data type"<<std::endl;
234 234 }
235 235  
236 236 else if(header.interleave == envi_header::BIP){ //if the infile is bip file
237 237 if(header.data_type ==envi_header::float32)
238   - return ((bip<float>*)file)->normalize(outfile, band, threshold, PROGRESS);
  238 + return ((bip<float>*)file)->normalize(outfile, band, mask, PROGRESS);
239 239 else if(header.data_type == envi_header::float64)
240   - return ((bip<double>*)file)->normalize(outfile,band, threshold, PROGRESS);
  240 + return ((bip<double>*)file)->normalize(outfile,band, mask, PROGRESS);
241 241 else
242 242 std::cout<<"ERROR: unidentified data type"<<std::endl;
243 243 }
... ... @@ -253,13 +253,13 @@ public:
253 253  
254 254 /// @param outfile is the file name for the baseline corrected output
255 255 /// @param w is a list of band labels to serve as baseline points (zero values)
256   - bool baseline(std::string outfile, std::vector<double> w, bool PROGRESS){
257   -
  256 + bool baseline(std::string outfile, std::vector<double> w, unsigned char* mask = NULL, bool PROGRESS = false){
  257 + header.save(outfile + ".hdr");
258 258 if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
259 259 if(header.data_type ==envi_header::float32)
260   - return ((bsq<float>*)file)->baseline(outfile, w, PROGRESS);
  260 + return ((bsq<float>*)file)->baseline(outfile, w, mask, PROGRESS);
261 261 else if(header.data_type == envi_header::float64)
262   - return ((bsq<double>*)file)->baseline(outfile,w, PROGRESS);
  262 + return ((bsq<double>*)file)->baseline(outfile,w, mask, PROGRESS);
263 263 else{
264 264 std::cout<<"ERROR: unidentified data type"<<std::endl;
265 265 exit(1);
... ... @@ -268,9 +268,9 @@ public:
268 268  
269 269 else if(header.interleave == envi_header::BIL){ //if the infile is bil file
270 270 if(header.data_type ==envi_header::float32)
271   - return ((bil<float>*)file)->baseline(outfile, w, PROGRESS);
  271 + return ((bil<float>*)file)->baseline(outfile, w, mask, PROGRESS);
272 272 else if(header.data_type == envi_header::float64)
273   - return ((bil<double>*)file)->baseline(outfile, w, PROGRESS);
  273 + return ((bil<double>*)file)->baseline(outfile, w, mask, PROGRESS);
274 274 else{
275 275 std::cout<<"ERROR: unidentified data type"<<std::endl;
276 276 exit(1);
... ... @@ -279,9 +279,9 @@ public:
279 279  
280 280 else if(header.interleave == envi_header::BIP){ //if the infile is bip file
281 281 if(header.data_type ==envi_header::float32)
282   - return ((bip<float>*)file)->baseline(outfile, w, PROGRESS);
  282 + return ((bip<float>*)file)->baseline(outfile, w, mask, PROGRESS);
283 283 else if(header.data_type == envi_header::float64)
284   - return ((bip<double>*)file)->baseline(outfile, w, PROGRESS);
  284 + return ((bip<double>*)file)->baseline(outfile, w, mask, PROGRESS);
285 285 else{
286 286 std::cout<<"ERROR: unidentified data type"<<std::endl;
287 287 exit(1);
... ... @@ -469,31 +469,31 @@ public:
469 469 /// @param mask_band is the label for the band that will be used to build the mask
470 470 /// @param threshold is a value selected such that all band values greater than threshold will have a mask value of 'true'
471 471 /// @param p is memory of size X*Y that will store the resulting mask
472   - bool build_mask(double mask_band, double threshold, unsigned char* p = NULL) {
  472 + bool build_mask(double mask_band, double threshold, unsigned char* p = NULL, bool PROGRESS = false) {
473 473  
474 474 if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
475 475 if(header.data_type ==envi_header::float32)
476   - return ((bsq<float>*)file)->build_mask(mask_band, threshold, p);
  476 + return ((bsq<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS);
477 477 else if(header.data_type == envi_header::float64)
478   - return ((bsq<double>*)file)->build_mask(mask_band, threshold, p);
  478 + return ((bsq<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS);
479 479 else
480 480 std::cout<<"ERROR: unidentified data type"<<std::endl;
481 481 }
482 482  
483 483 else if(header.interleave == envi_header::BIL){ //if the infile is bil file
484 484 if(header.data_type ==envi_header::float32)
485   - return ((bil<float>*)file)->build_mask(mask_band, threshold, p);
  485 + return ((bil<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS);
486 486 else if(header.data_type == envi_header::float64)
487   - return ((bil<double>*)file)->build_mask(mask_band, threshold, p);
  487 + return ((bil<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS);
488 488 else
489 489 std::cout<<"ERROR: unidentified data type"<<std::endl;
490 490 }
491 491  
492 492 else if(header.interleave == envi_header::BIP){ //if the infile is bip file
493 493 if(header.data_type ==envi_header::float32)
494   - return ((bip<float>*)file)->build_mask(mask_band, threshold, p);
  494 + return ((bip<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS);
495 495 else if(header.data_type == envi_header::float64)
496   - return ((bip<double>*)file)->build_mask(mask_band, threshold, p);
  496 + return ((bip<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS);
497 497 else
498 498 std::cout<<"ERROR: unidentified data type"<<std::endl;
499 499 }
... ...