Commit 2fcab4f0ac9acea44993a954725c74cf8e36b0af

Authored by David Mayerich
1 parent 40a669b8

added unsifting for BSQ files (BIP and BIL still not supported)

stim/envi/bil.h
... ... @@ -826,7 +826,7 @@ public:
826 826 }
827 827  
828 828 ///Saves to disk only those spectra corresponding to mask values != 0
829   - bool sift_mask(std::string outfile, unsigned char* p){
  829 + bool sift(std::string outfile, unsigned char* p){
830 830 // Assume X() = X, Y() = Y, Z() = Z.
831 831 std::ofstream target(outfile.c_str(), std::ios::binary);
832 832  
... ...
stim/envi/bip.h
... ... @@ -836,8 +836,8 @@ public:
836 836 }
837 837  
838 838  
839   - ///Saves to disk only those spectra corresponding to mask values != 0
840   - bool sift_mask(std::string outfile, unsigned char* p){
  839 + /// Saves to disk only those spectra corresponding to mask values != 0
  840 + bool sift(std::string outfile, unsigned char* p){
841 841 // Assume X() = X, Y() = Y, Z() = Z.
842 842 std::ofstream target(outfile.c_str(), std::ios::binary);
843 843  
... ...
stim/envi/bsq.h
... ... @@ -759,8 +759,8 @@ public:
759 759 return true;
760 760 }
761 761  
762   - ///Saves to disk only those spectra corresponding to mask values != 0
763   - bool sift_mask(std::string outfile, unsigned char* p){
  762 + /// Saves to disk only those spectra corresponding to mask values != 0
  763 + bool sift(std::string outfile, unsigned char* p){
764 764 std::ofstream target(outfile.c_str(), std::ios::binary);
765 765 // open a band (XY plane)
766 766 unsigned XY = X() * Y(); //Number of XY pixels
... ... @@ -788,6 +788,57 @@ public:
788 788 return true;
789 789 }
790 790  
  791 + /// Generates a spectral image from a matrix of spectral values in lexicographic order and a mask
  792 + bool unsift(std::string outfile, unsigned char* p, unsigned int samples, unsigned int lines){
  793 +
  794 + //create a binary output stream
  795 + std::ofstream target(outfile.c_str(), std::ios::binary);
  796 +
  797 + //make sure that there's only one line
  798 + if(Y() != 1){
  799 + std::cout<<"ERROR in stim::bsq::sift() - number of lines does not equal 1"<<std::endl;
  800 + return false;
  801 + }
  802 +
  803 + std::cout<<"started sifting"<<std::endl;
  804 +
  805 + //get the number of pixels and bands in the input image
  806 + unsigned int P = X(); //Number of pixels
  807 + unsigned int B = Z(); //number of bands
  808 + unsigned int XY = samples * lines; //total number of pixels in an unsifted image
  809 +
  810 + // allocate memory for a sifted band
  811 + T * sifted = (T*)malloc(P * sizeof(T)); //allocate memory for a band
  812 +
  813 + //allocate memory for an unsifted band image
  814 + T* unsifted = (T*) malloc(XY * sizeof(T));
  815 +
  816 + //for each band
  817 + for(unsigned int b = 0; b < B; b++){
  818 +
  819 + //set the unsifted index value to zero
  820 + unsigned int i = 0;
  821 +
  822 + //retrieve the sifted band (masked pixels only)
  823 + band_index(sifted, b);
  824 +
  825 + //for each pixel in the final image (treat it as a 1D image)
  826 + for(unsigned int xi = 0; xi < XY; xi++){
  827 + if( p[xi] == 0 )
  828 + unsifted[xi] = 0;
  829 + else{
  830 + unsifted[xi] = sifted[i];
  831 + i++;
  832 + }
  833 + }
  834 +
  835 + //write the band image to disk
  836 + target.write(reinterpret_cast<const char*>(unsifted), sizeof(T) * XY);
  837 + }
  838 +
  839 + return true;
  840 + }
  841 +
791 842  
792 843 /// Calculate the mean band value (average along B) at each pixel location.
793 844  
... ...
stim/envi/envi.h
... ... @@ -373,32 +373,48 @@ public:
373 373 }
374 374  
375 375 /// sift-mask saves in an array only those spectra corresponding to nonzero values of the mask.
376   - bool sift_mask(std::string outfile, unsigned char* p)
  376 + bool sift(std::string outfile, unsigned char* p)
377 377 {
378 378  
  379 + //calculate the number of non-zero values in the mask
  380 + unsigned int nnz = 0;
  381 + unsigned int npixels = header.lines * header.samples;
  382 + for(unsigned int i = 0; i < npixels; i++)
  383 + if( p[i] > 0 ) nnz++;
  384 +
  385 + //create a new header
  386 + envi_header new_header = header;
  387 +
  388 + //set the number of lines to 1 (this is a matrix with 1 line and N samples)
  389 + new_header.lines = 1;
  390 + new_header.samples = nnz;
  391 + new_header.save(outfile + ".hdr");
  392 +
  393 + std::cout<<"Saved: "<<outfile+".hdr"<<std::endl;
  394 +
379 395 if (header.interleave == envi_header::BSQ){ //if the infile is bsq file
380 396 if (header.data_type == envi_header::float32)
381   - return ((bsq<float>*)file)->sift_mask(outfile, p);
  397 + return ((bsq<float>*)file)->sift(outfile, p);
382 398 else if (header.data_type == envi_header::float64)
383   - return ((bsq<double>*)file)->sift_mask(outfile, p);
  399 + return ((bsq<double>*)file)->sift(outfile, p);
384 400 else
385 401 std::cout << "ERROR: unidentified data type" << std::endl;
386 402 }
387 403  
388 404 else if (header.interleave == envi_header::BIL){ //if the infile is bil file
389 405 if (header.data_type == envi_header::float32)
390   - return ((bil<float>*)file)->sift_mask(outfile, p);
  406 + return ((bil<float>*)file)->sift(outfile, p);
391 407 else if (header.data_type == envi_header::float64)
392   - return ((bil<double>*)file)->sift_mask(outfile, p);
  408 + return ((bil<double>*)file)->sift(outfile, p);
393 409 else
394 410 std::cout << "ERROR: unidentified data type" << std::endl;
395 411 }
396 412  
397 413 else if (header.interleave == envi_header::BIP){ //if the infile is bip file
398 414 if (header.data_type == envi_header::float32)
399   - return ((bip<float>*)file)->sift_mask(outfile, p);
  415 + return ((bip<float>*)file)->sift(outfile, p);
400 416 else if (header.data_type == envi_header::float64)
401   - return ((bip<double>*)file)->sift_mask(outfile, p);
  417 + return ((bip<double>*)file)->sift(outfile, p);
402 418 else
403 419 std::cout << "ERROR: unidentified data type" << std::endl;
404 420 }
... ... @@ -407,9 +423,48 @@ public:
407 423 std::cout << "ERROR: unidentified file type" << std::endl;
408 424 exit(1);
409 425 }
  426 +
  427 +
410 428 return false;
411 429 }
412 430  
  431 + bool unsift(std::string outfile, unsigned char* mask, unsigned int samples, unsigned int lines){
  432 +
  433 + //create a new header
  434 + envi_header new_header = header;
  435 +
  436 + //set the number of lines and samples in the output file (that's all that changes)
  437 + new_header.lines = lines;
  438 + new_header.samples = samples;
  439 + new_header.save(outfile + ".hdr");
  440 +
  441 +
  442 + if (header.interleave == envi_header::BSQ){ //if the infile is bsq file
  443 + if (header.data_type == envi_header::float32)
  444 + return ((bsq<float>*)file)->unsift(outfile, mask, samples, lines);
  445 + else if (header.data_type == envi_header::float64)
  446 + return ((bsq<double>*)file)->unsift(outfile, mask, samples, lines);
  447 + else
  448 + std::cout << "ERROR: unidentified data type" << std::endl;
  449 + }
  450 +
  451 + else if (header.interleave == envi_header::BIL){ //if the infile is bil file
  452 +
  453 + std::cout << "ERROR in stim::envi::unsift - BIL files aren't supported yet" << std::endl;
  454 + }
  455 +
  456 + else if (header.interleave == envi_header::BIP){ //if the infile is bip file
  457 +
  458 + std::cout << "ERROR in stim::envi::unsift - BIP files aren't supported yet" << std::endl;
  459 + }
  460 +
  461 + else{
  462 + std::cout << "ERROR: unidentified file type" << std::endl;
  463 + exit(1);
  464 + }
  465 +
  466 + }
  467 +
413 468 /// Compute the ratio of two baseline-corrected peaks. The result is stored in a pre-allocated array.
414 469  
415 470 /// @param lb1 is the label value for the left baseline point for the first peak (numerator)
... ...