Commit 2fcab4f0ac9acea44993a954725c74cf8e36b0af
1 parent
40a669b8
added unsifting for BSQ files (BIP and BIL still not supported)
Showing
4 changed files
with
118 additions
and
12 deletions
Show diff stats
stim/envi/bil.h
@@ -826,7 +826,7 @@ public: | @@ -826,7 +826,7 @@ public: | ||
826 | } | 826 | } |
827 | 827 | ||
828 | ///Saves to disk only those spectra corresponding to mask values != 0 | 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 | // Assume X() = X, Y() = Y, Z() = Z. | 830 | // Assume X() = X, Y() = Y, Z() = Z. |
831 | std::ofstream target(outfile.c_str(), std::ios::binary); | 831 | std::ofstream target(outfile.c_str(), std::ios::binary); |
832 | 832 |
stim/envi/bip.h
@@ -836,8 +836,8 @@ public: | @@ -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 | // Assume X() = X, Y() = Y, Z() = Z. | 841 | // Assume X() = X, Y() = Y, Z() = Z. |
842 | std::ofstream target(outfile.c_str(), std::ios::binary); | 842 | std::ofstream target(outfile.c_str(), std::ios::binary); |
843 | 843 |
stim/envi/bsq.h
@@ -759,8 +759,8 @@ public: | @@ -759,8 +759,8 @@ public: | ||
759 | return true; | 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 | std::ofstream target(outfile.c_str(), std::ios::binary); | 764 | std::ofstream target(outfile.c_str(), std::ios::binary); |
765 | // open a band (XY plane) | 765 | // open a band (XY plane) |
766 | unsigned XY = X() * Y(); //Number of XY pixels | 766 | unsigned XY = X() * Y(); //Number of XY pixels |
@@ -788,6 +788,57 @@ public: | @@ -788,6 +788,57 @@ public: | ||
788 | return true; | 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 | /// Calculate the mean band value (average along B) at each pixel location. | 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,32 +373,48 @@ public: | ||
373 | } | 373 | } |
374 | 374 | ||
375 | /// sift-mask saves in an array only those spectra corresponding to nonzero values of the mask. | 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 | if (header.interleave == envi_header::BSQ){ //if the infile is bsq file | 395 | if (header.interleave == envi_header::BSQ){ //if the infile is bsq file |
380 | if (header.data_type == envi_header::float32) | 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 | else if (header.data_type == envi_header::float64) | 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 | else | 400 | else |
385 | std::cout << "ERROR: unidentified data type" << std::endl; | 401 | std::cout << "ERROR: unidentified data type" << std::endl; |
386 | } | 402 | } |
387 | 403 | ||
388 | else if (header.interleave == envi_header::BIL){ //if the infile is bil file | 404 | else if (header.interleave == envi_header::BIL){ //if the infile is bil file |
389 | if (header.data_type == envi_header::float32) | 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 | else if (header.data_type == envi_header::float64) | 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 | else | 409 | else |
394 | std::cout << "ERROR: unidentified data type" << std::endl; | 410 | std::cout << "ERROR: unidentified data type" << std::endl; |
395 | } | 411 | } |
396 | 412 | ||
397 | else if (header.interleave == envi_header::BIP){ //if the infile is bip file | 413 | else if (header.interleave == envi_header::BIP){ //if the infile is bip file |
398 | if (header.data_type == envi_header::float32) | 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 | else if (header.data_type == envi_header::float64) | 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 | else | 418 | else |
403 | std::cout << "ERROR: unidentified data type" << std::endl; | 419 | std::cout << "ERROR: unidentified data type" << std::endl; |
404 | } | 420 | } |
@@ -407,9 +423,48 @@ public: | @@ -407,9 +423,48 @@ public: | ||
407 | std::cout << "ERROR: unidentified file type" << std::endl; | 423 | std::cout << "ERROR: unidentified file type" << std::endl; |
408 | exit(1); | 424 | exit(1); |
409 | } | 425 | } |
426 | + | ||
427 | + | ||
410 | return false; | 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 | /// Compute the ratio of two baseline-corrected peaks. The result is stored in a pre-allocated array. | 468 | /// Compute the ratio of two baseline-corrected peaks. The result is stored in a pre-allocated array. |
414 | 469 | ||
415 | /// @param lb1 is the label value for the left baseline point for the first peak (numerator) | 470 | /// @param lb1 is the label value for the left baseline point for the first peak (numerator) |