Commit ba51ae6a3d666879ecea0dd9fe40a56b7ca47092
1 parent
44f44bb5
fixed metric calculations, added a finite-value mask, as_float() in stim::arglist returns a double
Showing
6 changed files
with
265 additions
and
118 deletions
Show diff stats
stim/envi/bil.h
... | ... | @@ -600,7 +600,7 @@ public: |
600 | 600 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
601 | 601 | /// @param pos2 is the label value for the second peak (denominator) position |
602 | 602 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
603 | - bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, T * result){ | |
603 | + bool ph_to_ph(T* result, double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, unsigned char* mask = NULL){ | |
604 | 604 | |
605 | 605 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
606 | 606 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
... | ... | @@ -630,8 +630,8 @@ public: |
630 | 630 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
631 | 631 | /// @param pos2 is the label value for the second peak (denominator) position |
632 | 632 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
633 | - bool pa_to_ph(double lb1, double rb1, double lab1, double rab1, | |
634 | - double lb2, double rb2, double pos, T* result){ | |
633 | + bool pa_to_ph(T* result, double lb1, double rb1, double lab1, double rab1, | |
634 | + double lb2, double rb2, double pos, unsigned char* mask = NULL){ | |
635 | 635 | |
636 | 636 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
637 | 637 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
... | ... | @@ -663,8 +663,8 @@ public: |
663 | 663 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) |
664 | 664 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) |
665 | 665 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
666 | - bool pa_to_pa(double lb1, double rb1, double lab1, double rab1, | |
667 | - double lb2, double rb2, double lab2, double rab2, T* result){ | |
666 | + bool pa_to_pa(T* result, double lb1, double rb1, double lab1, double rab1, | |
667 | + double lb2, double rb2, double lab2, double rab2, unsigned char* mask = NULL){ | |
668 | 668 | |
669 | 669 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
670 | 670 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
... | ... | @@ -773,7 +773,7 @@ public: |
773 | 773 | /// @param lab is the label for the start of the peak |
774 | 774 | /// @param rab is the label for the end of the peak |
775 | 775 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
776 | - bool cpoint(double lb, double rb, double lab, double rab, T* result){ | |
776 | + bool centroid(T* result, double lb, double rb, double lab, double rab, unsigned char* mask = NULL){ | |
777 | 777 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
778 | 778 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
779 | 779 | |
... | ... | @@ -782,9 +782,7 @@ public: |
782 | 782 | area(lb, rb, lab, rab, p2); |
783 | 783 | //calculate the ratio in result |
784 | 784 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
785 | - if(p1[i] == 0 && p2[i] ==0) | |
786 | - result[i] = 1; | |
787 | - else | |
785 | + if(mask == NULL || mask[i]) | |
788 | 786 | result[i] = p1[i] / p2[i]; |
789 | 787 | } |
790 | 788 | |
... | ... | @@ -800,16 +798,16 @@ public: |
800 | 798 | /// @param mask_band is the band used to specify the mask |
801 | 799 | /// @param threshold is the threshold used to determine if the mask value is true or false |
802 | 800 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
803 | - bool build_mask(double mask_band, double threshold, unsigned char* p, bool PROGRESS = false){ | |
801 | + bool build_mask(unsigned char* mask, double mask_band, double threshold, bool PROGRESS = false){ | |
804 | 802 | |
805 | 803 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
806 | 804 | band(temp, mask_band, PROGRESS); |
807 | 805 | |
808 | 806 | for (unsigned long long i = 0; i < X() * Y(); i++) { |
809 | 807 | if (temp[i] < threshold) |
810 | - p[i] = 0; | |
808 | + mask[i] = 0; | |
811 | 809 | else |
812 | - p[i] = 255; | |
810 | + mask[i] = 255; | |
813 | 811 | } |
814 | 812 | |
815 | 813 | free(temp); |
... | ... | @@ -850,6 +848,36 @@ public: |
850 | 848 | return true; |
851 | 849 | } |
852 | 850 | |
851 | + /// Copies all spectra corresponding to nonzero values of a mask into a pre-allocated matrix of size (B x P) | |
852 | + /// where P is the number of masked pixels and B is the number of bands. The allocated memory can be accessed | |
853 | + /// using the following indexing: i = p*B + b | |
854 | + /// @param matrix is the destination for the pixel data | |
855 | + /// @param mask is the mask | |
856 | + bool sift(T* matrix, unsigned char* mask){ | |
857 | + size_t Lbytes = sizeof(T) * X(); | |
858 | + T* line = (T*) malloc( Lbytes ); //allocate space for a line | |
859 | + | |
860 | + file.seekg(0, std::ios::beg); //seek to the beginning of the file | |
861 | + | |
862 | + size_t pl; | |
863 | + size_t p = 0; //create counter variables | |
864 | + for(size_t y = 0; y < Y(); y++){ //for each line in the data set | |
865 | + for(size_t b = 0; b < Z(); b++){ //for each band in the data set | |
866 | + pl = 0; //initialize the pixel offset for the current line to zero (0) | |
867 | + file.read( (char*)line, Lbytes ); //read the current line | |
868 | + for(size_t x = 0; x < X(); x++){ | |
869 | + if(mask[y * X() + x]){ //if the current pixel is masked | |
870 | + size_t i = (p + pl) * Z() + b; //calculate the index in the sifted matrix | |
871 | + matrix[i] = line[x]; //store the current value in the line at the correct matrix location | |
872 | + pl++; //increment the pixel pointer | |
873 | + } | |
874 | + } | |
875 | + } | |
876 | + p += pl; //add the line increment to the running pixel index | |
877 | + } | |
878 | + return true; | |
879 | + } | |
880 | + | |
853 | 881 | /// Saves to disk only those spectra corresponding to mask values != 0 |
854 | 882 | /// Unlike the BIP and BSQ versions of this function, this version saves a different format: the BIL file is saved as a BIP |
855 | 883 | bool sift(std::string outfile, unsigned char* p, bool PROGRESS = false){ | ... | ... |
stim/envi/bip.h
... | ... | @@ -526,7 +526,7 @@ public: |
526 | 526 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
527 | 527 | /// @param pos2 is the label value for the second peak (denominator) position |
528 | 528 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
529 | - bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, T * result){ | |
529 | + bool ph_to_ph(T* result, double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, unsigned char* mask = NULL){ | |
530 | 530 | |
531 | 531 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
532 | 532 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
... | ... | @@ -556,8 +556,8 @@ public: |
556 | 556 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
557 | 557 | /// @param pos2 is the label value for the second peak (denominator) position |
558 | 558 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
559 | - bool pa_to_ph(double lb1, double rb1, double lab1, double rab1, | |
560 | - double lb2, double rb2, double pos, T* result){ | |
559 | + bool pa_to_ph(T* result, double lb1, double rb1, double lab1, double rab1, | |
560 | + double lb2, double rb2, double pos, unsigned char* mask = NULL){ | |
561 | 561 | |
562 | 562 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
563 | 563 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
... | ... | @@ -589,8 +589,8 @@ public: |
589 | 589 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) |
590 | 590 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) |
591 | 591 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
592 | - bool pa_to_pa(double lb1, double rb1, double lab1, double rab1, | |
593 | - double lb2, double rb2, double lab2, double rab2, T* result){ | |
592 | + bool pa_to_pa(T* result, double lb1, double rb1, double lab1, double rab1, | |
593 | + double lb2, double rb2, double lab2, double rab2, unsigned char* mask = NULL){ | |
594 | 594 | |
595 | 595 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
596 | 596 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
... | ... | @@ -699,7 +699,7 @@ public: |
699 | 699 | /// @param lab is the label for the start of the peak |
700 | 700 | /// @param rab is the label for the end of the peak |
701 | 701 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
702 | - bool cpoint(double lb, double rb, double lab, double rab, T* result){ | |
702 | + bool centroid(T* result, double lb, double rb, double lab, double rab, unsigned char* mask = NULL){ | |
703 | 703 | T* p1 = (T*)malloc(X() * Y() * sizeof(T)); |
704 | 704 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
705 | 705 | |
... | ... | @@ -708,9 +708,7 @@ public: |
708 | 708 | area(lb, rb, lab, rab, p2); |
709 | 709 | //calculate the ratio in result |
710 | 710 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
711 | - if(p1[i] == 0 && p2[i] ==0) | |
712 | - result[i] = 1; | |
713 | - else | |
711 | + if(mask == NULL || mask[i]) | |
714 | 712 | result[i] = p1[i] / p2[i]; |
715 | 713 | } |
716 | 714 | |
... | ... | @@ -726,16 +724,16 @@ public: |
726 | 724 | /// @param mask_band is the band used to specify the mask |
727 | 725 | /// @param threshold is the threshold used to determine if the mask value is true or false |
728 | 726 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
729 | - bool build_mask(double mask_band, double threshold, unsigned char* p, bool PROGRESS = false){ | |
727 | + bool build_mask(unsigned char* mask, double mask_band, double threshold, bool PROGRESS = false){ | |
730 | 728 | |
731 | 729 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
732 | 730 | band(temp, mask_band, PROGRESS); |
733 | 731 | |
734 | 732 | for (unsigned long long i = 0; i < X() * Y();i++) { |
735 | 733 | if (temp[i] < threshold) |
736 | - p[i] = 0; | |
734 | + mask[i] = 0; | |
737 | 735 | else |
738 | - p[i] = 255; | |
736 | + mask[i] = 255; | |
739 | 737 | } |
740 | 738 | |
741 | 739 | free(temp); |
... | ... | @@ -776,6 +774,33 @@ public: |
776 | 774 | return true; //return true |
777 | 775 | } |
778 | 776 | |
777 | + /// Copies all spectra corresponding to nonzero values of a mask into a pre-allocated matrix of size (B x P) | |
778 | + /// where P is the number of masked pixels and B is the number of bands. The allocated memory can be accessed | |
779 | + /// using the following indexing: i = p*B + b | |
780 | + /// @param matrix is the destination for the pixel data | |
781 | + /// @param mask is the mask | |
782 | + bool sift(T* matrix, unsigned char* mask){ | |
783 | + size_t Bbytes = sizeof(T) * Z(); | |
784 | + size_t XY = X() * Y(); | |
785 | + T* band = (T*) malloc( Bbytes ); //allocate space for a line | |
786 | + | |
787 | + file.seekg(0, std::ios::beg); //seek to the beginning of the file | |
788 | + | |
789 | + size_t p = 0; //create counter variables | |
790 | + for(size_t xy = 0; xy < XY; xy++){ //for each pixel | |
791 | + if(mask[xy]){ //if the current pixel is masked | |
792 | + file.read( (char*)band, Bbytes ); //read the current line | |
793 | + for(size_t b = 0; b < Z(); b++){ //copy each band value to the sifted matrix | |
794 | + size_t i = p * Z() + b; //calculate the index in the sifted matrix | |
795 | + matrix[i] = band[b]; //store the current value in the line at the correct matrix location | |
796 | + } | |
797 | + p++; //increment the pixel pointer | |
798 | + } | |
799 | + else | |
800 | + file.seekg(Bbytes, std::ios::cur); //otherwise skip this band | |
801 | + } | |
802 | + return true; | |
803 | + } | |
779 | 804 | |
780 | 805 | /// Saves to disk only those spectra corresponding to mask values != 0 |
781 | 806 | bool sift(std::string outfile, unsigned char* mask, bool PROGRESS = false){ | ... | ... |
stim/envi/bsq.h
... | ... | @@ -436,9 +436,7 @@ public: |
436 | 436 | cur = (T*) malloc(S); |
437 | 437 | cur2 = (T*) malloc(S); |
438 | 438 | |
439 | - memset(result, (char)0, S); | |
440 | - | |
441 | - //find the wavelenght position in the whole band | |
439 | + //find the wavelength position in the whole band | |
442 | 440 | unsigned long long n = w.size(); |
443 | 441 | unsigned long long ai = 0; //left bound position |
444 | 442 | unsigned long long bi = n - 1; //right bound position |
... | ... | @@ -450,26 +448,30 @@ public: |
450 | 448 | std::cout<<"ERROR: left bound or right bound out of bandwidth"<<std::endl; |
451 | 449 | exit(1); |
452 | 450 | } |
453 | - //to make sure rigth bound is bigger than left bound | |
451 | + //to make sure right bound is bigger than left bound | |
454 | 452 | else if(lb > rb){ |
455 | 453 | std::cout<<"ERROR: right bound should be bigger than left bound"<<std::endl; |
456 | 454 | exit(1); |
457 | 455 | } |
458 | 456 | |
459 | - //get the position of lb and rb | |
460 | - while (lab >= w[ai]){ | |
457 | + //find the indices of the left and right baseline points | |
458 | + while (lab >= w[ai]){ | |
461 | 459 | ai++; |
462 | 460 | } |
463 | 461 | while (rab <= w[bi]){ |
464 | 462 | bi--; |
465 | 463 | } |
466 | 464 | |
467 | - band(lp, lb); | |
465 | + band(lp, lb); //get the band images for the left and right baseline points | |
468 | 466 | band(rp, rb); |
469 | 467 | |
470 | - //calculate the beginning and the ending part | |
471 | - baseline_band(lb, rb, lp, rp, rab, cur2); //ending part | |
472 | - baseline_band(lb, rb, lp, rp, w[bi], cur); | |
468 | + // calculate the average value of the indexed region | |
469 | + memset(result, 0, S); //initialize the integral to zero (0) | |
470 | + | |
471 | + //integrate the region between the specified bands and the closest indexed band | |
472 | + // this integrates the "tails" of the spectrum that lie outside the main indexed region | |
473 | + baseline_band(lb, rb, lp, rp, rab, cur2); //calculate the image for the right-most band in the integral | |
474 | + baseline_band(lb, rb, lp, rp, w[bi], cur); //calculate the image for the right-most indexed band | |
473 | 475 | for(unsigned long long j = 0; j < XY; j++){ |
474 | 476 | result[j] += (T)((rab - w[bi]) * ((double)cur[j] + (double)cur2[j]) / 2.0); |
475 | 477 | } |
... | ... | @@ -479,13 +481,12 @@ public: |
479 | 481 | result[j] += (T)((w[ai] - lab) * ((double)cur[j] + (double)cur2[j]) / 2.0); |
480 | 482 | } |
481 | 483 | |
482 | - //calculate the area | |
484 | + //integrate the main indexed region | |
483 | 485 | ai++; |
484 | - for(unsigned long long i = ai; i <= bi ;i++) | |
486 | + for(unsigned long long i = ai; i <= bi ;i++) //for each band in the integral | |
485 | 487 | { |
486 | - baseline_band(lb, rb, lp, rp, w[ai], cur2); | |
487 | - for(unsigned long long j = 0; j < XY; j++) | |
488 | - { | |
488 | + baseline_band(lb, rb, lp, rp, w[ai], cur2); //get the baselined band | |
489 | + for(unsigned long long j = 0; j < XY; j++){ //for each pixel in that band | |
489 | 490 | result[j] += (T)((w[ai] - w[ai-1]) * ((double)cur[j] + (double)cur2[j]) / 2.0); |
490 | 491 | } |
491 | 492 | std::swap(cur,cur2); //swap the band pointers |
... | ... | @@ -507,20 +508,22 @@ public: |
507 | 508 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
508 | 509 | /// @param pos2 is the label value for the second peak (denominator) position |
509 | 510 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
510 | - bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, T * result){ | |
511 | + bool ph_to_ph(T* result, double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, unsigned char* mask = NULL){ | |
511 | 512 | |
512 | - T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | |
513 | - T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | |
513 | + size_t XYbytes = X() * Y() * sizeof(T); //calculate the size of the band image (in bytes) | |
514 | + | |
515 | + T* p1 = (T*)malloc(XYbytes); //allocate space for both bands in the ratio | |
516 | + T* p2 = (T*)malloc(XYbytes); | |
514 | 517 | |
518 | + memset(result, 0, XYbytes); //initialize the ratio to zero | |
515 | 519 | //get the two peak band |
516 | 520 | height(lb1, rb1, pos1, p1); |
517 | 521 | height(lb2, rb2, pos2, p2); |
518 | 522 | //calculate the ratio in result |
519 | 523 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
520 | - if(p1[i] == 0 && p2[i] ==0) | |
521 | - result[i] = 1; | |
522 | - else | |
524 | + if(mask == NULL || mask[i]){ | |
523 | 525 | result[i] = p1[i] / p2[i]; |
526 | + } | |
524 | 527 | } |
525 | 528 | |
526 | 529 | free(p1); |
... | ... | @@ -537,20 +540,20 @@ public: |
537 | 540 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
538 | 541 | /// @param pos2 is the label value for the second peak (denominator) position |
539 | 542 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
540 | - bool pa_to_ph(double lb1, double rb1, double lab1, double rab1, | |
541 | - double lb2, double rb2, double pos, T* result){ | |
543 | + bool pa_to_ph(T* result, double lb1, double rb1, double lab1, double rab1, | |
544 | + double lb2, double rb2, double pos, unsigned char* mask = NULL){ | |
542 | 545 | |
543 | - T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | |
544 | - T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | |
546 | + size_t bytes = X() * Y() * sizeof(T); | |
547 | + T* p1 = (T*)malloc(bytes); //allocate space for both ratio components | |
548 | + T* p2 = (T*)malloc(bytes); | |
545 | 549 | |
550 | + memset(result, 0, bytes); //initialize the ratio to zero | |
546 | 551 | //get the area and the peak band |
547 | 552 | area(lb1, rb1, lab1, rab1, p1); |
548 | 553 | height(lb2, rb2, pos, p2); |
549 | 554 | //calculate the ratio in result |
550 | 555 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
551 | - if(p1[i] == 0 && p2[i] ==0) | |
552 | - result[i] = 1; | |
553 | - else | |
556 | + if(mask == NULL || mask[i]) | |
554 | 557 | result[i] = p1[i] / p2[i]; |
555 | 558 | } |
556 | 559 | |
... | ... | @@ -570,21 +573,21 @@ public: |
570 | 573 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) |
571 | 574 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) |
572 | 575 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
573 | - bool pa_to_pa(double lb1, double rb1, double lab1, double rab1, | |
574 | - double lb2, double rb2, double lab2, double rab2, T* result){ | |
576 | + bool pa_to_pa(T* result, double lb1, double rb1, double lab1, double rab1, | |
577 | + double lb2, double rb2, double lab2, double rab2, unsigned char* mask = NULL){ | |
575 | 578 | |
576 | - T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | |
577 | - T* p2 = (T*)malloc(X() * Y() * sizeof(T)); | |
579 | + size_t bytes = X() * Y() * sizeof(T); | |
580 | + T* p1 = (T*)malloc(bytes); //allocate space for each of the operands | |
581 | + T* p2 = (T*)malloc(bytes); | |
578 | 582 | |
583 | + memset(result, 0, bytes); //initialize the ratio result to zero (0) | |
579 | 584 | //get the area and the peak band |
580 | 585 | area(lb1, rb1, lab1, rab1, p1); |
581 | 586 | area(lb2, rb2, lab2, rab2, p2); |
582 | 587 | //calculate the ratio in result |
583 | 588 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
584 | - if(p1[i] == 0 && p2[i] ==0) | |
585 | - result[i] = 1; | |
586 | - else | |
587 | - result[i] = p1[i] / p2[i]; | |
589 | + if(mask == NULL || mask[i]) //if the pixel is masked | |
590 | + result[i] = p1[i] / p2[i]; //calculate the ratio | |
588 | 591 | } |
589 | 592 | |
590 | 593 | free(p1); |
... | ... | @@ -592,7 +595,7 @@ public: |
592 | 595 | return true; |
593 | 596 | } |
594 | 597 | |
595 | - /// Compute the definite integral of a baseline corrected peak. | |
598 | + /// Compute the definite integral of a baseline corrected peak weighted by the corresponding wavelength | |
596 | 599 | |
597 | 600 | /// @param lb is the label value for the left baseline point |
598 | 601 | /// @param rb is the label value for the right baseline point |
... | ... | @@ -613,8 +616,6 @@ public: |
613 | 616 | cur = (T*) malloc(S); |
614 | 617 | cur2 = (T*) malloc(S); |
615 | 618 | |
616 | - memset(result, (char)0, S); | |
617 | - | |
618 | 619 | //find the wavelenght position in the whole band |
619 | 620 | unsigned long long n = w.size(); |
620 | 621 | unsigned long long ai = 0; //left bound position |
... | ... | @@ -642,6 +643,8 @@ public: |
642 | 643 | band(lp, lb); |
643 | 644 | band(rp, rb); |
644 | 645 | |
646 | + memset(result, (char)0, S); //initialize the integral to zero (0) | |
647 | + | |
645 | 648 | //calculate the beginning and the ending part |
646 | 649 | baseline_band(lb, rb, lp, rp, rab, cur2); //ending part |
647 | 650 | baseline_band(lb, rb, lp, rp, w[bi], cur); |
... | ... | @@ -656,12 +659,11 @@ public: |
656 | 659 | |
657 | 660 | //calculate f(x) times x |
658 | 661 | ai++; |
659 | - for(unsigned long long i = ai; i <= bi ;i++) | |
660 | - { | |
662 | + for(unsigned long long i = ai; i <= bi ;i++){ | |
661 | 663 | baseline_band(lb, rb, lp, rp, w[ai], cur2); |
662 | - for(unsigned long long j = 0; j < XY; j++) | |
663 | - { | |
664 | - result[j] += (T)((w[ai] - w[ai-1]) * (w[ai] + w[ai-1]) * ((double)cur[j] + (double)cur2[j]) / 4.0); | |
664 | + for(unsigned long long j = 0; j < XY; j++){ | |
665 | + T v = (T)((w[ai] - w[ai-1]) * (w[ai] + w[ai-1]) * ((double)cur[j] + (double)cur2[j]) / 4.0); | |
666 | + result[j] += v; | |
665 | 667 | } |
666 | 668 | std::swap(cur,cur2); //swap the band pointers |
667 | 669 | } |
... | ... | @@ -674,25 +676,27 @@ public: |
674 | 676 | } |
675 | 677 | |
676 | 678 | /// Compute the centroid of a baseline corrected peak. |
679 | + /// Note that the values for the centroid can be outside of [lab, rab] if the spectrum goes negative. | |
677 | 680 | |
678 | 681 | /// @param lb is the label value for the left baseline point |
679 | 682 | /// @param rb is the label value for the right baseline point |
680 | 683 | /// @param lab is the label for the start of the peak |
681 | 684 | /// @param rab is the label for the end of the peak |
682 | 685 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
683 | - bool cpoint(double lb, double rb, double lab, double rab, T* result){ | |
684 | - T* p1 = (T*)malloc(X() * Y() * sizeof(T)); | |
686 | + bool centroid(T* result, double lb, double rb, double lab, double rab, unsigned char* mask = NULL){ | |
687 | + size_t bytes = X() * Y() * sizeof(T); //calculate the number of bytes in a band image | |
688 | + T* p1 = (T*)malloc(X() * Y() * sizeof(T)); //allocate space for both operands | |
685 | 689 | T* p2 = (T*)malloc(X() * Y() * sizeof(T)); |
686 | 690 | |
691 | + memset(result, 0, bytes); //initialize the ratio result to zero (0) | |
687 | 692 | //get the area and the peak band |
688 | 693 | x_area(lb, rb, lab, rab, p1); |
689 | 694 | area(lb, rb, lab, rab, p2); |
690 | 695 | //calculate the ratio in result |
691 | 696 | for(unsigned long long i = 0; i < X() * Y(); i++){ |
692 | - if(p1[i] == 0 && p2[i] ==0) | |
693 | - result[i] = 1; | |
694 | - else | |
697 | + if(mask == NULL || mask[i]){ | |
695 | 698 | result[i] = p1[i] / p2[i]; |
699 | + } | |
696 | 700 | } |
697 | 701 | |
698 | 702 | free(p1); |
... | ... | @@ -707,16 +711,16 @@ public: |
707 | 711 | /// @param mask_band is the band used to specify the mask |
708 | 712 | /// @param threshold is the threshold used to determine if the mask value is true or false |
709 | 713 | /// @param p is a pointer to a pre-allocated array at least X * Y in size |
710 | - bool build_mask(double mask_band, double threshold, unsigned char* p = NULL, bool PROGRESS = false){ | |
714 | + bool build_mask(unsigned char* mask, double mask_band, double threshold, bool PROGRESS = false){ | |
711 | 715 | |
712 | 716 | T* temp = (T*)malloc(X() * Y() * sizeof(T)); //allocate memory for the certain band |
713 | 717 | band(temp, mask_band); |
714 | 718 | |
715 | 719 | for (unsigned long long i = 0; i < X() * Y(); i++) { |
716 | 720 | if (temp[i] < threshold) |
717 | - p[i] = 0; | |
721 | + mask[i] = 0; | |
718 | 722 | else |
719 | - p[i] = 255; | |
723 | + mask[i] = 255; | |
720 | 724 | |
721 | 725 | if(PROGRESS) progress = (double) (i+1) / (X() * Y()) * 100; |
722 | 726 | } | ... | ... |
stim/envi/envi.h
... | ... | @@ -475,31 +475,31 @@ public: |
475 | 475 | /// @param mask_band is the label for the band that will be used to build the mask |
476 | 476 | /// @param threshold is a value selected such that all band values greater than threshold will have a mask value of 'true' |
477 | 477 | /// @param p is memory of size X*Y that will store the resulting mask |
478 | - bool build_mask(double mask_band, double threshold, unsigned char* p = NULL, bool PROGRESS = false) { | |
478 | + bool build_mask(unsigned char* mask, double mask_band, double threshold, bool PROGRESS = false) { | |
479 | 479 | |
480 | 480 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
481 | 481 | if(header.data_type ==envi_header::float32) |
482 | - return ((bsq<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
482 | + return ((bsq<float>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); | |
483 | 483 | else if(header.data_type == envi_header::float64) |
484 | - return ((bsq<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
484 | + return ((bsq<double>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); | |
485 | 485 | else |
486 | 486 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
487 | 487 | } |
488 | 488 | |
489 | 489 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
490 | 490 | if(header.data_type ==envi_header::float32) |
491 | - return ((bil<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
491 | + return ((bil<float>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); | |
492 | 492 | else if(header.data_type == envi_header::float64) |
493 | - return ((bil<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
493 | + return ((bil<double>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); | |
494 | 494 | else |
495 | 495 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
496 | 496 | } |
497 | 497 | |
498 | 498 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
499 | 499 | if(header.data_type ==envi_header::float32) |
500 | - return ((bip<float>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
500 | + return ((bip<float>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); | |
501 | 501 | else if(header.data_type == envi_header::float64) |
502 | - return ((bip<double>*)file)->build_mask(mask_band, threshold, p, PROGRESS); | |
502 | + return ((bip<double>*)file)->build_mask(mask, mask_band, threshold, PROGRESS); | |
503 | 503 | else |
504 | 504 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
505 | 505 | } |
... | ... | @@ -507,6 +507,36 @@ public: |
507 | 507 | return false; |
508 | 508 | } |
509 | 509 | |
510 | + /// Creates a mask with a true value for all pixels that contain finite values | |
511 | + void mask_finite(unsigned char* mask, bool PROGRESS = false){ | |
512 | + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | |
513 | + if(header.data_type ==envi_header::float32) | |
514 | + ((bsq<float>*)file)->mask_finite(mask, PROGRESS); | |
515 | + else if(header.data_type == envi_header::float64) | |
516 | + ((bsq<double>*)file)->mask_finite(mask, PROGRESS); | |
517 | + else | |
518 | + std::cout<<"ERROR: unidentified data type"<<std::endl; | |
519 | + } | |
520 | + | |
521 | + else if(header.interleave == envi_header::BIL){ //if the infile is bil file | |
522 | + if(header.data_type ==envi_header::float32) | |
523 | + ((bil<float>*)file)->mask_finite(mask, PROGRESS); | |
524 | + else if(header.data_type == envi_header::float64) | |
525 | + ((bil<double>*)file)->mask_finite(mask, PROGRESS); | |
526 | + else | |
527 | + std::cout<<"ERROR: unidentified data type"<<std::endl; | |
528 | + } | |
529 | + | |
530 | + else if(header.interleave == envi_header::BIP){ //if the infile is bip file | |
531 | + if(header.data_type ==envi_header::float32) | |
532 | + ((bip<float>*)file)->mask_finite(mask, PROGRESS); | |
533 | + else if(header.data_type == envi_header::float64) | |
534 | + ((bip<double>*)file)->mask_finite(mask, PROGRESS); | |
535 | + else | |
536 | + std::cout<<"ERROR: unidentified data type"<<std::endl; | |
537 | + } | |
538 | + } | |
539 | + | |
510 | 540 | /// Applies a mask to the ENVI file. |
511 | 541 | |
512 | 542 | /// @param outfile is the name of the resulting masked output file |
... | ... | @@ -560,17 +590,31 @@ public: |
560 | 590 | return ((bsq<float>*)file)->sift((float*)matrix, p); |
561 | 591 | else if (header.data_type == envi_header::float64) |
562 | 592 | return ((bsq<double>*)file)->sift((double*)matrix, p); |
563 | - else | |
593 | + else{ | |
564 | 594 | std::cout << "ERROR: unidentified data type" << std::endl; |
595 | + exit(1); | |
596 | + } | |
565 | 597 | } |
566 | 598 | |
567 | 599 | if (header.interleave == envi_header::BIP){ |
568 | - std::cout<<"Memory sifting not supported for BIP files"<<std::endl; | |
569 | - exit(1); | |
600 | + if (header.data_type == envi_header::float32) | |
601 | + return ((bip<float>*)file)->sift((float*)matrix, p); | |
602 | + else if (header.data_type == envi_header::float64) | |
603 | + return ((bip<double>*)file)->sift((double*)matrix, p); | |
604 | + else{ | |
605 | + std::cout << "ERROR: unidentified data type" << std::endl; | |
606 | + exit(1); | |
607 | + } | |
570 | 608 | } |
571 | 609 | if (header.interleave == envi_header::BIL){ |
572 | - std::cout<<"Memory sifting not supported for BIL files"<<std::endl; | |
573 | - exit(1); | |
610 | + if (header.data_type == envi_header::float32) | |
611 | + return ((bil<float>*)file)->sift((float*)matrix, p); | |
612 | + else if (header.data_type == envi_header::float64) | |
613 | + return ((bil<double>*)file)->sift((double*)matrix, p); | |
614 | + else{ | |
615 | + std::cout << "ERROR: unidentified data type" << std::endl; | |
616 | + exit(1); | |
617 | + } | |
574 | 618 | } |
575 | 619 | return false; |
576 | 620 | |
... | ... | @@ -684,30 +728,30 @@ public: |
684 | 728 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
685 | 729 | /// @param pos2 is the label value for the second peak (denominator) position |
686 | 730 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
687 | - bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, void * result){ | |
731 | + bool ph_to_ph(void * result, double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, unsigned char* mask){ | |
688 | 732 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
689 | 733 | if(header.data_type ==envi_header::float32) |
690 | - return ((bsq<float>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); | |
734 | + return ((bsq<float>*)file)->ph_to_ph((float*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); | |
691 | 735 | else if(header.data_type == envi_header::float64) |
692 | - return ((bsq<double>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); | |
736 | + return ((bsq<double>*)file)->ph_to_ph((double*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); | |
693 | 737 | else |
694 | 738 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
695 | 739 | } |
696 | 740 | |
697 | 741 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
698 | 742 | if(header.data_type ==envi_header::float32) |
699 | - return ((bil<float>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); | |
743 | + return ((bil<float>*)file)->ph_to_ph((float*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); | |
700 | 744 | else if(header.data_type == envi_header::float64) |
701 | - return ((bil<double>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); | |
745 | + return ((bil<double>*)file)->ph_to_ph((double*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); | |
702 | 746 | else |
703 | 747 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
704 | 748 | } |
705 | 749 | |
706 | 750 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
707 | 751 | if(header.data_type ==envi_header::float32) |
708 | - return ((bip<float>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); | |
752 | + return ((bip<float>*)file)->ph_to_ph((float*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); | |
709 | 753 | else if(header.data_type == envi_header::float64) |
710 | - return ((bip<double>*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); | |
754 | + return ((bip<double>*)file)->ph_to_ph((double*)result, lb1, rb1, pos1, lb2, rb2, pos2, mask); | |
711 | 755 | else |
712 | 756 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
713 | 757 | } |
... | ... | @@ -728,30 +772,30 @@ public: |
728 | 772 | /// @param rb2 is the label value for the right baseline point for the second peak (denominator) |
729 | 773 | /// @param pos2 is the label value for the second peak (denominator) position |
730 | 774 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
731 | - bool pa_to_ph(double lb1, double rb1, double lab1, double rab1, double lb2, double rb2, double pos, void * result){ | |
775 | + bool pa_to_ph(void* result, double lb1, double rb1, double lab1, double rab1, double lb2, double rb2, double pos, unsigned char* mask = NULL){ | |
732 | 776 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
733 | 777 | if(header.data_type ==envi_header::float32) |
734 | - return ((bsq<float>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); | |
778 | + return ((bsq<float>*)file)->pa_to_ph((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); | |
735 | 779 | else if(header.data_type == envi_header::float64) |
736 | - return ((bsq<double>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); | |
780 | + return ((bsq<double>*)file)->pa_to_ph((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); | |
737 | 781 | else |
738 | 782 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
739 | 783 | } |
740 | 784 | |
741 | 785 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
742 | 786 | if(header.data_type ==envi_header::float32) |
743 | - return ((bil<float>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); | |
787 | + return ((bil<float>*)file)->pa_to_ph((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); | |
744 | 788 | else if(header.data_type == envi_header::float64) |
745 | - return ((bil<double>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); | |
789 | + return ((bil<double>*)file)->pa_to_ph((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); | |
746 | 790 | else |
747 | 791 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
748 | 792 | } |
749 | 793 | |
750 | 794 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
751 | 795 | if(header.data_type ==envi_header::float32) |
752 | - return ((bip<float>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); | |
796 | + return ((bip<float>*)file)->pa_to_ph((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); | |
753 | 797 | else if(header.data_type == envi_header::float64) |
754 | - return ((bip<double>*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); | |
798 | + return ((bip<double>*)file)->pa_to_ph((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, pos, mask); | |
755 | 799 | else |
756 | 800 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
757 | 801 | } |
... | ... | @@ -774,31 +818,31 @@ public: |
774 | 818 | /// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator) |
775 | 819 | /// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator) |
776 | 820 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
777 | - bool pa_to_pa(double lb1, double rb1, double lab1, double rab1, | |
778 | - double lb2, double rb2, double lab2, double rab2, void* result){ | |
821 | + bool pa_to_pa(void* result, double lb1, double rb1, double lab1, double rab1, | |
822 | + double lb2, double rb2, double lab2, double rab2, unsigned char* mask = NULL){ | |
779 | 823 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
780 | 824 | if(header.data_type ==envi_header::float32) |
781 | - return ((bsq<float>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); | |
825 | + return ((bsq<float>*)file)->pa_to_pa((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); | |
782 | 826 | else if(header.data_type == envi_header::float64) |
783 | - return ((bsq<double>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); | |
827 | + return ((bsq<double>*)file)->pa_to_pa((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); | |
784 | 828 | else |
785 | 829 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
786 | 830 | } |
787 | 831 | |
788 | 832 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
789 | 833 | if(header.data_type ==envi_header::float32) |
790 | - return ((bil<float>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); | |
834 | + return ((bil<float>*)file)->pa_to_pa((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); | |
791 | 835 | else if(header.data_type == envi_header::float64) |
792 | - return ((bil<double>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); | |
836 | + return ((bil<double>*)file)->pa_to_pa((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); | |
793 | 837 | else |
794 | 838 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
795 | 839 | } |
796 | 840 | |
797 | 841 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
798 | 842 | if(header.data_type ==envi_header::float32) |
799 | - return ((bip<float>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); | |
843 | + return ((bip<float>*)file)->pa_to_pa((float*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); | |
800 | 844 | else if(header.data_type == envi_header::float64) |
801 | - return ((bip<double>*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); | |
845 | + return ((bip<double>*)file)->pa_to_pa((double*)result, lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, mask); | |
802 | 846 | else |
803 | 847 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
804 | 848 | } |
... | ... | @@ -817,30 +861,30 @@ public: |
817 | 861 | /// @param lab is the label for the start of the peak |
818 | 862 | /// @param rab is the label for the end of the peak |
819 | 863 | /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size |
820 | - bool cpoint(double lb1, double rb1, double lab1, double rab1, void* result){ | |
864 | + bool centroid(void* result, double lb1, double rb1, double lab1, double rab1, unsigned char* mask = NULL){ | |
821 | 865 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file |
822 | 866 | if(header.data_type ==envi_header::float32) |
823 | - return ((bsq<float>*)file)->cpoint(lb1, rb1, lab1, rab1, (float*)result); | |
867 | + return ((bsq<float>*)file)->centroid((float*)result, lb1, rb1, lab1, rab1, mask); | |
824 | 868 | else if(header.data_type == envi_header::float64) |
825 | - return ((bsq<double>*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); | |
869 | + return ((bsq<double>*)file)->centroid((double*)result, lb1, rb1, lab1, rab1, mask); | |
826 | 870 | else |
827 | 871 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
828 | 872 | } |
829 | 873 | |
830 | 874 | else if(header.interleave == envi_header::BIL){ //if the infile is bil file |
831 | 875 | if(header.data_type ==envi_header::float32) |
832 | - return ((bil<float>*)file)->cpoint(lb1, rb1, lab1, rab1, (float*)result); | |
876 | + return ((bil<float>*)file)->centroid((float*)result, lb1, rb1, lab1, rab1, mask); | |
833 | 877 | else if(header.data_type == envi_header::float64) |
834 | - return ((bil<double>*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); | |
878 | + return ((bil<double>*)file)->centroid((double*)result, lb1, rb1, lab1, rab1, mask); | |
835 | 879 | else |
836 | 880 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
837 | 881 | } |
838 | 882 | |
839 | 883 | else if(header.interleave == envi_header::BIP){ //if the infile is bip file |
840 | 884 | if(header.data_type ==envi_header::float32) |
841 | - return ((bip<float>*)file)->cpoint(lb1, rb1, lab1, rab1,(float*)result); | |
885 | + return ((bip<float>*)file)->centroid((float*)result, lb1, rb1, lab1, rab1, mask); | |
842 | 886 | else if(header.data_type == envi_header::float64) |
843 | - return ((bip<double>*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); | |
887 | + return ((bip<double>*)file)->centroid((double*)result, lb1, rb1, lab1, rab1, mask); | |
844 | 888 | else |
845 | 889 | std::cout<<"ERROR: unidentified data type"<<std::endl; |
846 | 890 | } | ... | ... |
stim/envi/hsi.h
... | ... | @@ -6,6 +6,12 @@ |
6 | 6 | #include <cstring> |
7 | 7 | #include <utility> |
8 | 8 | |
9 | +#ifdef _WIN32 | |
10 | + #include <float.h> | |
11 | +#else | |
12 | + #include<cmath> | |
13 | +#endif | |
14 | + | |
9 | 15 | namespace stim{ |
10 | 16 | |
11 | 17 | /** |
... | ... | @@ -113,6 +119,46 @@ protected: |
113 | 119 | |
114 | 120 | return c[2] * R[0] * R[1] + c[1] * R[0] + c[0]; //calculate and return the index (trust me this works) |
115 | 121 | } |
122 | + | |
123 | + /// Returns the 3D coordinates of a specified index | |
124 | + void xyb(size_t idx, size_t& x, size_t& y, size_t& b){ | |
125 | + | |
126 | + size_t c[3]; | |
127 | + | |
128 | + c[2] = idx / (R[0] * R[1]); | |
129 | + c[1] = (idx - c[2] * R[0] * R[1]) / R[0]; | |
130 | + c[0] = idx - c[2] * R[0] * R[1] - c[1] * R[0]; | |
131 | + | |
132 | + x = c[O[0]]; | |
133 | + y = c[O[1]]; | |
134 | + b = c[O[2]]; | |
135 | + } | |
136 | + | |
137 | +public: | |
138 | + /// Get a mask that has all pixels with inf or NaN values masked out (false) | |
139 | + void mask_finite(unsigned char* mask, bool PROGRESS = false){ | |
140 | + size_t XY = X() * Y(); | |
141 | + memset(mask, 255, XY * sizeof(unsigned char)); //initialize the mask to zero (0) | |
142 | + T* page = (T*)malloc(R[0] * R[1] * sizeof(T)); //allocate space for a page of data | |
143 | + | |
144 | + for(size_t p = 0; p < R[2]; p++){ //for each page | |
145 | + binary<T>::read_page(page, p); //read a page | |
146 | + for(size_t i = 0; i < R[0] * R[1]; i++){ //for each pixel in that page | |
147 | + | |
148 | +#ifdef _WIN32 | |
149 | + if(!_finite(page[i])){ //if the value at index i is finite | |
150 | +#else | |
151 | + if(!std::isfinite(page[i])){ //C++11 implementation | |
152 | +#endif | |
153 | + size_t x, y, b; | |
154 | + xyb(p * R[0] * R[1] + i, x, y, b); //find the 3D coordinates of the value | |
155 | + mask[ y * X() + x ] = 0; //mask the pixel (it's not bad) | |
156 | + } | |
157 | + } | |
158 | + if(PROGRESS) progress = (double)(p + 1) / (double)R[2] * 100; | |
159 | + } | |
160 | + } | |
161 | + | |
116 | 162 | }; |
117 | 163 | |
118 | 164 | } //end namespace STIM | ... | ... |