Commit 3d0b6243c6e8fe045c1aeef57b785c1a32711531
1 parent
2aa68315
fixed hsiproc bugs, added insert() method into stim::filename, added Matlab func…
…tion to save ENVI files
Showing
6 changed files
with
88 additions
and
35 deletions
Show diff stats
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; |
stim/envi/bsq.h
@@ -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 |
stim/envi/envi.h
@@ -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 | } |