Commit 798cea97b3b181a1fe8adf06738fac398abf8daf
1 parent
c1078e19
added progress bars to making masks, fixed overflow error in baseline correction
Showing
4 changed files
with
88 additions
and
78 deletions
Show diff stats
stim/envi/bil.h
... | ... | @@ -230,7 +230,7 @@ public: |
230 | 230 | |
231 | 231 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
232 | 232 | /// @param wls is the list of baseline points based on band labels. |
233 | - bool baseline(std::string outname, std::vector<double> wls, bool PROGRESS = false){ | |
233 | + bool baseline(std::string outname, std::vector<double> wls, unsigned char* mask = NULL, bool PROGRESS = false){ | |
234 | 234 | |
235 | 235 | unsigned N = wls.size(); //get the number of baseline points |
236 | 236 | |
... | ... | @@ -345,7 +345,7 @@ public: |
345 | 345 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
346 | 346 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. |
347 | 347 | /// @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. |
348 | - bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false) | |
348 | + bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) | |
349 | 349 | { |
350 | 350 | unsigned int B = Z(); //calculate the number of bands |
351 | 351 | unsigned int ZX = Z() * X(); |
... | ... | @@ -371,7 +371,7 @@ public: |
371 | 371 | { |
372 | 372 | for(unsigned m = 0; m < X(); m++) |
373 | 373 | { |
374 | - if( b[m + j * X()] < t ) | |
374 | + if( mask != NULL && !mask[m + j * X()] ) | |
375 | 375 | c[m + i * X()] = (T)0.0; |
376 | 376 | else |
377 | 377 | c[m + i * X()] = c[m + i * X()] / b[m + j * X()]; |
... | ... | @@ -792,16 +792,16 @@ public: |
792 | 792 | /// @param mask_band is the band used to specify the mask |
793 | 793 | /// @param threshold is the threshold used to determine if the mask value is true or false |
794 | 794 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
795 | - bool build_mask(double mask_band, double threshold, unsigned char* p){ | |
795 | + bool build_mask(double mask_band, double threshold, unsigned char* p, bool PROGRESS = false){ | |
796 | 796 | |
797 | 797 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
798 | - band(temp, mask_band); | |
798 | + band(temp, mask_band, PROGRESS); | |
799 | 799 | |
800 | 800 | for (unsigned int i = 0; i < X() * Y(); i++) { |
801 | - if (temp[i] < threshold) | |
802 | - p[i] = 0; | |
803 | - else | |
804 | - p[i] = 255; | |
801 | + if (temp[i] < threshold) | |
802 | + p[i] = 0; | |
803 | + else | |
804 | + p[i] = 255; | |
805 | 805 | } |
806 | 806 | |
807 | 807 | free(temp); | ... | ... |
stim/envi/bip.h
... | ... | @@ -31,13 +31,13 @@ protected: |
31 | 31 | std::vector<double> w; //band wavelength |
32 | 32 | unsigned int offset; //header offset |
33 | 33 | |
34 | - unsigned long X(){ | |
34 | + unsigned long long X(){ | |
35 | 35 | return R[1]; |
36 | 36 | } |
37 | - unsigned long Y(){ | |
37 | + unsigned long long Y(){ | |
38 | 38 | return R[2]; |
39 | 39 | } |
40 | - unsigned long Z(){ | |
40 | + unsigned long long Z(){ | |
41 | 41 | return R[0]; |
42 | 42 | } |
43 | 43 | |
... | ... | @@ -318,10 +318,9 @@ public: |
318 | 318 | |
319 | 319 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
320 | 320 | /// @param wls is the list of baseline points based on band labels. |
321 | - bool baseline(std::string outname, std::vector<double> base_pts, bool PROGRESS = false){ | |
321 | + bool baseline(std::string outname, std::vector<double> base_pts, unsigned char* mask = NULL, bool PROGRESS = false){ | |
322 | 322 | |
323 | 323 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file |
324 | - std::string headername = outname + ".hdr"; //the header file name | |
325 | 324 | |
326 | 325 | unsigned long long N = X() * Y(); //calculate the total number of pixels to be processed |
327 | 326 | unsigned long long B = Z(); //get the number of bands |
... | ... | @@ -334,30 +333,36 @@ public: |
334 | 333 | double alpha; |
335 | 334 | unsigned long long ai, bi; //surrounding baseline point band indices |
336 | 335 | for(unsigned long long n = 0; n < N; n++){ //for each pixel in the image |
337 | - pixel(s, n); //retrieve the spectrum s | |
338 | - base_vals = interp_spectrum(s, base_pts); //get the values at each baseline point | |
339 | - | |
340 | - ai = bi = 0; | |
341 | - aw = w[0]; //initialize the current baseline points (assume the spectrum starts at 0) | |
342 | - av = s[0]; | |
343 | - bw = base_pts[0]; | |
344 | - for(unsigned long long b = 0; b < B; b++){ //for each band in the spectrum | |
345 | - while(bi < base_pts.size() && base_pts[bi] < w[b]) //while the current wavelength is higher than the second baseline point | |
346 | - bi++; //move to the next baseline point | |
347 | - if(bi < base_pts.size()){ | |
348 | - bw = base_pts[bi]; //set the wavelength for the upper bound baseline point | |
349 | - bv = base_vals[bi]; //set the value for the upper bound baseline point | |
350 | - } | |
351 | - if(bi == base_pts.size()){ //if we have passed the last baseline point | |
352 | - bw = w[B-1]; //set the outer bound to the last spectral band | |
353 | - bv = s[B-1]; | |
354 | - } | |
355 | - if(bi != 0){ | |
356 | - ai = bi - 1; //set the lower bound baseline point index | |
357 | - aw = base_pts[ai]; //set the wavelength for the lower bound baseline point | |
358 | - av = base_vals[ai]; //set the value for the lower bound baseline point | |
336 | + if(mask != NULL && !mask[n]){ //if the pixel isn't masked | |
337 | + memset(sbc, 0, sizeof(T) * B); //set the baseline corrected spectrum to zero | |
338 | + } | |
339 | + else{ | |
340 | + | |
341 | + pixel(s, n); //retrieve the spectrum s | |
342 | + base_vals = interp_spectrum(s, base_pts); //get the values at each baseline point | |
343 | + | |
344 | + ai = bi = 0; | |
345 | + aw = w[0]; //initialize the current baseline points (assume the spectrum starts at 0) | |
346 | + av = s[0]; | |
347 | + bw = base_pts[0]; | |
348 | + for(unsigned long long b = 0; b < B; b++){ //for each band in the spectrum | |
349 | + while(bi < base_pts.size() && base_pts[bi] < w[b]) //while the current wavelength is higher than the second baseline point | |
350 | + bi++; //move to the next baseline point | |
351 | + if(bi < base_pts.size()){ | |
352 | + bw = base_pts[bi]; //set the wavelength for the upper bound baseline point | |
353 | + bv = base_vals[bi]; //set the value for the upper bound baseline point | |
354 | + } | |
355 | + if(bi == base_pts.size()){ //if we have passed the last baseline point | |
356 | + bw = w[B-1]; //set the outer bound to the last spectral band | |
357 | + bv = s[B-1]; | |
358 | + } | |
359 | + if(bi != 0){ | |
360 | + ai = bi - 1; //set the lower bound baseline point index | |
361 | + aw = base_pts[ai]; //set the wavelength for the lower bound baseline point | |
362 | + av = base_vals[ai]; //set the value for the lower bound baseline point | |
363 | + } | |
364 | + sbc[b] = s[b] - lerp(w[b], av, aw, bv, bw); //perform the baseline correction and save the new value | |
359 | 365 | } |
360 | - sbc[b] = s[b] - lerp(w[b], av, aw, bv, bw); //perform the baseline correction and save the new value | |
361 | 366 | } |
362 | 367 | |
363 | 368 | if(PROGRESS) progress = (double)(n+1) / N * 100; //set the current progress |
... | ... | @@ -378,7 +383,7 @@ public: |
378 | 383 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
379 | 384 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. |
380 | 385 | /// @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. |
381 | - bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false) | |
386 | + bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) | |
382 | 387 | { |
383 | 388 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file |
384 | 389 | std::string headername = outname + ".hdr"; //the header file name |
... | ... | @@ -390,7 +395,7 @@ public: |
390 | 395 | for(unsigned long long n = 0; n < N; n++){ //for each pixel in the image |
391 | 396 | pixel(s, n); //retrieve the spectrum s |
392 | 397 | nv = interp_spectrum(s, w); //find the value of the normalization band |
393 | - if(abs(nv) <= t) //if the normalization band is below threshold | |
398 | + if(mask != NULL && !mask[n]) //if the normalization band is below threshold | |
394 | 399 | memset(s, 0, sizeof(T) * B); //set the output to zero |
395 | 400 | else{ |
396 | 401 | for(unsigned long long b = 0; b < B; b++){ //for each band in the spectrum |
... | ... | @@ -784,16 +789,16 @@ public: |
784 | 789 | /// @param mask_band is the band used to specify the mask |
785 | 790 | /// @param threshold is the threshold used to determine if the mask value is true or false |
786 | 791 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
787 | - bool build_mask(double mask_band, double threshold, unsigned char* p){ | |
792 | + bool build_mask(double mask_band, double threshold, unsigned char* p, bool PROGRESS = false){ | |
788 | 793 | |
789 | 794 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
790 | - band(temp, mask_band); | |
795 | + band(temp, mask_band, PROGRESS); | |
791 | 796 | |
792 | 797 | for (unsigned int i = 0; i < X() * Y();i++) { |
793 | - if (temp[i] < threshold) | |
794 | - p[i] = 0; | |
795 | - else | |
796 | - p[i] = 255; | |
798 | + if (temp[i] < threshold) | |
799 | + p[i] = 0; | |
800 | + else | |
801 | + p[i] = 255; | |
797 | 802 | } |
798 | 803 | |
799 | 804 | free(temp); | ... | ... |
stim/envi/bsq.h
... | ... | @@ -172,9 +172,8 @@ public: |
172 | 172 | |
173 | 173 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
174 | 174 | /// @param wls is the list of baseline points based on band labels. |
175 | - bool baseline(std::string outname, std::vector<double> wls, bool PROGRESS = false ) | |
175 | + bool baseline(std::string outname, std::vector<double> wls, unsigned char* mask = NULL, bool PROGRESS = false ) | |
176 | 176 | { |
177 | - if(PROGRESS) progress = 0; | |
178 | 177 | unsigned N = wls.size(); //get the number of baseline points |
179 | 178 | |
180 | 179 | std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file |
... | ... | @@ -257,8 +256,12 @@ public: |
257 | 256 | |
258 | 257 | //perform the baseline correction |
259 | 258 | for(unsigned i=0; i < XY; i++){ |
260 | - double r = (double) (ci - ai) / (double) (bi - ai); | |
261 | - c[i] =(T) ( c[i] - (b[i] - a[i]) * r - a[i] ); | |
259 | + if(mask != NULL && !mask[i]) //if the pixel is excluded by a mask | |
260 | + c[i] = 0; //set the value to zero | |
261 | + else{ | |
262 | + double r = (double) (ci - ai) / (double) (bi - ai); | |
263 | + c[i] =(T) ( c[i] - (b[i] - a[i]) * r - a[i] ); | |
264 | + } | |
262 | 265 | } |
263 | 266 | |
264 | 267 | target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination |
... | ... | @@ -282,7 +285,7 @@ public: |
282 | 285 | /// @param outname is the name of the output file used to store the resulting baseline-corrected data. |
283 | 286 | /// @param w is the label specifying the band that the hyperspectral image will be normalized to. |
284 | 287 | /// @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. |
285 | - bool normalize(std::string outname, double w, double t = 0.0, bool PROGRESS = false) | |
288 | + bool normalize(std::string outname, double w, unsigned char* mask = NULL, bool PROGRESS = false) | |
286 | 289 | { |
287 | 290 | unsigned int B = Z(); //calculate the number of bands |
288 | 291 | unsigned int XY = X() * Y(); //calculate the number of pixels in a band |
... | ... | @@ -304,7 +307,7 @@ public: |
304 | 307 | band_index(c, j); //get the current band into memory |
305 | 308 | for(unsigned i = 0; i < XY; i++) |
306 | 309 | { |
307 | - if(b[i] < t) | |
310 | + if(mask != NULL && !mask[i]) | |
308 | 311 | c[i] = (T)0.0; |
309 | 312 | else |
310 | 313 | c[i] = c[i] / b[i]; |
... | ... | @@ -698,16 +701,18 @@ public: |
698 | 701 | /// @param mask_band is the band used to specify the mask |
699 | 702 | /// @param threshold is the threshold used to determine if the mask value is true or false |
700 | 703 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
701 | - bool build_mask(double mask_band, double threshold, unsigned char* p = NULL){ | |
704 | + bool build_mask(double mask_band, double threshold, unsigned char* p = NULL, bool PROGRESS = false){ | |
702 | 705 | |
703 | 706 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
704 | 707 | band(temp, mask_band); |
705 | 708 | |
706 | 709 | for (unsigned int i = 0; i < X() * Y(); i++) { |
707 | - if (temp[i] < threshold) | |
708 | - p[i] = 0; | |
709 | - else | |
710 | - p[i] = 255; | |
710 | + if (temp[i] < threshold) | |
711 | + p[i] = 0; | |
712 | + else | |
713 | + p[i] = 255; | |
714 | + | |
715 | + if(PROGRESS) progress = (double) (i+1) / (X() * Y()); | |
711 | 716 | } |
712 | 717 | |
713 | 718 | free(temp); | ... | ... |
stim/envi/envi.h
... | ... | @@ -213,31 +213,31 @@ public: |
213 | 213 | /// @param outfile is the name of the normalized file to be output |
214 | 214 | /// @param band is the band label to be output |
215 | 215 | /// @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) |
216 | - bool normalize(std::string outfile, double band, double threshold = 0.0, bool PROGRESS = false){ | |
216 | + bool normalize(std::string outfile, double band, unsigned char* mask = NULL, bool PROGRESS = false){ | |
217 | 217 | |
218 | 218 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
219 | 219 | if(header.data_type ==envi_header::float32) |
220 | - return ((bsq<float>*)file)->normalize(outfile, band, threshold, PROGRESS); | |
220 | + return ((bsq<float>*)file)->normalize(outfile, band, mask, PROGRESS); | |
221 | 221 | else if(header.data_type == envi_header::float64) |
222 | - return ((bsq<double>*)file)->normalize(outfile,band, threshold, PROGRESS); | |
222 | + return ((bsq<double>*)file)->normalize(outfile,band, mask, PROGRESS); | |
223 | 223 | else |
224 | 224 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
225 | 225 | } |
226 | 226 | |
227 | 227 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
228 | 228 | if(header.data_type ==envi_header::float32) |
229 | - return ((bil<float>*)file)->normalize(outfile, band, threshold, PROGRESS); | |
229 | + return ((bil<float>*)file)->normalize(outfile, band, mask, PROGRESS); | |
230 | 230 | else if(header.data_type == envi_header::float64) |
231 | - return ((bil<double>*)file)->normalize(outfile,band, threshold, PROGRESS); | |
231 | + return ((bil<double>*)file)->normalize(outfile,band, mask, PROGRESS); | |
232 | 232 | else |
233 | 233 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
234 | 234 | } |
235 | 235 | |
236 | 236 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
237 | 237 | if(header.data_type ==envi_header::float32) |
238 | - return ((bip<float>*)file)->normalize(outfile, band, threshold, PROGRESS); | |
238 | + return ((bip<float>*)file)->normalize(outfile, band, mask, PROGRESS); | |
239 | 239 | else if(header.data_type == envi_header::float64) |
240 | - return ((bip<double>*)file)->normalize(outfile,band, threshold, PROGRESS); | |
240 | + return ((bip<double>*)file)->normalize(outfile,band, mask, PROGRESS); | |
241 | 241 | else |
242 | 242 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
243 | 243 | } |
... | ... | @@ -253,13 +253,13 @@ public: |
253 | 253 | |
254 | 254 | /// @param outfile is the file name for the baseline corrected output |
255 | 255 | /// @param w is a list of band labels to serve as baseline points (zero values) |
256 | - bool baseline(std::string outfile, std::vector<double> w, bool PROGRESS){ | |
257 | - | |
256 | + bool baseline(std::string outfile, std::vector<double> w, unsigned char* mask = NULL, bool PROGRESS = false){ | |
257 | + header.save(outfile + ".hdr"); | |
258 | 258 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
259 | 259 | if(header.data_type ==envi_header::float32) |
260 | - return ((bsq<float>*)file)->baseline(outfile, w, PROGRESS); | |
260 | + return ((bsq<float>*)file)->baseline(outfile, w, mask, PROGRESS); | |
261 | 261 | else if(header.data_type == envi_header::float64) |
262 | - return ((bsq<double>*)file)->baseline(outfile,w, PROGRESS); | |
262 | + return ((bsq<double>*)file)->baseline(outfile,w, mask, PROGRESS); | |
263 | 263 | else{ |
264 | 264 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
265 | 265 | exit(1); |
... | ... | @@ -268,9 +268,9 @@ public: |
268 | 268 | |
269 | 269 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
270 | 270 | if(header.data_type ==envi_header::float32) |
271 | - return ((bil<float>*)file)->baseline(outfile, w, PROGRESS); | |
271 | + return ((bil<float>*)file)->baseline(outfile, w, mask, PROGRESS); | |
272 | 272 | else if(header.data_type == envi_header::float64) |
273 | - return ((bil<double>*)file)->baseline(outfile, w, PROGRESS); | |
273 | + return ((bil<double>*)file)->baseline(outfile, w, mask, PROGRESS); | |
274 | 274 | else{ |
275 | 275 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
276 | 276 | exit(1); |
... | ... | @@ -279,9 +279,9 @@ public: |
279 | 279 | |
280 | 280 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
281 | 281 | if(header.data_type ==envi_header::float32) |
282 | - return ((bip<float>*)file)->baseline(outfile, w, PROGRESS); | |
282 | + return ((bip<float>*)file)->baseline(outfile, w, mask, PROGRESS); | |
283 | 283 | else if(header.data_type == envi_header::float64) |
284 | - return ((bip<double>*)file)->baseline(outfile, w, PROGRESS); | |
284 | + return ((bip<double>*)file)->baseline(outfile, w, mask, PROGRESS); | |
285 | 285 | else{ |
286 | 286 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
287 | 287 | exit(1); |
... | ... | @@ -469,31 +469,31 @@ public: |
469 | 469 | /// @param mask_band is the label for the band that will be used to build the mask |
470 | 470 | /// @param threshold is a value selected such that all band values greater than threshold will have a mask value of 'true' |
471 | 471 | /// @param p is memory of size X*Y that will store the resulting mask |
472 | - bool build_mask(double mask_band, double threshold, unsigned char* p = NULL) { | |
472 | + bool build_mask(double mask_band, double threshold, unsigned char* p = NULL, bool PROGRESS = false) { | |
473 | 473 | |
474 | 474 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
475 | 475 | if(header.data_type ==envi_header::float32) |
476 | - return ((bsq<float>*)file)->build_mask(mask_band, threshold, p); | |
476 | + return ((bsq<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
477 | 477 | else if(header.data_type == envi_header::float64) |
478 | - return ((bsq<double>*)file)->build_mask(mask_band, threshold, p); | |
478 | + return ((bsq<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
479 | 479 | else |
480 | 480 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
481 | 481 | } |
482 | 482 | |
483 | 483 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
484 | 484 | if(header.data_type ==envi_header::float32) |
485 | - return ((bil<float>*)file)->build_mask(mask_band, threshold, p); | |
485 | + return ((bil<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
486 | 486 | else if(header.data_type == envi_header::float64) |
487 | - return ((bil<double>*)file)->build_mask(mask_band, threshold, p); | |
487 | + return ((bil<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
488 | 488 | else |
489 | 489 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
490 | 490 | } |
491 | 491 | |
492 | 492 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
493 | 493 | if(header.data_type ==envi_header::float32) |
494 | - return ((bip<float>*)file)->build_mask(mask_band, threshold, p); | |
494 | + return ((bip<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
495 | 495 | else if(header.data_type == envi_header::float64) |
496 | - return ((bip<double>*)file)->build_mask(mask_band, threshold, p); | |
496 | + return ((bip<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
497 | 497 | else |
498 | 498 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
499 | 499 | } | ... | ... |