Commit b31c02ebf337c0fb2fedefd203ef999cf061ed4a
1 parent
66304f4f
added a --select feature that creates a new ENVI file from individual bands
Showing
5 changed files
with
109 additions
and
0 deletions
Show diff stats
stim/envi/bil.h
@@ -462,6 +462,11 @@ public: | @@ -462,6 +462,11 @@ public: | ||
462 | }*/ | 462 | }*/ |
463 | } | 463 | } |
464 | 464 | ||
465 | + bool select(std::string outfile, std::vector<double> bandlist, unsigned char* mask = NULL, bool PROGRESS = NULL) { | ||
466 | + std::cout << "ERROR: select() not implemented for BIL" << std::endl; | ||
467 | + exit(1); | ||
468 | + } | ||
469 | + | ||
465 | /// Convert the current BIL file to a BSQ file with the specified file name. | 470 | /// Convert the current BIL file to a BSQ file with the specified file name. |
466 | 471 | ||
467 | /// @param outname is the name of the output BSQ file to be saved to disk. | 472 | /// @param outname is the name of the output BSQ file to be saved to disk. |
stim/envi/bip.h
@@ -392,6 +392,50 @@ public: | @@ -392,6 +392,50 @@ public: | ||
392 | } | 392 | } |
393 | } | 393 | } |
394 | 394 | ||
395 | + /// This function loads a specified set of bands and saves them into a new output file | ||
396 | + bool select(std::string outfile, std::vector<double> bandlist, unsigned char* mask = NULL, bool PROGRESS = false) { | ||
397 | + std::ofstream target(outfile.c_str(), std::ios::binary); //open the target binary file | ||
398 | + if (!target) { | ||
399 | + std::cout << "ERROR opening output file: " << outfile << std::endl; | ||
400 | + return false; | ||
401 | + } | ||
402 | + file.seekg(0, std::ios::beg); //move the pointer to the current file to the beginning | ||
403 | + | ||
404 | + size_t B = Z(); //number of spectral components | ||
405 | + size_t XY = X() * Y(); //calculate the number of pixels | ||
406 | + size_t Bout = bandlist.size(); | ||
407 | + size_t in_bytes = B * sizeof(T); //number of bytes in a spectrum | ||
408 | + size_t out_bytes = Bout * sizeof(T); //number of bytes in an output spectrum | ||
409 | + | ||
410 | + T* in = (T*)malloc(in_bytes); //allocate space for the input spectrum | ||
411 | + T* out = (T*)malloc(out_bytes); //allocate space for the output spectrum | ||
412 | + | ||
413 | + double wc; //register to store the desired wavelength | ||
414 | + double w0, w1; //registers to store the wavelengths surrounding the given band | ||
415 | + size_t b0, b1; //indices of the bands surrounding the specified wavelength | ||
416 | + for (size_t xy = 0; xy < XY; xy++) { //for each pixel | ||
417 | + //memset(out, 0, out_bytes); //set the spectrum to zero | ||
418 | + if (mask == NULL || mask[xy]) { //if the pixel is masked | ||
419 | + file.read((char*)in, in_bytes); //read an input spectrum | ||
420 | + for (size_t b = 0; b < Bout; b++) { //for each band | ||
421 | + wc = bandlist[b]; //set the desired wavelength | ||
422 | + band_bounds(wc, b0, b1); //get the surrounding bands | ||
423 | + w0 = w[b0]; //get the wavelength for the lower band | ||
424 | + w1 = w[b1]; //get the wavelength for the higher band | ||
425 | + out[b] = lerp(wc, in[b0], w0, in[b1], w1); //interpolate the spectral values to get the desired output value | ||
426 | + } | ||
427 | + } | ||
428 | + else | ||
429 | + file.seekg(Bout, std::ios::cur); //otherwise skip a spectrum | ||
430 | + target.write((char*)out, out_bytes); //output the normalized spectrum | ||
431 | + if (PROGRESS) progress = (double)(xy + 1) / (double)XY * 100; //update the progress | ||
432 | + } | ||
433 | + | ||
434 | + free(in); | ||
435 | + free(out); | ||
436 | + return true; | ||
437 | + } | ||
438 | + | ||
395 | 439 | ||
396 | /// Convert the current BIP file to a BIL file with the specified file name. | 440 | /// Convert the current BIP file to a BIL file with the specified file name. |
397 | 441 |
stim/envi/bsq.h
@@ -380,6 +380,30 @@ public: | @@ -380,6 +380,30 @@ public: | ||
380 | 380 | ||
381 | } | 381 | } |
382 | 382 | ||
383 | + bool select(std::string outfile, std::vector<double> bandlist, unsigned char* mask = NULL, bool PROGRESS = false) { | ||
384 | + std::ofstream out(outfile.c_str(), std::ios::binary); //open the output file | ||
385 | + if (!out) { | ||
386 | + std::cout << "ERROR opening output file: " << outfile << std::endl; | ||
387 | + return false; | ||
388 | + } | ||
389 | + file.seekg(0, std::ios::beg); //move the pointer to the current file to the beginning | ||
390 | + | ||
391 | + size_t B = Z(); //calculate the number of bands | ||
392 | + size_t XY = X() * Y(); //calculate the number of pixels in a band | ||
393 | + size_t in_bytes = XY * sizeof(T); //calculate the size of a band in bytes | ||
394 | + | ||
395 | + T* in = (T*)malloc(in_bytes); //allocate space for the band image | ||
396 | + size_t nb = bandlist.size(); //get the number of bands in the output image | ||
397 | + for (size_t b = 0; b < nb; b++) { | ||
398 | + band(in, bandlist[b]); //get the band associated with the given wavelength | ||
399 | + out.write((char*)in, in_bytes); //write the band to the output file | ||
400 | + if (PROGRESS) progress = (double)(b + 1) / (double)bandlist.size() * 100; | ||
401 | + } | ||
402 | + out.close(); | ||
403 | + free(in); | ||
404 | + return true; | ||
405 | + } | ||
406 | + | ||
383 | size_t readlines(T* dest, size_t start, size_t n){ | 407 | size_t readlines(T* dest, size_t start, size_t n){ |
384 | return hsi<T>::read(dest, 0, start, 0, X(), n, Z()); | 408 | return hsi<T>::read(dest, 0, start, 0, X(), n, Z()); |
385 | } | 409 | } |
stim/envi/envi.h
@@ -562,6 +562,41 @@ public: | @@ -562,6 +562,41 @@ public: | ||
562 | } | 562 | } |
563 | } | 563 | } |
564 | 564 | ||
565 | + bool select(std::string outfile, std::vector<double> bandlist, unsigned char* MASK = NULL, bool PROGRESS = false) { | ||
566 | + stim::envi_header new_header = header; //copy all of the data from the current header file to the new one | ||
567 | + new_header.bands = bandlist.size(); //the number of bands in the new file is equal to the number of bands provided by the user | ||
568 | + new_header.wavelength = bandlist; //the wavelength values in the output file are the same as those specified by the user | ||
569 | + new_header.band_names.empty(); //no band names will be provided in the output file | ||
570 | + new_header.save(outfile + ".hdr"); //save the output header file | ||
571 | + | ||
572 | + if (header.interleave == envi_header::BSQ) { //if the infile is bip file | ||
573 | + if (header.data_type == envi_header::float32) | ||
574 | + return ((bsq<float>*)file)->select(outfile, bandlist, MASK, PROGRESS); | ||
575 | + else if (header.data_type == envi_header::float64) | ||
576 | + return ((bsq<double>*)file)->select(outfile, bandlist, MASK, PROGRESS); | ||
577 | + else | ||
578 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
579 | + } | ||
580 | + else if (header.interleave == envi_header::BIL) { //if the infile is bip file | ||
581 | + if (header.data_type == envi_header::float32) | ||
582 | + return ((bil<float>*)file)->select(outfile, bandlist, MASK, PROGRESS); | ||
583 | + else if (header.data_type == envi_header::float64) | ||
584 | + return ((bil<double>*)file)->select(outfile, bandlist, MASK, PROGRESS); | ||
585 | + else | ||
586 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
587 | + } | ||
588 | + else if (header.interleave == envi_header::BIP) { //if the infile is bip file | ||
589 | + if (header.data_type == envi_header::float32) | ||
590 | + return ((bip<float>*)file)->select(outfile, bandlist, MASK, PROGRESS); | ||
591 | + else if (header.data_type == envi_header::float64) | ||
592 | + return ((bip<double>*)file)->select(outfile, bandlist, MASK, PROGRESS); | ||
593 | + else | ||
594 | + std::cout << "ERROR: unidentified data type" << std::endl; | ||
595 | + } | ||
596 | + | ||
597 | + return false; | ||
598 | + } | ||
599 | + | ||
565 | /// Performs piecewise linear baseline correction of a hyperspectral file/ | 600 | /// Performs piecewise linear baseline correction of a hyperspectral file/ |
566 | 601 | ||
567 | /// @param outfile is the file name for the baseline corrected output | 602 | /// @param outfile is the file name for the baseline corrected output |
stim/envi/hsi.h
@@ -55,6 +55,7 @@ protected: | @@ -55,6 +55,7 @@ protected: | ||
55 | return n; //return the number of masked pixels | 55 | return n; //return the number of masked pixels |
56 | } | 56 | } |
57 | 57 | ||
58 | + //perform linear interpolation between two bands | ||
58 | T lerp(double w, T low_v, double low_w, T high_v, double high_w){ | 59 | T lerp(double w, T low_v, double low_w, T high_v, double high_w){ |
59 | if(low_w == high_w) return low_v; //if the interval is of zero length, just return one of the bounds | 60 | if(low_w == high_w) return low_v; //if the interval is of zero length, just return one of the bounds |
60 | double alpha = (w - low_w) / (high_w - low_w); //calculate the interpolation factor | 61 | double alpha = (w - low_w) / (high_w - low_w); //calculate the interpolation factor |