Commit 3d0b6243c6e8fe045c1aeef57b785c1a32711531

Authored by David Mayerich
1 parent 2aa68315

fixed hsiproc bugs, added insert() method into stim::filename, added Matlab func…

…tion to save ENVI files
stim/envi/binary.h
@@ -81,7 +81,7 @@ protected: @@ -81,7 +81,7 @@ protected:
81 81
82 //if the file isn't open, the user may only have read access 82 //if the file isn't open, the user may only have read access
83 if(!file.is_open()){ 83 if(!file.is_open()){
84 - std::cout<<"class BINARY - failed to open file, trying for read only"<<std::endl; 84 + std::cout<<"class STIM::BINARY - failed to open file, trying for read only"<<std::endl;
85 file.open(filename.c_str(), std::ios::in | std::ios::binary); 85 file.open(filename.c_str(), std::ios::in | std::ios::binary);
86 if(!file.is_open()){ 86 if(!file.is_open()){
87 std::cout<<" still unable to load the file"<<std::endl; 87 std::cout<<" still unable to load the file"<<std::endl;
@@ -776,49 +776,46 @@ public: @@ -776,49 +776,46 @@ public:
776 return true; 776 return true;
777 } 777 }
778 778
779 - /// Saves only those pixels in a band corresponding to the mask value != 0  
780 - /// @param array is a pointer to the destination array used to store the data  
781 - /// @param i is the band index  
782 - /// @p is a pointer to the mask data  
783 - bool sift_band(T* values, unsigned long b, unsigned char* p){ 779 + /// Copies all spectra corresponding to nonzero values of a mask into a pre-allocated matrix of size (B x P)
  780 + /// where P is the number of masked pixels and B is the number of bands. The allocated memory can be accessed
  781 + /// using the following indexing: i = p*B + b
  782 + /// @param matrix is the destination for the pixel data
  783 + /// @param mask is the mask
  784 + bool sift(T* matrix, unsigned char* mask){
784 unsigned long long XY = X() * Y(); //Number of XY pixels 785 unsigned long long XY = X() * Y(); //Number of XY pixels
785 unsigned long long L = XY * sizeof(T); //size of XY plane (in bytes) 786 unsigned long long L = XY * sizeof(T); //size of XY plane (in bytes)
786 -  
787 - unsigned long long vi = 0; //create an index into the values array  
788 -  
789 - unsigned long long start, end; //start and end indices of a block of masked pixels in the band  
790 - bool reading = false;  
791 - unsigned long long l, i; //length of the masked region  
792 -  
793 - for(unsigned long long xy = 0; xy < XY; xy++){ //for each pixel in the band  
794 -  
795 - if(reading){ //if we are currently iterating through a block of masked pixels  
796 - if(p[xy]) end++; //if the current pixel is part of that block, increment the end index  
797 - else{ //otherwise, terminate the block  
798 - reading = false; //stop reading  
799 - i = b * XY + start;  
800 - file.seekg( i * sizeof(T) + header); //skip all of the unmasked pixels up to this point  
801 - l = (end - start);  
802 - file.read((char *)&values[vi], l * sizeof(T)); //write the values between start and end to the values array  
803 - vi += l; //increment the pointer into the values array  
804 - } 787 +
  788 + //calculate the number of pixels in the mask
  789 + unsigned long long P = 0;
  790 + if(mask == NULL) P = XY;
  791 + else{
  792 + for(unsigned long long xy = 0; xy < XY; xy++){
  793 + if(mask[xy] != 0) P++;
805 } 794 }
806 - else{ //if we are currently iterating through a block of empty pixels  
807 - if(p[xy]){ //if the next pixel is masked, start a new block for reading  
808 - reading = true;  
809 - start = xy; //set the start and end indices to the beginning of this new block  
810 - end = start + 1; 795 + }
  796 +
  797 + T* band_image = (T*) malloc( XY * sizeof(T)); //allocate space for a single band
  798 +
  799 + unsigned long long i; //pixel index into the sifted array
  800 + for(unsigned long long b = 0; b < Z(); b++){ //for each band in the data set
  801 + band_index(band_image, b); //retrieve an image of that band
  802 +
  803 + i = 0;
  804 + for(unsigned long long xy = 0; xy < XY; xy++){
  805 + if(mask == NULL || mask[xy] != 0){ //if the pixel is valid
  806 + matrix[i*Z() + b] = band_image[xy]; //copy it to the appropriate point in the values[] array
  807 + i++;
811 } 808 }
812 } 809 }
813 } 810 }
814 - 811 +
815 return true; 812 return true;
816 } 813 }
817 814
818 /// Saves only those spectra corresponding to mask value != 0 to pre-allocated memory 815 /// Saves only those spectra corresponding to mask value != 0 to pre-allocated memory
819 /// @param matrix is the destination for the sifted pixels 816 /// @param matrix is the destination for the sifted pixels
820 /// @param p is the mask file used for sifting 817 /// @param p is the mask file used for sifting
821 - bool sift(T* matrix, unsigned char* p){ 818 + /*bool sift(T* matrix, unsigned char* p){
822 819
823 // open a band (XY plane) 820 // open a band (XY plane)
824 unsigned long XY = X() * Y(); //Number of XY pixels 821 unsigned long XY = X() * Y(); //Number of XY pixels
@@ -845,7 +842,7 @@ public: @@ -845,7 +842,7 @@ public:
845 842
846 free(bandvals); //clean up temporary memory 843 free(bandvals); //clean up temporary memory
847 return true; 844 return true;
848 - } 845 + }*/
849 846
850 /// Saves to disk only those spectra corresponding to mask values != 0 847 /// Saves to disk only those spectra corresponding to mask values != 0
851 /// @param outfile is the name of the sifted ENVI file to be written to disk 848 /// @param outfile is the name of the sifted ENVI file to be written to disk
@@ -465,7 +465,9 @@ public: @@ -465,7 +465,9 @@ public:
465 return false; 465 return false;
466 } 466 }
467 467
468 - /// sift copies all spectra corresponding to nonzero values of a mask into a pre-allocated matrix 468 + /// Copies all spectra corresponding to nonzero values of a mask into a pre-allocated matrix of size (P x B)
  469 + /// where P is the number of masked pixels and B is the number of bands. The allocated memory can be accessed
  470 + /// using the following indexing: i = b*P + p
469 /// @param matrix is the destination for the pixel data 471 /// @param matrix is the destination for the pixel data
470 /// @param p is the mask 472 /// @param p is the mask
471 bool sift(void* matrix, unsigned char* p){ 473 bool sift(void* matrix, unsigned char* p){
@@ -478,11 +480,20 @@ public: @@ -478,11 +480,20 @@ public:
478 else 480 else
479 std::cout << "ERROR: unidentified data type" << std::endl; 481 std::cout << "ERROR: unidentified data type" << std::endl;
480 } 482 }
  483 +
  484 + if (header.interleave == envi_header::BIP){
  485 + std::cout<<"Memory sifting not supported for BIP files"<<std::endl;
  486 + exit(1);
  487 + }
  488 + if (header.interleave == envi_header::BIL){
  489 + std::cout<<"Memory sifting not supported for BIL files"<<std::endl;
  490 + exit(1);
  491 + }
481 return false; 492 return false;
482 493
483 } 494 }
484 495
485 - /// sift-mask saves in an array only those spectra corresponding to nonzero values of the mask. 496 + /// Saves in an array only those spectra corresponding to nonzero values of the mask.
486 /// @param outfile is the name of the sifted output file 497 /// @param outfile is the name of the sifted output file
487 /// @param p is the mask 498 /// @param p is the mask
488 bool sift(std::string outfile, unsigned char* p) 499 bool sift(std::string outfile, unsigned char* p)
stim/envi/envi_header.h
@@ -77,6 +77,9 @@ struct envi_header @@ -77,6 +77,9 @@ struct envi_header
77 } 77 }
78 78
79 std::string trim(std::string line){ 79 std::string trim(std::string line){
  80 +
  81 + if(line.length() == 0)
  82 + return line;
80 //trims whitespace from the beginning and end of line 83 //trims whitespace from the beginning and end of line
81 unsigned int start_i, end_i; 84 unsigned int start_i, end_i;
82 for(start_i=0; start_i < line.length(); start_i++) 85 for(start_i=0; start_i < line.length(); start_i++)
stim/image/image.h
@@ -94,6 +94,24 @@ public: @@ -94,6 +94,24 @@ public:
94 94
95 } 95 }
96 96
  97 + T& operator()(unsigned x, unsigned y, unsigned z = 0, unsigned c = 0){
  98 + return img(x, y, z, c);
  99 + }
  100 +
  101 + /// Set all elements in the image to a given scalar value
  102 +
  103 + /// @param v is the value used to set all values in the image
  104 + image<T> operator=(T v){
  105 +
  106 + unsigned int X = width() * height() * depth() * channels();
  107 +
  108 + for(unsigned x = 0; x < X; x++)
  109 + img.data()[x] = v;
  110 +
  111 + return *this;
  112 +
  113 + }
  114 +
97 /// Copy the given data to the specified channel 115 /// Copy the given data to the specified channel
98 116
99 /// @param c is the channel number that the data will be copied to 117 /// @param c is the channel number that the data will be copied to
@@ -134,6 +152,10 @@ public: @@ -134,6 +152,10 @@ public:
134 return img.height(); 152 return img.height();
135 } 153 }
136 154
  155 + unsigned int depth(){
  156 + return img.depth();
  157 + }
  158 +
137 T* data(){ 159 T* data(){
138 160
139 return img.data(); 161 return img.data();
stim/parser/filename.h
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 15
16 #include <string> 16 #include <string>
17 #include <sstream> 17 #include <sstream>
  18 +#include <iomanip>
18 #include <vector> 19 #include <vector>
19 #include <stack> 20 #include <stack>
20 #include <algorithm> 21 #include <algorithm>
@@ -290,6 +291,25 @@ public: @@ -290,6 +291,25 @@ public:
290 return result; 291 return result;
291 } 292 }
292 293
  294 + /// This function replaces a wildcard in the prefix with the specified string
  295 + stim::filename insert(std::string str){
  296 +
  297 + stim::filename result = *this; //initialize the result filename to the current filename
  298 + size_t loc = result.prefix.find('*'); //find a wild card in the string
  299 + if(loc == std::string::npos) //if a wildcard isn't found
  300 + return result; //return the original string
  301 +
  302 + result.prefix.replace(loc, 1, str); //replace the wildcard with the string
  303 + return result; //return the result
  304 + }
  305 +
  306 + stim::filename insert(unsigned i, unsigned int n = 2){
  307 +
  308 + std::stringstream ss;
  309 + ss << std::setw(n) << std::setfill('0') << i;
  310 + return insert(ss.str());
  311 + }
  312 +
293 bool is_relative(){ 313 bool is_relative(){
294 return !absolute; 314 return !absolute;
295 } 315 }