OTB  6.7.0
Orfeo Toolbox
otbVegetationIndicesFunctor.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbVegetationIndicesFunctor_h
22 #define otbVegetationIndicesFunctor_h
23 
24 #include "otbMath.h"
26 #include "otbBandName.h"
27 #include <string>
28 
29 namespace otb
30 {
31 
32 namespace Functor
33 {
34 
49 template<class TInput1, class TInput2, class TOutput>
51 {
52 public:
56 
57  //operators !=
58  bool operator !=(const RAndNIRIndexBase&) const
59  {
60  return true;
61  }
62  //operator ==
63  bool operator ==(const RAndNIRIndexBase& other) const
64  {
65  return !(*this != other);
66  }
67 
68  // Operator on vector pixel type
69  inline TOutput operator ()(const InputVectorType& inputVector) const
70  {
71  return this->Evaluate(inputVector[m_RedIndex - 1], static_cast<TInput2>(inputVector[m_NIRIndex - 1]));
72  }
73 
74  // Binary operator
75  inline TOutput operator ()(const TInput1& r, const TInput2& nir) const
76  {
77  return this->Evaluate(r, nir);
78  }
82  virtual ~RAndNIRIndexBase() {}
83 
85  void SetIndex(BandName::BandName band, unsigned int channel)
86  {
87  if (band == BandName::RED)
88  {
89  m_RedIndex = channel;
90  }
91  if (band == BandName::NIR)
92  {
93  m_NIRIndex = channel;
94  }
95  }
96 
98  unsigned int GetIndex(BandName::BandName band) const
99  {
100  if (band == BandName::RED)
101  {
102  return m_RedIndex;
103  }
104  if (band == BandName::NIR)
105  {
106  return m_NIRIndex;
107  }
108  }
110 
112  void SetRedIndex(unsigned int channel)
113  {
114  m_RedIndex = channel;
115  }
117  unsigned int GetRedIndex() const
118  {
119  return m_RedIndex;
120  }
122  void SetNIRIndex(unsigned int channel)
123  {
124  m_NIRIndex = channel;
125  }
127  unsigned int GetNIRIndex() const
128  {
129  return m_NIRIndex;
130  }
131 
133  virtual std::string GetName() const = 0;
134 
135 protected:
136  // This method must be reimplemented in subclasses to actually
137  // compute the index value
138  virtual TOutput Evaluate(const TInput1& r, const TInput2& nir) const = 0;
140 
141 private:
142  unsigned int m_RedIndex;
143  unsigned int m_NIRIndex;
144 };
145 
158 template<class TInput1, class TInput2, class TInput3, class TOutput>
160 {
161 public:
165 
166  //operators !=
168  {
169  return true;
170  }
171 
172  //operator ==
173  bool operator ==(const RAndBAndNIRIndexBase& other) const
174  {
175  return !(*this != other);
176  }
177 
178  // Operator on vector pixel type
179  inline TOutput operator ()(const InputVectorType& inputVector)
180  {
181  return this->Evaluate(inputVector[m_RedIndex - 1],
182  static_cast<TInput2>(inputVector[m_BlueIndex - 1]),
183  static_cast<TInput3>(inputVector[m_NIRIndex - 1]));
184  }
185  // Binary operator
186  inline TOutput operator ()(const TInput1& r, const TInput2& b, const TInput2& nir)
187  {
188  return this->Evaluate(r, b, nir);
189  }
194 
196  void SetIndex(BandName::BandName band, unsigned int channel)
197  {
198  if (band == BandName::RED)
199  {
200  m_RedIndex = channel;
201  }
202  if (band == BandName::BLUE)
203  {
204  m_BlueIndex = channel;
205  }
206  if (band == BandName::NIR)
207  {
208  m_NIRIndex = channel;
209  }
210  }
211 
213  unsigned int GetIndex(BandName::BandName band) const
214  {
215  if (band == BandName::RED)
216  {
217  return m_RedIndex;
218  }
219  if (band == BandName::BLUE)
220  {
221  return m_BlueIndex;
222  }
223  if (band == BandName::NIR)
224  {
225  return m_NIRIndex;
226  }
227  }
229 
231  void SetRedIndex(unsigned int channel)
232  {
233  m_RedIndex = channel;
234  }
236  unsigned int GetRedIndex() const
237  {
238  return m_RedIndex;
239  }
241  void SetBlueIndex(unsigned int channel)
242  {
243  m_BlueIndex = channel;
244  }
246  unsigned int GetBlueIndex() const
247  {
248  return m_BlueIndex;
249  }
250 
252  void SetNIRIndex(unsigned int channel)
253  {
254  m_NIRIndex = channel;
255  }
257  unsigned int GetNIRIndex() const
258  {
259  return m_NIRIndex;
260  }
261 
263  virtual std::string GetName() const = 0;
264 
265 protected:
266  // This method must be reimplemented in subclasses to actually
267  // compute the index value
268  virtual TOutput Evaluate(const TInput1& r, const TInput2& b, const TInput3& nir) const = 0;
270 
271 private:
272  unsigned int m_RedIndex;
273  unsigned int m_BlueIndex;
274  unsigned int m_NIRIndex;
275 };
276 
289 template<class TInput1, class TInput2, class TInput3, class TOutput>
291 {
292 public:
296 
297  //operators !=
299  {
300  return true;
301  }
302  //operator ==
303  bool operator ==(const RAndGAndNIRIndexBase& other) const
304  {
305  return !(*this != other);
306  }
307 
308  // Operator on vector pixel type
309  inline TOutput operator ()(const InputVectorType& inputVector)
310  {
311  return this->Evaluate(inputVector[m_RedIndex - 1],
312  static_cast<TInput2>(inputVector[m_GreenIndex - 1]),
313  static_cast<TInput3>(inputVector[m_NIRIndex - 1]));
314  }
315 
316  // Binary operator
317  inline TOutput operator ()(const TInput1& r, const TInput2& g, const TInput2& nir)
318  {
319  return this->Evaluate(r, g, nir);
320  }
325 
327  void SetIndex(BandName::BandName band, unsigned int channel)
328  {
329  if (band == BandName::RED)
330  {
331  m_RedIndex = channel;
332  }
333  if (band == BandName::GREEN)
334  {
335  m_GreenIndex = channel;
336  }
337  if (band == BandName::NIR)
338  {
339  m_NIRIndex = channel;
340  }
341  }
342 
344  unsigned int GetIndex(BandName::BandName band) const
345  {
346  if (band == BandName::RED)
347  {
348  return m_RedIndex;
349  }
350  if (band == BandName::GREEN)
351  {
352  return m_GreenIndex;
353  }
354  if (band == BandName::NIR)
355  {
356  return m_NIRIndex;
357  }
358  }
360 
362  void SetRedIndex(unsigned int channel)
363  {
364  m_RedIndex = channel;
365  }
367  unsigned int GetRedIndex() const
368  {
369  return m_RedIndex;
370  }
372  void SetGreenIndex(unsigned int channel)
373  {
374  m_GreenIndex = channel;
375  }
377  unsigned int GetGreenIndex() const
378  {
379  return m_GreenIndex;
380  }
381 
383  void SetNIRIndex(unsigned int channel)
384  {
385  m_NIRIndex = channel;
386  }
388  unsigned int GetNIRIndex() const
389  {
390  return m_NIRIndex;
391  }
392 
394  virtual std::string GetName() const = 0;
395 
396 protected:
397  // This method must be reimplemented in subclasses to actually
398  // compute the index value
399  virtual TOutput Evaluate(const TInput1& r, const TInput2& g, const TInput3& nir) const = 0;
401 
402 private:
403  unsigned int m_RedIndex;
404  unsigned int m_GreenIndex;
405  unsigned int m_NIRIndex;
406 };
407 
418 template <class TInput1, class TInput2, class TOutput>
419 class NDVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
420 {
421 public:
422 
424  std::string GetName() const override
425  {
426  return "NDVI";
427  }
428 
430  NDVI() {}
432  ~NDVI() override {}
433  // Operator on r and nir single pixel values
434 protected:
435  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
436  {
437  double dr = static_cast<double>(r);
438  double dnir = static_cast<double>(nir);
439  if (std::abs(dnir + dr) < this->m_EpsilonToBeConsideredAsZero)
440  {
441  return static_cast<TOutput>(0.);
442  }
443 
444  return (static_cast<TOutput>((dnir - dr) / (dnir + dr)));
445  }
446 };
447 
458 template <class TInput1, class TInput2, class TOutput>
459 class RVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
460 {
461 public:
462 
464  std::string GetName() const override
465  {
466  return "RVI";
467  }
468 
469  RVI() {}
470  ~RVI() override {}
471 protected:
472  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
473  {
474  double dr = static_cast<double>(r);
475  double dnir = static_cast<double>(nir);
476  if (std::abs(dr) < this->m_EpsilonToBeConsideredAsZero)
477  {
478  return static_cast<TOutput>(0.);
479  }
480  return (static_cast<TOutput>(dnir / dr));
481  }
482 };
483 
498 template <class TInput1, class TInput2, class TOutput>
499 class PVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
500 {
501 public:
503  std::string GetName() const override
504  {
505  return "PVI";
506  }
507 
508  PVI() : m_A(0.90893), m_B(7.46216), m_Coeff(0.74) {}
509  ~PVI() override {}
511  void SetA(const double A)
512  {
513  m_A = A;
514  m_Coeff = 1. / (std::sqrt(m_A * m_A + 1.));
515  }
516  double GetA(void) const
517  {
518  return (m_A);
519  }
520  void SetB(const double B)
521  {
522  m_B = B;
523  }
524  double GetB(void) const
525  {
526  return (m_B);
527  }
528 protected:
529  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
530  {
531  double dnir = static_cast<double>(nir);
532  double dr = static_cast<double>(r);
533  return (static_cast<TOutput>((dnir - m_A * dr - m_B) * m_Coeff));
534  }
536 
537 private:
538 
540  double m_A;
541  double m_B;
542 
544  double m_Coeff;
545 
546 };
547 
558 template <class TInput1, class TInput2, class TOutput>
559 class SAVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
560 {
561 public:
562 
564  std::string GetName() const override
565  {
566  return "SAVI";
567  }
568 
569  SAVI() : m_L(0.5) {}
570  ~SAVI() override {}
571 
573  void SetL(const double L)
574  {
575  m_L = L;
576  }
577  double GetL(void) const
578  {
579  return (m_L);
580  }
582 
583 protected:
584  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
585  {
586  double dnir = static_cast<double>(nir);
587  double dr = static_cast<double>(r);
588  double denominator = dnir + dr + m_L;
589  if (std::abs(denominator) < this->m_EpsilonToBeConsideredAsZero)
590  {
591  return static_cast<TOutput>(0.);
592  }
593  return (static_cast<TOutput>(((dnir - dr) * (1 + m_L)) / denominator));
594  }
595 
596 private:
597 
599  double m_L;
600 
601 };
602 
613 template <class TInput1, class TInput2, class TOutput>
614 class TSAVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
615 {
616 public:
617 
619  std::string GetName() const override
620  {
621  return "TSAVI";
622  }
623 
624  TSAVI() : m_A(0.7), m_S(0.9), m_X(0.08) {}
625  ~TSAVI() override {}
626 
628  void SetS(const double S)
629  {
630  m_S = S;
631  }
632  double GetS(void) const
633  {
634  return (m_S);
635  }
636  void SetA(const double A)
637  {
638  m_A = A;
639  }
640  double GetA(void) const
641  {
642  return (m_A);
643  }
644 
646  void SetX(const double X)
647  {
648  m_X = X;
649  }
650  double GetX(void) const
651  {
652  return (m_X);
653  }
655 
656 protected:
657  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
658  {
659  double dnir = static_cast<double>(nir);
660  double dr = static_cast<double>(r);
661  double denominator = m_A * dnir + dr + m_X * (1. + m_A * m_A);
662  if (std::abs(denominator) < this->m_EpsilonToBeConsideredAsZero)
663  {
664  return static_cast<TOutput>(0.);
665  }
666  return (static_cast<TOutput>((m_A * (dnir - m_A * dr - m_S)) / denominator));
667  }
668 
669 private:
670 
672  double m_A;
673  double m_S;
674 
676  double m_X;
677 
678 };
679 
690 template <class TInput1, class TInput2, class TOutput>
691 class WDVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
692 {
693 public:
695  std::string GetName() const override
696  {
697  return "WDVI";
698  }
699 
701  WDVI() : m_S(0.4) {}
703  ~WDVI() override {}
704  // Operator on r and nir single pixel values
706  void SetS(const double s)
707  {
708  m_S = s;
709  }
710  double GetS(void) const
711  {
712  return (m_S);
713  }
714 protected:
715  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
716  {
717  double dr = static_cast<double>(r);
718  double dnir = static_cast<double>(nir);
720 
721  return (dnir - m_S * dr);
722  }
723 private:
725  double m_S;
726 };
727 
739 template <class TInput1, class TInput2, class TOutput>
740 class MSAVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
741 {
742 public:
744  std::string GetName() const override
745  {
746  return "MSAVI";
747  }
748 
752  MSAVI() : m_S(0.4)
753  {
755  }
756  ~MSAVI() override {}
758  void SetS(const double s)
759  {
760  m_S = s;
762  }
763  double GetS(void) const
764  {
765  return (m_S);
766  }
768  {
769  return (m_NDVIfunctor);
770  }
772  {
773  return (m_WDVIfunctor);
774  }
776 
777 protected:
778  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
779  {
780  double dnir = static_cast<double>(nir);
781  double dr = static_cast<double>(r);
782 
783  double dNDVI = this->GetNDVI() (r, nir);
784  double dWDVI = this->GetWDVI() (r, nir);
785  double dL = 1 - 2 * m_S * dNDVI * dWDVI;
786 
787  double denominator = dnir + dr + dL;
788 
789  if (std::abs(denominator) < this->m_EpsilonToBeConsideredAsZero)
790  {
791  return static_cast<TOutput>(0.);
792  }
793 
794  return (static_cast<TOutput>(((dnir - dr) * (1 + dL)) / denominator));
795  }
796 
797 private:
799  double m_S;
802 
803 };
804 
815 template <class TInput1, class TInput2, class TOutput>
816 class MSAVI2 : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
817 {
818 public:
820  std::string GetName() const override
821  {
822  return "MSAVI2";
823  }
824 
825  MSAVI2() {}
826  ~MSAVI2() override {}
827 
828 protected:
829  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
830  {
831  double dnir = static_cast<double>(nir);
832  double dr = static_cast<double>(r);
833  double sqrt_value = (2 * dnir + 1) * (2 * dnir + 1) - 8 * (dnir - dr);
834  if (sqrt_value < 0.)
835  {
836  return static_cast<TOutput>(0.);
837  }
838  return (static_cast<TOutput>((2 * dnir + 1 - std::sqrt(sqrt_value)) / 2.));
839  }
840 
841 };
842 
853 template <class TInput1, class TInput2, class TOutput>
854 class GEMI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
855 {
856 public:
858  std::string GetName() const override
859  {
860  return "GEMI";
861  }
862 
863  GEMI() {}
864  ~GEMI() override {}
865 
866 protected:
867  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
868  {
869  double dnir = static_cast<double>(nir);
870  double dr = static_cast<double>(r);
871 
872  double dnu;
873  double dnumerateur_nu;
874  double ddenominateur_nu = dnir + dr + 0.5;
875  if (std::abs(ddenominateur_nu) < this->m_EpsilonToBeConsideredAsZero)
876  {
877  dnu = 0;
878  }
879  else
880  {
881  dnumerateur_nu = 2 * (dnir * dnir - dr * dr) + 1.5 * dnir + 0.5 * dr;
882  dnu = dnumerateur_nu / ddenominateur_nu;
883  }
884 
885  double ddenominateur_GEMI = 1 - dr;
886  if (std::abs(ddenominateur_GEMI) < this->m_EpsilonToBeConsideredAsZero)
887  {
888  return static_cast<TOutput>(0.);
889  }
890  return (static_cast<TOutput>((dnu * (1 - 0.25 * dnu) - (dr - 0.125)) / ddenominateur_GEMI));
891  }
892 
893 };
894 
907 template <class TInput1, class TInput2, class TInput3, class TOutput>
908 class AVI : public RAndGAndNIRIndexBase<TInput1, TInput2, TInput3, TOutput>
909 {
910 public:
912  std::string GetName() const override
913  {
914  return "AVI";
915  }
916 
917  AVI() : m_LambdaG(560.), m_LambdaR(660.), m_LambdaNir(830.) {}
918  ~AVI() override {}
920  void SetLambdaR(const double lr)
921  {
922  m_LambdaR = lr;
923  }
924  double GetLambdaR(void) const
925  {
926  return (m_LambdaR);
927  }
928 
930  void SetLambdaG(const double lg)
931  {
932  m_LambdaG = lg;
933  }
934  double GetLambdaG(void) const
935  {
936  return (m_LambdaG);
937  }
938 
940  void SetLambdaNir(const double lnir)
941  {
942  m_LambdaNir = lnir;
943  }
944  double GetLambdaNir(void) const
945  {
946  return (m_LambdaNir);
947  }
948 protected:
949  inline TOutput Evaluate(const TInput1& r, const TInput2& g, const TInput3& nir) const override
950  {
951  double dr = static_cast<double>(r);
952  double dg = static_cast<double>(g);
953  double dnir = static_cast<double>(nir);
955 
956  double dfact1 = (m_LambdaNir - m_LambdaR) / m_LambdaR;
957  double dfact2 = (m_LambdaR - m_LambdaG) / m_LambdaR;
958  double dterm1;
959  double dterm2;
960  if (std::abs(dnir - dr) < this->m_EpsilonToBeConsideredAsZero)
961  {
962  dterm1 = 0;
963  }
964  else
965  {
966  dterm1 = std::atan(dfact1 / (dnir - dr));
967  }
968 
969  if (std::abs(dg - dr) < this->m_EpsilonToBeConsideredAsZero)
970  {
971  dterm2 = 0;
972  }
973  else
974  {
975  dterm2 = std::atan(dfact2 / (dg - dr));
976  }
977 
978  return static_cast<TOutput>(dterm1 + dterm2);
979 
980  }
981 private:
982 
984  double m_LambdaG;
985 
987  double m_LambdaR;
988 
990  double m_LambdaNir;
991 };
992 
1005 template <class TInput1, class TInput2, class TInput3, class TOutput>
1006 class ARVI : public RAndBAndNIRIndexBase<TInput1, TInput2, TInput3, TOutput>
1007 {
1008 public:
1010  std::string GetName() const override
1011  {
1012  return "ARVI";
1013  }
1014 
1015  ARVI() : m_Gamma(0.5) {}
1016  ~ARVI() override {}
1017 
1019  void SetGamma(const double gamma)
1020  {
1021  m_Gamma = gamma;
1022  }
1023  double GetGamma(void) const
1024  {
1025  return (m_Gamma);
1026  }
1028 
1029 protected:
1030  inline TOutput Evaluate(const TInput1& r, const TInput2& b, const TInput3& nir) const override
1031  {
1032  double dr = static_cast<double>(r);
1033  double db = static_cast<double>(b);
1034  double dnir = static_cast<double>(nir);
1035  double RHOrb = dr - m_Gamma * (db - dr);
1036  double denominator = dnir + RHOrb;
1037  if (std::abs(denominator) < this->m_EpsilonToBeConsideredAsZero)
1038  {
1039  return static_cast<TOutput>(0.);
1040  }
1041  return (static_cast<TOutput>((dnir - RHOrb) / denominator));
1042  }
1043 
1044 private:
1045 
1047  double m_Gamma;
1048 };
1049 
1060 template <class TInput1, class TInput2, class TInput3, class TOutput>
1061 class TSARVI : public RAndBAndNIRIndexBase<TInput1, TInput2, TInput3, TOutput>
1062 {
1063 public:
1065  std::string GetName() const override
1066  {
1067  return "TSARVI";
1068  }
1069 
1070  TSARVI() : m_A(0.0), m_B(0.0), m_X(0.08), m_Gamma(0.5) {}
1071  ~TSARVI() override {}
1072 
1074  void SetA(const double A)
1075  {
1076  m_A = A;
1077  }
1078  double GetA(void) const
1079  {
1080  return (m_A);
1081  }
1082  void SetB(const double B)
1083  {
1084  m_B = B;
1085  }
1086  double GetB(void) const
1087  {
1088  return (m_B);
1089  }
1090 
1092  void SetX(const double X)
1093  {
1094  m_X = X;
1095  }
1096  double GetX(void) const
1097  {
1098  return (m_X);
1099  }
1100 
1102  void SetGamma(const double gamma)
1103  {
1104  m_Gamma = gamma;
1105  }
1106  double GetGamma(void) const
1107  {
1108  return (m_Gamma);
1109  }
1111 
1112 protected:
1113  inline TOutput Evaluate(const TInput1& r, const TInput2& b, const TInput3& nir) const override
1114  {
1115  double dr = static_cast<double>(r);
1116  double db = static_cast<double>(b);
1117  double dnir = static_cast<double>(nir);
1118  double dRB = dr - m_Gamma * (db - dr);
1119  double denominator = dRB + m_A * dnir - m_A * m_B + m_X * (1. + m_A * m_A);
1120  if (std::abs(denominator) < this->m_EpsilonToBeConsideredAsZero)
1121  {
1122  return static_cast<TOutput>(0.);
1123  }
1124  return (static_cast<TOutput>((m_A * (dnir - m_A * dRB - m_B)) / denominator));
1125  }
1126 
1127 private:
1128 
1130  double m_A;
1131  double m_B;
1132 
1134  double m_X;
1135 
1137  double m_Gamma;
1138 
1139 };
1140 
1153 template <class TInput1, class TInput2, class TInput3, class TOutput>
1154 class EVI : public RAndBAndNIRIndexBase<TInput1, TInput2, TInput3, TOutput>
1155 {
1156 public:
1158  std::string GetName() const override
1159  {
1160  return "EVI";
1161  }
1162 
1163  EVI() : m_G(2.5), m_C1(6.0), m_C2(7.5), m_L(1.0) {}
1164  ~EVI() override {}
1166  void SetG(const double g)
1167  {
1168  m_G = g;
1169  }
1170  double GetG(void) const
1171  {
1172  return (m_G);
1173  }
1174 
1176  void SetC1(const double c1)
1177  {
1178  m_C1 = c1;
1179  }
1180  double GetC1(void) const
1181  {
1182  return (m_C1);
1183  }
1184 
1186  void SetC2(const double c2)
1187  {
1188  m_C2 = c2;
1189  }
1190  double GetC2(void) const
1191  {
1192  return (m_C2);
1193  }
1194 
1196  void SetL(const double l)
1197  {
1198  m_L = l;
1199  }
1200  double GetL(void) const
1201  {
1202  return (m_L);
1203  }
1204 protected:
1205  inline TOutput Evaluate(const TInput1& r, const TInput2& b, const TInput3& nir) const override
1206  {
1207  double dr = static_cast<double>(r);
1208  double db = static_cast<double>(b);
1209  double dnir = static_cast<double>(nir);
1210  double denominator = dnir + m_C1 * dr - m_C2 * db + m_L;
1211  if (std::abs(denominator) < this->m_EpsilonToBeConsideredAsZero)
1212  {
1213  return (static_cast<TOutput>(0.));
1214  }
1215  return (static_cast<TOutput>(m_G * (dnir - dr) / denominator));
1216  }
1218 
1219 private:
1220 
1222  double m_G;
1223 
1225  double m_C1;
1226 
1228  double m_C2;
1229 
1231  double m_L;
1232 };
1233 
1244 template <class TInput1, class TInput2, class TOutput>
1245 class IPVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
1246 {
1247 public:
1249  std::string GetName() const override
1250  {
1251  return "IPVI";
1252  }
1253 
1254  IPVI() {}
1255  ~IPVI() override {}
1256 
1257 protected:
1258  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
1259  {
1260  double dr = static_cast<double>(r);
1261  double dnir = static_cast<double>(nir);
1262  if (std::abs(dnir + dr) < this->m_EpsilonToBeConsideredAsZero)
1263  {
1264  return static_cast<TOutput>(0.);
1265  }
1266  else
1267  {
1268  return (static_cast<TOutput>(dnir / (dnir + dr)));
1269  }
1270  }
1271 };
1272 
1283 template <class TInput1, class TInput2, class TOutput>
1284 class TNDVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
1285 {
1286 public:
1288  std::string GetName() const override
1289  {
1290  return "TNDVI";
1291  }
1292 
1294  TNDVI() {}
1295  ~TNDVI() override {}
1296 
1298  {
1299  return (m_NDVIfunctor);
1300  }
1301 
1302 protected:
1303  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
1304  {
1305  double dval = this->GetNDVI() (r, nir) + 0.5;
1306  if (dval < 0)
1307  {
1308  return (static_cast<TOutput>(0));
1309  }
1310  else
1311  {
1312  return (static_cast<TOutput>(std::sqrt(dval)));
1313  }
1314  }
1315 private:
1317 };
1318 
1335 template <class TInput1, class TInput2, class TOutput>
1336 class LAIFromNDVILogarithmic : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
1337 {
1338 public:
1340  std::string GetName() const override
1341  {
1342  return "LAIFromNDVILogarithmic";
1343  }
1344 
1348 
1350  {
1351  return (m_NDVIfunctor);
1352  }
1353 
1354  void SetNdviSoil(const double val)
1355  {
1356  m_NdviSoil = val;
1357  }
1358  double GetNdviSoil(void) const
1359  {
1360  return (m_NdviSoil);
1361  }
1362 
1363  void SetNdviInf(const double val)
1364  {
1365  m_NdviInf = val;
1366  }
1367  double GetNdviInf(void) const
1368  {
1369  return (m_NdviInf);
1370  }
1371 
1372  void SetExtinctionCoefficient(const double val)
1373  {
1375  }
1376  double GetExtinctionCoefficient(void) const
1377  {
1378  return (m_ExtinctionCoefficient);
1379  }
1380 
1381 protected:
1382  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
1383  {
1384  double dval = this->GetNDVI() (r, nir);
1385  if (dval < 0)
1386  {
1387  return (static_cast<TOutput>(0));
1388  }
1389  else
1390  {
1391  return (static_cast<TOutput>(
1392  -(1.0/m_ExtinctionCoefficient)*std::log((dval- m_NdviInf)/(m_NdviSoil-m_NdviInf))
1393  ));
1394  }
1395  }
1396 private:
1398  double m_NdviSoil;
1399  double m_NdviInf;
1401 };
1402 
1403 
1421 template <class TInput1, class TInput2, class TOutput>
1422 class LAIFromReflectancesLinear : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
1423 {
1424 public:
1426  std::string GetName() const override
1427  {
1428  return "LAIFromReflectancesLinear";
1429  }
1430 
1434 
1436  {
1437  return (m_NDVIfunctor);
1438  }
1439 
1440  void SetRedCoef(const double val)
1441  {
1442  m_RedCoef = val;
1443  }
1444  double GetRedCoef(void) const
1445  {
1446  return (m_RedCoef);
1447  }
1448 
1449  void SetNirCoef(const double val)
1450  {
1451  m_NirCoef = val;
1452  }
1453  double GetNirCoef(void) const
1454  {
1455  return (m_NirCoef);
1456  }
1457 
1458 protected:
1459  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
1460  {
1461  return (static_cast<TOutput>(m_RedCoef*r+m_NirCoef*nir));
1462  }
1463 private:
1465  double m_RedCoef;
1466  double m_NirCoef;
1467 };
1468 
1469 
1489  template <class TInput1, class TInput2, class TOutput>
1490  class LAIFromNDVIFormosat2Functor : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
1491  {
1492  public:
1493 
1495  std::string GetName() const override
1496  {
1497  return "LAIFromNDVIFormosat2Functor";
1498  }
1499 
1504  // Operator on r and nir single pixel values
1505  protected:
1506  inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const override
1507  {
1508  double a = 0.1519;
1509  double b = 3.9443;
1510  double c = 0.13;
1511 
1512  double dr = static_cast<double>(r);
1513  double dnir = static_cast<double>(nir);
1514  if (std::abs(dnir + dr) < this->m_EpsilonToBeConsideredAsZero)
1515  {
1516  return static_cast<TOutput>(0.);
1517  }
1518 
1519  return static_cast<TOutput>(a*(std::exp(static_cast<double>(dnir-dr)/static_cast<double>(dr+dnir)*b)-std::exp(c*b)));
1520  };
1521 
1522 
1523 };
1524 
1525 
1526 } // namespace Functor
1527 } // namespace otb
1528 
1529 #endif
This functor computes the Perpendicular Vegetation Index (PVI)
void SetNIRIndex(unsigned int channel)
Set NIR Index.
This functor computes the Ratio Vegetation Index (RVI)
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
std::string GetName() const override
void SetLambdaR(const double lr)
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
TOutput operator()(const InputVectorType &inputVector) const
This functor computes the Soil Adjusted Vegetation Index (SAVI)
virtual TOutput Evaluate(const TInput1 &r, const TInput2 &b, const TInput3 &nir) const =0
virtual std::string GetName() const =0
WDVI< TInput1, TInput2, TOutput > WDVIFunctorType
TOutput operator()(const InputVectorType &inputVector)
This functor computes the Modified Soil Adjusted Vegetation Index (MSAVI)
void SetGamma(const double gamma)
void SetRedIndex(unsigned int channel)
Set Red Index.
NDVI< TInput1, TInput2, TOutput > NDVIFunctorType
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
void SetC1(const double c1)
virtual TOutput Evaluate(const TInput1 &r, const TInput2 &g, const TInput3 &nir) const =0
Base class for R And NIR based Index.
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
std::string GetName() const override
TOutput Evaluate(const TInput1 &r, const TInput2 &g, const TInput3 &nir) const override
This functor computes the Transformed Soil Atmospherical Resistant Vegetation Index (TSARVI) ...
std::string GetName() const override
This functor computes the Normalized Difference Vegetation Index (NDVI)
itk::VariableLengthVector< TInput1 > InputVectorType
std::string GetName() const override
This functor computes the Global Environment Monitoring Index (GEMI)
~NDVI() override
Desctructor.
This functor computes the Modified Soil Adjusted Vegetation Index (MSAVI2)
unsigned int GetIndex(BandName::BandName band) const
std::string GetName() const override
WDVIFunctorType GetWDVI(void) const
TOutput Evaluate(const TInput1 &r, const TInput2 &b, const TInput3 &nir) const override
NDVIFunctorType GetNDVI(void) const
unsigned int GetRedIndex() const
Get Red Index.
std::string GetName() const override
void SetIndex(BandName::BandName band, unsigned int channel)
double GetLambdaG(void) const
NDVIFunctorType GetNDVI(void) const
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
itk::VariableLengthVector< TInput1 > InputVectorType
This functor computes the Transformed Soil Adjusted Vegetation Index (TSAVI)
unsigned int GetNIRIndex() const
Get NIR Index.
NDVI< TInput1, TInput2, TOutput > NDVIFunctorType
bool operator==(const RAndBAndNIRIndexBase &other) const
unsigned int GetNIRIndex() const
Get NIR Index.
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
void SetRedIndex(unsigned int channel)
Set Red Index.
std::string GetName() const override
TOutput Evaluate(const TInput1 &r, const TInput2 &b, const TInput3 &nir) const override
std::string GetName() const override
TOutput Evaluate(const TInput1 &r, const TInput2 &b, const TInput3 &nir) const override
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
This functor computes the Transformed NDVI (TNDVI)
std::string GetName() const override
double GetLambdaR(void) const
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
void SetNIRIndex(unsigned int channel)
Set NIR Index.
This functor computes the Infrared Percentage Vegetation Index (IPVI)
std::string GetName() const override
use red and nir image band to compute LAI image using formula a*(exp(nir-red)/((red+nir)*b)-exp(c*b))...
void SetIndex(BandName::BandName band, unsigned int channel)
void SetRedIndex(unsigned int channel)
Set Red Index.
bool operator!=(const RAndNIRIndexBase &) const
bool operator!=(const RAndBAndNIRIndexBase &) const
void SetBlueIndex(unsigned int channel)
Set Blue Index.
void SetGamma(const double gamma)
bool operator==(const RAndGAndNIRIndexBase &other) const
unsigned int GetRedIndex() const
Get Red Index.
std::string GetName() const override
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
virtual TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const =0
std::string GetName() const override
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
void SetNIRIndex(unsigned int channel)
Set NIR Index.
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
unsigned int GetGreenIndex() const
Get Green Index.
unsigned int GetIndex(BandName::BandName band) const
unsigned int GetRedIndex() const
Get Red Index.
void SetC2(const double c2)
This functor computes the Atmospherically Resistant Vegetation Index (ARVI)
void SetGreenIndex(unsigned int channel)
Set Green Index.
double GetLambdaNir(void) const
std::string GetName() const override
itk::VariableLengthVector< TInput1 > InputVectorType
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
bool operator==(const RAndNIRIndexBase &other) const
~WDVI() override
Desctructor.
This functor computes the Weighted Difference Vegetation Index (WDVI)
NDVI< TInput1, TInput2, TOutput > NDVIFunctorType
void SetIndex(BandName::BandName band, unsigned int channel)
unsigned int GetIndex(BandName::BandName band) const
std::string GetName() const override
base class for R, B And NIR based Index Implement operators for UnaryFunctorImageFilter templated wit...
bool operator!=(const RAndGAndNIRIndexBase &) const
unsigned int GetNIRIndex() const
Get NIR Index.
base class for R, G And NIR based Index Implement operators for UnaryFunctorImageFilter templated wit...
void SetLambdaG(const double lg)
This functor computes the Angular Vegetation Index (AVI)
TOutput operator()(const InputVectorType &inputVector)
This functor computes the Enhanced Vegetation Index (EVI)
unsigned int GetBlueIndex() const
Get Blue Index.
SAVI< TInput1, TInput2, TOutput > SAVIFunctorType
virtual std::string GetName() const =0
NDVI< TInput1, TInput2, TOutput > NDVIFunctorType
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override
virtual std::string GetName() const =0
std::string GetName() const override
void SetLambdaNir(const double lnir)
TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const override