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 | 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 | 470 | /// Convert the current BIL file to a BSQ file with the specified file name. |
466 | 471 | |
467 | 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 | 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 | 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 | 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 | 407 | size_t readlines(T* dest, size_t start, size_t n){ |
384 | 408 | return hsi<T>::read(dest, 0, start, 0, X(), n, Z()); |
385 | 409 | } | ... | ... |
stim/envi/envi.h
... | ... | @@ -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 | 600 | /// Performs piecewise linear baseline correction of a hyperspectral file/ |
566 | 601 | |
567 | 602 | /// @param outfile is the file name for the baseline corrected output | ... | ... |
stim/envi/hsi.h
... | ... | @@ -55,6 +55,7 @@ protected: |
55 | 55 | return n; //return the number of masked pixels |
56 | 56 | } |
57 | 57 | |
58 | + //perform linear interpolation between two bands | |
58 | 59 | T lerp(double w, T low_v, double low_w, T high_v, double high_w){ |
59 | 60 | if(low_w == high_w) return low_v; //if the interval is of zero length, just return one of the bounds |
60 | 61 | double alpha = (w - low_w) / (high_w - low_w); //calculate the interpolation factor | ... | ... |