diff --git a/stim/envi/bil.h b/stim/envi/bil.h index bb0ec03..c571d4e 100644 --- a/stim/envi/bil.h +++ b/stim/envi/bil.h @@ -353,7 +353,7 @@ public: /// @param outname is the name of the output file used to store the resulting baseline-corrected data. /// @param w is the label specifying the band that the hyperspectral image will be normalized to. /// @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. - bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) + bool ratio(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) { unsigned long long B = Z(); //calculate the number of bands unsigned long long ZX = Z() * X(); @@ -395,6 +395,8 @@ public: target.close(); return true; } + + void normalize(std::string outfile, unsigned char* mask = NULL, bool PROGRESS = false){} /// Convert the current BIL file to a BSQ file with the specified file name. diff --git a/stim/envi/bip.h b/stim/envi/bip.h index 2a0a85c..ed6542a 100644 --- a/stim/envi/bip.h +++ b/stim/envi/bip.h @@ -320,7 +320,7 @@ public: /// @param outname is the name of the output file used to store the resulting baseline-corrected data. /// @param w is the label specifying the band that the hyperspectral image will be normalized to. /// @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. - bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) + bool ratio(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) { std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file std::string headername = outname + ".hdr"; //the header file name @@ -349,6 +349,8 @@ public: target.close(); return true; } + + void normalize(std::string outfile, unsigned char* mask = NULL, bool PROGRESS = false){} /// Convert the current BIP file to a BIL file with the specified file name. diff --git a/stim/envi/bsq.h b/stim/envi/bsq.h index 78ebf73..b523dab 100644 --- a/stim/envi/bsq.h +++ b/stim/envi/bsq.h @@ -286,7 +286,7 @@ public: /// @param outname is the name of the output file used to store the resulting baseline-corrected data. /// @param w is the label specifying the band that the hyperspectral image will be normalized to. /// @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. - bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) + bool ratio(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) { unsigned long long B = Z(); //calculate the number of bands unsigned long long XY = X() * Y(); //calculate the number of pixels in a band @@ -328,6 +328,47 @@ public: return true; } + void normalize(std::string outfile, unsigned char* mask = NULL, bool PROGRESS = false){ + size_t B = Z(); //calculate the number of bands + size_t XY = X() * Y(); //calculate the number of pixels in a band + size_t XYb = XY * sizeof(T); //calculate the size of a band in bytes + + std::ofstream out(outfile.c_str(), std::ios::binary); //open the output file + file.seekg(0, std::ios::beg); //move the pointer to the current file to the beginning + + T* len = (T*)malloc(XYb); //allocate space to store the vector length + memset(len, 0, XYb); //initialize the vector length to zero (0) + + T* band = (T*) malloc(XYb); //allocate space to store a band image + + for(size_t b = 0; b < B; b++){ + file.read((char*)band, XYb); + for(size_t xy = 0; xy < XY; xy++){ + if(mask == NULL || mask[xy]){ + len[xy] += pow(band[xy], 2); //sum the squared value for each pixel value in the band + } + } + if(PROGRESS) progress = (double) (b+1) / (double)B * 50; + } + for(size_t xy = 0; xy < XY; xy++){ //for each pixel, calculate the square root + if(mask == NULL || mask[xy]){ + len[xy] += pow(band[xy], 2); //sum the squared value for each pixel value in the band + } + } + file.seekg(0, std::ios::beg); //move the pointer to the current file to the beginning + for(size_t b = 0; b < B; b++){ + file.read((char*)band, XYb); + for(size_t xy = 0; xy < XY; xy++){ + if(mask == NULL || mask[xy]){ + band[xy] /= len[xy]; //divide the band by the vector length + } + } + out.write((char*)band, XYb); + if(PROGRESS) progress = (double) (b+1) / (double)B * 50 + 50; + } + + } + /// Convert the current BSQ file to a BIL file with the specified file name. /// @param outname is the name of the output BIL file to be saved to disk. diff --git a/stim/envi/envi.h b/stim/envi/envi.h index 79e42ff..2c27acc 100644 --- a/stim/envi/envi.h +++ b/stim/envi/envi.h @@ -214,31 +214,31 @@ public: /// @param outfile is the name of the normalized file to be output /// @param band is the band label to be output /// @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) - bool normalize(std::string outfile, double band, unsigned char* mask = NULL, bool PROGRESS = false){ + bool ratio(std::string outfile, double band, unsigned char* mask = NULL, bool PROGRESS = false){ header.save(outfile + ".hdr"); if(header.interleave == envi_header::BSQ){ //if the infile is bsq file if(header.data_type ==envi_header::float32) - return ((bsq*)file)->normalize(outfile, band, mask, PROGRESS); + return ((bsq*)file)->ratio(outfile, band, mask, PROGRESS); else if(header.data_type == envi_header::float64) - return ((bsq*)file)->normalize(outfile,band, mask, PROGRESS); + return ((bsq*)file)->ratio(outfile,band, mask, PROGRESS); else std::cout<<"ERROR: unidentified data type"<*)file)->normalize(outfile, band, mask, PROGRESS); + return ((bil*)file)->ratio(outfile, band, mask, PROGRESS); else if(header.data_type == envi_header::float64) - return ((bil*)file)->normalize(outfile,band, mask, PROGRESS); + return ((bil*)file)->ratio(outfile,band, mask, PROGRESS); else std::cout<<"ERROR: unidentified data type"<*)file)->normalize(outfile, band, mask, PROGRESS); + return ((bip*)file)->ratio(outfile, band, mask, PROGRESS); else if(header.data_type == envi_header::float64) - return ((bip*)file)->normalize(outfile,band, mask, PROGRESS); + return ((bip*)file)->ratio(outfile,band, mask, PROGRESS); else std::cout<<"ERROR: unidentified data type"<*)file)->normalize(outfile, mask, PROGRESS); + else if(header.data_type == envi_header::float64) + ((bsq*)file)->normalize(outfile, mask, PROGRESS); + else + std::cout<<"ERROR: unidentified data type"<*)file)->normalize(outfile, mask, PROGRESS); + else if(header.data_type == envi_header::float64) + ((bil*)file)->normalize(outfile, mask, PROGRESS); + else + std::cout<<"ERROR: unidentified data type"<*)file)->normalize(outfile, mask, PROGRESS); + else if(header.data_type == envi_header::float64) + ((bip*)file)->normalize(outfile, mask, PROGRESS); + else + std::cout<<"ERROR: unidentified data type"<