OTB  6.7.0
Orfeo Toolbox
otbLandsatTMIndices.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 otbLandsatTMIndices_h
22 #define otbLandsatTMIndices_h
23 
24 #include "otbMath.h"
26 #include "otbBandName.h"
27 #include "otbFuzzyVariable.h"
28 #include <vector>
29 #include <algorithm>
30 #include <string>
31 
32 namespace otb
33 {
34 
35 namespace Functor
36 {
37 
38 namespace LandsatTM
39 {
40 
42 enum SATType {L5, L7};
66 template<class TInput, class TOutput>
68 {
69 public:
70 
71  //operators !=
72  bool operator !=(const LandsatTMIndexBase&) const
73  {
74  return false;
75  }
76  //operator ==
77  bool operator ==(const LandsatTMIndexBase& other) const
78  {
79  return !(*this != other);
80  }
81 
85  virtual ~LandsatTMIndexBase() {}
86 
88  void SetIndex(BandName::LandsatTMBandNames band, unsigned int channel)
89  {
90  switch( band )
91  {
92  case BandName::TM1:
93  m_TM1 = channel;
94  break;
95  case BandName::TM2:
96  m_TM2 = channel;
97  break;
98  case BandName::TM3:
99  m_TM3 = channel;
100  break;
101  case BandName::TM4:
102  m_TM4 = channel;
103  break;
104  case BandName::TM5:
105  m_TM5 = channel;
106  break;
107  case BandName::TM60:
108  m_TM60 = channel;
109  break;
110  case BandName::TM61:
111  m_TM61 = channel;
112  break;
113  case BandName::TM62:
114  m_TM62 = channel;
115  break;
116  case BandName::TM7:
117  m_TM7 = channel;
118  break;
119  }
120  }
121 
123  unsigned int GetIndex(BandName::LandsatTMBandNames band) const
124  {
125  switch( band )
126  {
127  case BandName::TM1:
128  return m_TM1;
129  break;
130  case BandName::TM2:
131  return m_TM2;
132  break;
133  case BandName::TM3:
134  return m_TM3;
135  break;
136  case BandName::TM4:
137  return m_TM4;
138  break;
139  case BandName::TM5:
140  return m_TM5;
141  break;
142  case BandName::TM60:
143  return m_TM60;
144  break;
145  case BandName::TM61:
146  return m_TM61;
147  break;
148  case BandName::TM62:
149  return m_TM62;
150  break;
151  case BandName::TM7:
152  return m_TM7;
153  break;
154  }
155  return m_TM1;
156  }
158 
159  unsigned int GetTM1() const
160  {
161  return this->m_TM1;
162  }
163 
164  unsigned int GetTM2() const
165  {
166  return this->m_TM2;
167  }
168 
169  unsigned int GetTM3() const
170  {
171  return this->m_TM3;
172  }
173 
174  unsigned int GetTM4() const
175  {
176  return this->m_TM4;
177  }
178 
179  unsigned int GetTM5() const
180  {
181  return this->m_TM5;
182  }
183 
184  unsigned int GetTM60() const
185  {
186  return this->m_TM60;
187  }
188 
189  unsigned int GetTM61() const
190  {
191  return this->m_TM61;
192  }
193 
194  unsigned int GetTM62() const
195  {
196  return this->m_TM62;
197  }
198 
199  unsigned int GetTM7() const
200  {
201  return this->m_TM7;
202  }
203 
204  void SetSAT(SATType sat)
205  {
206 
207  this->m_SAT = sat;
208 
209  if( sat == L5 )
210  {
211  m_TM1 = 0;
212  m_TM2 = 1;
213  m_TM3 = 2;
214  m_TM4 = 3;
215  m_TM5 = 4;
216  m_TM60 = 5;
217  m_TM7 = 6;
218  m_SAT = L5;
219  }
220  else
221  {
222  m_TM1 = 0;
223  m_TM2 = 1;
224  m_TM3 = 2;
225  m_TM4 = 3;
226  m_TM5 = 4;
227  m_TM61 = 5;
228  m_TM62 = 6;
229  m_TM7 = 7;
230  m_SAT = L7;
231  }
232  }
233 
234  SATType GetSAT() const
235  {
236  return this->m_SAT;
237  }
238 
240  {
241  this->m_Degree = deg;
242  }
243 
245  {
246  return this->m_Degree;
247  }
248 
250  {
251  this->m_Reflectance = ref;
252  }
253 
255  {
256  return this->m_Reflectance;
257  }
258 
260  {
261  return this->m_EpsilonToBeConsideredAsZero;
262  }
263 
264 protected:
266 
267  TInput PrepareValues(const TInput& inputPixel)
268  {
269 
270  TInput newPix( inputPixel );
271  if( this->m_Degree == Kelvin )
272  {
273  if(this->m_SAT == L5)
274  {
275  newPix[this->m_TM60] = newPix[this->m_TM60]-273.15;
276  }
277  else
278  {
279  newPix[this->m_TM61] = newPix[this->m_TM61]-273.15;
280  newPix[this->m_TM62] = newPix[this->m_TM62]-273.15;
281  }
282  }
283  else
284  if( this->m_Degree == HundredsKelvin )
285  {
286  if(this->m_SAT == L5)
287  {
288  newPix[this->m_TM60] = newPix[this->m_TM60]/100.-273.15;
289  }
290  else
291  {
292  newPix[this->m_TM61] = newPix[this->m_TM61]/100.-273.15;
293  newPix[this->m_TM62] = newPix[this->m_TM62]/100.-273.15;
294  }
295  }
296  if( this->m_Reflectance == Thousands )
297  {
298  newPix[this->m_TM1] = newPix[this->m_TM1]/1000.;
299  newPix[this->m_TM2] = newPix[this->m_TM2]/1000.;
300  newPix[this->m_TM3] = newPix[this->m_TM3]/1000.;
301  newPix[this->m_TM4] = newPix[this->m_TM4]/1000.;
302  newPix[this->m_TM5] = newPix[this->m_TM5]/1000.;
303  newPix[this->m_TM7] = newPix[this->m_TM7]/1000.;
304  }
305 
306  return newPix;
307  }
308 
309 
311 
312  unsigned int m_TM1;
313  unsigned int m_TM2;
314  unsigned int m_TM3;
315  unsigned int m_TM4;
316  unsigned int m_TM5;
317  unsigned int m_TM60;
318  unsigned int m_TM61;
319  unsigned int m_TM62;
320  unsigned int m_TM7;
321 
325 
326 };
327 
328 
337 template <class TInput, class TOutput>
338 class LandsatTMIndex : public LandsatTMIndexBase<TInput, TOutput>
339 {
340 public:
341 
342  // Operator performing the work
343  inline TOutput operator ()(const TInput& inputPixel) const;
344 
346  virtual std::string GetName() const = 0;
347 
349  ~LandsatTMIndex() override {}
350 
351 
352 };
353 
371 template <class TInput, class TOutput>
372 class Bright : public LandsatTMIndex<TInput, TOutput>
373 {
374 public:
376  std::string GetName() const override
377  {
378  return "Bright";
379  }
380 
381  Bright() {}
382  ~Bright() override {}
383 
384  inline TOutput operator ()(const TInput& inputPixel)
385  {
386 
387  TInput newPixel(this->PrepareValues( inputPixel ));
388  double result = (newPixel[this->m_TM1]+newPixel[this->m_TM2]+2*newPixel[this->m_TM3]+2*newPixel[this->m_TM4]+newPixel[this->m_TM5]+newPixel[this->m_TM7])/8.0;
389  return static_cast<TOutput>(result);
390  }
391 
392 
393 };
394 
412 template <class TInput, class TOutput>
413 class Vis : public LandsatTMIndex<TInput, TOutput>
414 {
415 public:
417  std::string GetName() const override
418  {
419  return "Vis";
420  }
421 
422  Vis() {}
423  ~Vis() override {}
424 
425  inline TOutput operator ()(const TInput& inputPixel)
426  {
427  TInput newPixel(this->PrepareValues( inputPixel ));
428  double result = (newPixel[this->m_TM1]+newPixel[this->m_TM2]+newPixel[this->m_TM3])/3.0;
429  return static_cast<TOutput>(result);
430  }
431 
432 
433 };
434 
435 
445 template <class TInput, class TOutput>
446 class NIR : public LandsatTMIndex<TInput, TOutput>
447 {
448 public:
450  std::string GetName() const override
451  {
452  return "NIR";
453  }
454 
455  NIR() {}
456  ~NIR() override {}
457 
458  inline TOutput operator ()(const TInput& inputPixel)
459  {
460  TInput newPixel(this->PrepareValues( inputPixel ));
461  double result = newPixel[this->m_TM4];
462  return static_cast<TOutput>(result);
463  }
464 
465 
466 };
467 
477 template <class TInput, class TOutput>
478 class MIR1 : public LandsatTMIndex<TInput, TOutput>
479 {
480 public:
482  std::string GetName() const override
483  {
484  return "MIR1";
485  }
486 
487  MIR1() {}
488  ~MIR1() override {}
489 
490  inline TOutput operator ()(const TInput& inputPixel)
491  {
492  TInput newPixel(this->PrepareValues( inputPixel ));
493  double result = newPixel[this->m_TM5];
494  return static_cast<TOutput>(result);
495  }
496 
497 
498 };
499 
509 template <class TInput, class TOutput>
510 class MIR2 : public LandsatTMIndex<TInput, TOutput>
511 {
512 public:
514  std::string GetName() const override
515  {
516  return "MIR2";
517  }
518 
519  MIR2() {}
520  ~MIR2() override {}
521 
522  inline TOutput operator ()(const TInput& inputPixel)
523  {
524  TInput newPixel(this->PrepareValues( inputPixel ));
525  double result = newPixel[this->m_TM7];
526  return static_cast<TOutput>(result);
527  }
528 
529 
530 };
531 
541 template <class TInput, class TOutput>
542 class TIR : public LandsatTMIndex<TInput, TOutput>
543 {
544 public:
546  std::string GetName() const override
547  {
548  return "TIR";
549  }
550 
551  TIR() {}
552  ~TIR() override {}
553 
554  inline TOutput operator ()(const TInput& inputPixel)
555  {
556  TInput newPixel(this->PrepareValues( inputPixel ));
557  double result = newPixel[this->m_TM62];
558 
559  if( this->m_SAT == L5 )
560  result = newPixel[this->m_TM60];
561 
562  return static_cast<TOutput>(result);
563  }
564 
565 
566 };
567 
587 template <class TInput, class TOutput>
588 class MIRTIR : public LandsatTMIndex<TInput, TOutput>
589 {
590 public:
592  std::string GetName() const override
593  {
594  return "MIRTIR";
595  }
596 
597  MIRTIR() {}
598  ~MIRTIR() override {}
599 
600  inline TOutput operator ()(const TInput& inputPixel)
601  {
602  TInput newPixel(this->PrepareValues( inputPixel ));
603  double tir = newPixel[this->m_TM62];
604  double mir1 = newPixel[this->m_TM5];
605 
606  if( this->m_SAT == L5 )
607  tir = newPixel[this->m_TM60];
608 
609  double result = 255*(1 - mir1)*(tir+100)/100.;
610 
611  return static_cast<TOutput>(result);
612  }
613 
614 
615 };
616 
627 template <class TInput, class TOutput>
628 class NDVI : public LandsatTMIndex<TInput, TOutput>
629 {
630 public:
632  std::string GetName() const override
633  {
634  return "NDVI";
635  }
636 
637  NDVI() {}
638  ~NDVI() override {}
639 
640  inline TOutput operator ()(const TInput& inputPixel)
641  {
642  TInput newPixel(this->PrepareValues( inputPixel ));
643  double result = (newPixel[this->m_TM4] - newPixel[this->m_TM3])/
644  (newPixel[this->m_TM4] + newPixel[this->m_TM3] + this->m_EpsilonToBeConsideredAsZero);
645 
646  return static_cast<TOutput>(result);
647  }
648 
649 
650 };
651 
674 template <class TInput, class TOutput>
675 class NDBSI : public LandsatTMIndex<TInput, TOutput>
676 {
677 public:
679  std::string GetName() const override
680  {
681  return "NDBSI";
682  }
683 
684  NDBSI() {}
685  ~NDBSI() override {}
686 
687  inline TOutput operator ()(const TInput& inputPixel)
688  {
689  TInput newPixel(this->PrepareValues( inputPixel ));
690  double result = (newPixel[this->m_TM5] - newPixel[this->m_TM4])/
691  (newPixel[this->m_TM5] + newPixel[this->m_TM4] + this->m_EpsilonToBeConsideredAsZero);
692 
693  return static_cast<TOutput>(result);
694  }
695 
696 
697 };
698 
717 template <class TInput, class TOutput>
718 class BIO : public LandsatTMIndex<TInput, TOutput>
719 {
720 public:
722  std::string GetName() const override
723  {
724  return "BIO";
725  }
726 
727  BIO() {}
728  ~BIO() override {}
729 
730  inline TOutput operator ()(const TInput& inputPixel)
731  {
732  TInput newPixel(this->PrepareValues( inputPixel ));
733  double result = ((newPixel[this->m_TM5] + newPixel[this->m_TM3])
734  - (newPixel[this->m_TM4] + newPixel[this->m_TM1]))
735  /((newPixel[this->m_TM5] + newPixel[this->m_TM3])
736  + (newPixel[this->m_TM4] + newPixel[this->m_TM1]));
737 
738  return static_cast<TOutput>(result);
739  }
740 
741 
742 };
743 
744 
763 template <class TInput, class TOutput>
764 class NDSI : public LandsatTMIndex<TInput, TOutput>
765 {
766 public:
768  std::string GetName() const override
769  {
770  return "NDSI";
771  }
772 
773  NDSI() {}
774  ~NDSI() override {}
775 
776  inline TOutput operator ()(const TInput& inputPixel)
777  {
778  TInput newPixel(this->PrepareValues( inputPixel ));
779  double result = (newPixel[this->m_TM2] - newPixel[this->m_TM5])
780  /(newPixel[this->m_TM2] + newPixel[this->m_TM5] + this->m_EpsilonToBeConsideredAsZero);
781 
782  return static_cast<TOutput>(result);
783  }
784 
785 
786 };
787 
820 template <class TInput, class TOutput>
821 class NDSIVis : public LandsatTMIndex<TInput, TOutput>
822 {
823 public:
825  std::string GetName() const override
826  {
827  return "NDSIVis";
828  }
829 
830  NDSIVis() {}
831  ~NDSIVis() override {}
832 
833  inline TOutput operator ()(const TInput& inputPixel)
834  {
835  TInput newPixel(this->PrepareValues( inputPixel ));
836  double vis = (newPixel[this->m_TM1]+newPixel[this->m_TM2]+newPixel[this->m_TM3])/3.0;
837  double result = (vis - newPixel[this->m_TM5])/(vis + newPixel[this->m_TM5] + this->m_EpsilonToBeConsideredAsZero);
838 
839  return static_cast<TOutput>(result);
840  }
841 
842 
843 };
844 
865 template <class TInput, class TOutput>
866 class NDBBBI : public LandsatTMIndex<TInput, TOutput>
867 {
868 public:
870  std::string GetName() const override
871  {
872  return "NDBBBI";
873  }
874 
875  NDBBBI() {}
876  ~NDBBBI() override {}
877 
878  inline TOutput operator ()(const TInput& inputPixel)
879  {
880  TInput newPixel(this->PrepareValues( inputPixel ));
881  double result = (newPixel[this->m_TM1] - newPixel[this->m_TM5])
882  /(newPixel[this->m_TM1] + newPixel[this->m_TM5] + this->m_EpsilonToBeConsideredAsZero);
883  return static_cast<TOutput>(result);
884  }
885 
886 
887 };
888 
910 template <class TInput>
911 class LinguisticVariables : public LandsatTMIndexBase<TInput, itk::FixedArray<unsigned int, 11> >
912 {
913 public:
914 
915  typedef typename TInput::ValueType PrecisionType;
918 
921 
923  virtual std::string GetName() const
924  {
925  return "LandsatTM Linguistic Variables";
926  }
927 
929  {
941 
944 
945  // the thresholds are computed wrt Baraldi's paper (normalized 0-255 values)
946  m_FvBright->SetMembership(Low, minimumValue, minimumValue, 40/255., 40/255.);
947  m_FvBright->SetMembership(Medium, 40/255., 40/255., 60/255., 60/255.);
948  m_FvBright->SetMembership(High, 60/255., 60/255., maximumValue, maximumValue);
949 
950  m_FvVis->SetMembership(Low, minimumValue, minimumValue, 30/255., 30/255.);
951  m_FvVis->SetMembership(Medium, 30/255., 30/255., 50/255., 50/255.);
952  m_FvVis->SetMembership(High, 50/255., 50/255., maximumValue, maximumValue);
953 
954  m_FvNIR->SetMembership(Low, minimumValue, minimumValue, 40/255., 40/255.);
955  m_FvNIR->SetMembership(Medium, 40/255., 40/255., 60/255., 60/255.);
956  m_FvNIR->SetMembership(High, 60/255., 60/255., maximumValue, maximumValue);
957 
958  m_FvMIR1->SetMembership(Low, minimumValue, minimumValue, 40/255., 40/255.);
959  m_FvMIR1->SetMembership(Medium, 40/255., 40/255., 60/255., 60/255.);
960  m_FvMIR1->SetMembership(High, 60/255., 60/255., maximumValue, maximumValue);
961 
962  m_FvMIR2->SetMembership(Low, minimumValue, minimumValue, 30/255., 30/255.);
963  m_FvMIR2->SetMembership(Medium, 30/255., 30/255., 50/255., 50/255.);
964  m_FvMIR2->SetMembership(High, 50/255., 50/255., maximumValue, maximumValue);
965 
966  m_FvTIR->SetMembership(Low, minimumValue, minimumValue, 0, 0);
967  m_FvTIR->SetMembership(Medium, 0, 0, 28, 28);
968  m_FvTIR->SetMembership(High, 28, 28, maximumValue, maximumValue);
969 
970  m_FvMIRTIR->SetMembership(Low, minimumValue, minimumValue, 180, 180);
971  m_FvMIRTIR->SetMembership(Medium, 180, 180, 220, 220);
972  m_FvMIRTIR->SetMembership(High, 220, 220, maximumValue, maximumValue);
973 
974  m_FvNDSIVis->SetMembership(Low, minimumValue, minimumValue, 0, 0);
975  m_FvNDSIVis->SetMembership(Medium, 0, 0, 0.5, 0.5);
976  m_FvNDSIVis->SetMembership(High, 0.5, 0.5, maximumValue, maximumValue);
977 
978  m_FvNDBBBI ->SetMembership(Low, minimumValue, minimumValue, -0.20, -0.20);
979  m_FvNDBBBI->SetMembership(Medium, -0.20, -0.20, 0.10, 0.10);
980  m_FvNDBBBI->SetMembership(High, 0.10, 0.10, maximumValue, maximumValue);
981 
982  m_FvNDVI->SetMembership(Low, minimumValue, minimumValue, 0.35, 0.35);
983  m_FvNDVI->SetMembership(Medium, 0.35, 0.35, 0.6, 0.6);
984  m_FvNDVI->SetMembership(High, 0.6, 0.6, maximumValue, maximumValue);
985 
986  m_FvNDBSI->SetMembership(Low, minimumValue, minimumValue, -0.20, -0.20);
987  m_FvNDBSI->SetMembership(Medium, -0.20, -0.20, 0.0, 0.0);
988  m_FvNDBSI->SetMembership(High, 0.0, 0.0, maximumValue, maximumValue);
989  }
990  ~LinguisticVariables() override {}
991 
992  inline itk::FixedArray<unsigned int, 11> operator ()(const TInput& inputPixel)
993  {
994  TInput newPixel(this->PrepareValues( inputPixel ));
996 
997  result[ bright ] = m_FvBright->GetMaxVar(Bright<TInput, PrecisionType>()( newPixel ));
998  result[ vis ] = m_FvVis->GetMaxVar(Vis<TInput, PrecisionType>()( newPixel ));
999  result[ nir ] = m_FvNIR->GetMaxVar(NIR<TInput, PrecisionType>()( newPixel ));
1000  result[ mir1 ] = m_FvMIR1->GetMaxVar(MIR1<TInput, PrecisionType>()( newPixel ));
1001 
1003  mir2F.SetSAT( this->m_SAT );
1004  result[ mir2 ] = m_FvMIR2->GetMaxVar(mir2F( newPixel ));
1005 
1007  tirF.SetSAT( this->m_SAT );
1008  result[ tir ] = m_FvTIR->GetMaxVar(tirF( newPixel ));
1009 
1011  mirtirF.SetSAT( this->m_SAT );
1012  result[ mirtir ] = m_FvMIRTIR->GetMaxVar(mirtirF( newPixel ));
1013 
1014  result[ ndsivis ] = m_FvNDSIVis->GetMaxVar(NDSIVis<TInput, PrecisionType>()( newPixel ));
1015 
1016  result[ ndbbbi ] = m_FvNDBBBI->GetMaxVar(NDBBBI<TInput, PrecisionType>()( newPixel ));
1017 
1018  result[ ndvi ] = m_FvNDVI->GetMaxVar(NDVI<TInput, PrecisionType>()( newPixel ));
1019 
1020  result[ ndbsi ] = m_FvNDBSI->GetMaxVar(NDBSI<TInput, PrecisionType>()( newPixel ));
1021 
1022  return result;
1023  }
1024 
1025 protected:
1037 
1038 
1039 };
1040 
1041 
1059 template <class TInput, class TOutput>
1060 class KernelSpectralRule : public LandsatTMIndexBase<TInput, TOutput >
1061 {
1062 public:
1063 
1064  typedef typename TInput::ValueType PrecisionType;
1065  typedef bool OutputPixelType;
1066 
1068  virtual std::string GetName() const
1069  {
1070  return "LandsatTM KernelSpectralRule";
1071  }
1072 
1073  KernelSpectralRule() : m_TV1(0.7), m_TV2(0.5) { }
1074  ~KernelSpectralRule() override {}
1075 
1077  {
1078  this->m_TV1 = tv1;
1079  }
1080 
1082  {
1083  this->m_TV2 = tv2;
1084  }
1085 
1087  {
1088  return this->m_TV1;
1089  }
1090 
1092  {
1093  return this->m_TV2;
1094  }
1095 
1096 protected:
1099 
1102 
1103  void SetMinMax(const TInput& inputPixel, PrecisionType* max13, PrecisionType* min123, PrecisionType* max123, PrecisionType* min12347, PrecisionType* max12347, PrecisionType* max234, PrecisionType* max45)
1104  {
1105  std::vector< PrecisionType > v13;
1106  v13.push_back(inputPixel[this->m_TM1]);
1107  v13.push_back(inputPixel[this->m_TM3]);
1108 
1109  *max13 = *(std::max_element ( v13.begin(), v13.end() ));
1110 
1111 
1112  std::vector< PrecisionType > v123;
1113  v123.push_back(inputPixel[this->m_TM1]);
1114  v123.push_back(inputPixel[this->m_TM2]);
1115  v123.push_back(inputPixel[this->m_TM3]);
1116 
1117  *max123 = *(std::max_element ( v123.begin(), v123.end() ));
1118  *min123 = *(std::min_element ( v123.begin(), v123.end() ));
1119 
1120 
1121  std::vector< PrecisionType > v12347;
1122  v12347.push_back(inputPixel[this->m_TM1]);
1123  v12347.push_back(inputPixel[this->m_TM2]);
1124  v12347.push_back(inputPixel[this->m_TM3]);
1125  v12347.push_back(inputPixel[this->m_TM4]);
1126  v12347.push_back(inputPixel[this->m_TM7]);
1127 
1128  *max12347 = *(std::max_element ( v12347.begin(), v12347.end() ));
1129  *min12347 = *(std::min_element ( v12347.begin(), v12347.end() ));
1130 
1131  std::vector< PrecisionType > v234;
1132  v234.push_back(inputPixel[this->m_TM2]);
1133  v234.push_back(inputPixel[this->m_TM3]);
1134  v234.push_back(inputPixel[this->m_TM4]);
1135 
1136  *max234 = *(std::max_element ( v234.begin(), v234.end() ));
1137 
1138  std::vector< PrecisionType > v45;
1139  v45.push_back(inputPixel[this->m_TM4]);
1140  v45.push_back(inputPixel[this->m_TM5]);
1141 
1142  *max45 = *(std::max_element ( v45.begin(), v45.end() ));
1143  }
1144 };
1145 
1161 template <class TInput, class TOutput>
1162 class ThickCloudsSpectralRule : public KernelSpectralRule<TInput, TOutput>
1163 {
1164 public:
1165 
1166  typedef typename TInput::ValueType PrecisionType;
1167  typedef bool OutputPixelType;
1168 
1170  std::string GetName() const override
1171  {
1172  return "LandsatTM ThickCloudsSpectralRule";
1173  }
1174 
1177 
1178  inline TOutput operator ()(const TInput& inputPixel)
1179  {
1180  TInput newPixel(this->PrepareValues( inputPixel ));
1181  PrecisionType max13;
1182  PrecisionType max123;
1183  PrecisionType min123;
1184  PrecisionType max12347;
1185  PrecisionType min12347;
1186  PrecisionType max234;
1187  PrecisionType max45;
1188  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1189 
1190  bool result = (
1191  ((min123 >= (this->m_TV1 * max123)
1192  && (max123 <= this->m_TV1 * newPixel[this->m_TM4]))
1193  || ((newPixel[this->m_TM2] >= this->m_TV1 * max13)
1194  && (max123 <= newPixel[this->m_TM4])))
1195  && (newPixel[this->m_TM5] <= this->m_TV1 * newPixel[this->m_TM4])
1196  && (newPixel[this->m_TM5] >= this->m_TV1 * max123)
1197  && (newPixel[this->m_TM7] <= this->m_TV1 * newPixel[this->m_TM4]));
1198 
1199  return static_cast<TOutput>(result);
1200  }
1201 
1202 };
1203 
1219 template <class TInput, class TOutput>
1220 class ThinCloudsSpectralRule : public KernelSpectralRule<TInput, TOutput>
1221 {
1222 public:
1223 
1224  typedef typename TInput::ValueType PrecisionType;
1225  typedef bool OutputPixelType;
1226 
1228  std::string GetName() const override
1229  {
1230  return "LandsatTM ThinCloudsSpectralRule";
1231  }
1232 
1235 
1236  inline TOutput operator ()(const TInput& inputPixel)
1237  {
1238  TInput newPixel(this->PrepareValues( inputPixel ));
1239  PrecisionType max13;
1240  PrecisionType max123;
1241  PrecisionType min123;
1242  PrecisionType max12347;
1243  PrecisionType min12347;
1244  PrecisionType max234;
1245  PrecisionType max45;
1246  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1247 
1248 
1249  bool result = (min123 >= (this->m_TV1 * max123))
1250  && (newPixel[this->m_TM4] >= max123)
1251  && !((newPixel[this->m_TM1] <= newPixel[this->m_TM2]
1252  && newPixel[this->m_TM2] <= newPixel[this->m_TM3]
1253  && newPixel[this->m_TM3] <= newPixel[this->m_TM4])
1254  && (newPixel[this->m_TM3] >= this->m_TV1 * newPixel[this->m_TM4]))
1255  && (newPixel[this->m_TM4] >= this->m_TV1 * newPixel[this->m_TM5])
1256  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4])
1257  && (newPixel[this->m_TM5] >= this->m_TV1 * max123)
1258  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM7]);
1259 
1260  return static_cast<TOutput>(result);
1261  }
1262 
1263 };
1264 
1280 template <class TInput, class TOutput>
1281 class SnowOrIceSpectralRule : public KernelSpectralRule<TInput, TOutput>
1282 {
1283 public:
1284 
1285  typedef typename TInput::ValueType PrecisionType;
1286  typedef bool OutputPixelType;
1287 
1289  std::string GetName() const override
1290  {
1291  return "LandsatTM SnowOrIceSpectralRule";
1292  }
1293 
1296 
1297  inline TOutput operator ()(const TInput& inputPixel)
1298  {
1299  TInput newPixel(this->PrepareValues( inputPixel ));
1300  PrecisionType max13;
1301  PrecisionType max123;
1302  PrecisionType min123;
1303  PrecisionType max12347;
1304  PrecisionType min12347;
1305  PrecisionType max234;
1306  PrecisionType max45;
1307  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1308 
1309 
1310  bool result = (min123 >= (this->m_TV1 * max123))
1311  && (newPixel[this->m_TM4] >= (this->m_TV1 * max123))
1312  && (newPixel[this->m_TM5] <= this->m_TV2 * newPixel[this->m_TM4])
1313  && (newPixel[this->m_TM5] <= this->m_TV1 * min123)
1314  && (newPixel[this->m_TM5] <= this->m_TV1 * max123)
1315  && (newPixel[this->m_TM7] <= this->m_TV2 * newPixel[this->m_TM4])
1316  && (newPixel[this->m_TM7] <= this->m_TV1 * min123);
1317 
1318  return static_cast<TOutput>(result);
1319  }
1320 
1321 };
1322 
1323 
1339 template <class TInput, class TOutput>
1340 class WaterOrShadowSpectralRule : public KernelSpectralRule<TInput, TOutput>
1341 {
1342 public:
1343 
1344  typedef typename TInput::ValueType PrecisionType;
1345  typedef bool OutputPixelType;
1346 
1348  std::string GetName() const override
1349  {
1350  return "LandsatTM WaterOrShadowSpectralRule";
1351  }
1352 
1355 
1356  inline TOutput operator ()(const TInput& inputPixel)
1357  {
1358  TInput newPixel(this->PrepareValues( inputPixel ));
1359  bool result = (newPixel[this->m_TM1] >= newPixel[this->m_TM2])
1360  && (newPixel[this->m_TM2] >= newPixel[this->m_TM3])
1361  && (newPixel[this->m_TM3] >= newPixel[this->m_TM4])
1362  && (newPixel[this->m_TM4] >= newPixel[this->m_TM5])
1363  && (newPixel[this->m_TM4] >= newPixel[this->m_TM7]);
1364 
1365  return static_cast<TOutput>(result);
1366  }
1367 
1368 };
1369 
1370 
1386 template <class TInput, class TOutput>
1388 {
1389 public:
1390 
1391  typedef typename TInput::ValueType PrecisionType;
1392  typedef bool OutputPixelType;
1393 
1395  std::string GetName() const override
1396  {
1397  return "LandsatTM PitbogOrGreenhouseSpectralRule";
1398  }
1399 
1402 
1403  inline TOutput operator ()(const TInput& inputPixel)
1404  {
1405  TInput newPixel(this->PrepareValues( inputPixel ));
1406  PrecisionType max13;
1407  PrecisionType max123;
1408  PrecisionType min123;
1409  PrecisionType max12347;
1410  PrecisionType min12347;
1411  PrecisionType max234;
1412  PrecisionType max45;
1413  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1414 
1415 
1416  bool result = (newPixel[this->m_TM3] >= this->m_TV1 * newPixel[this->m_TM1])
1417  && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM3])
1418  && (max123 <= this->m_TV1 * newPixel[this->m_TM4])
1419  && (newPixel[this->m_TM5] <= this->m_TV1 * newPixel[this->m_TM4])
1420  && (newPixel[this->m_TM3] >= this->m_TV2 * newPixel[this->m_TM5])
1421  && (min123 >= this->m_TV1 * newPixel[this->m_TM7]);
1422 
1423 
1424  return static_cast<TOutput>(result);
1425  }
1426 
1427 };
1428 
1444 template <class TInput, class TOutput>
1445 class DominantBlueSpectralRule : public KernelSpectralRule<TInput, TOutput>
1446 {
1447 public:
1448 
1449  typedef typename TInput::ValueType PrecisionType;
1450  typedef bool OutputPixelType;
1451 
1453  std::string GetName() const override
1454  {
1455  return "LandsatTM DominantBlueSpectralRule";
1456  }
1457 
1460 
1461  inline TOutput operator ()(const TInput& inputPixel)
1462  {
1463  TInput newPixel(this->PrepareValues( inputPixel ));
1464  bool result = (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM2])
1465  && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM3])
1466  && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM4])
1467  && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM5])
1468  && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM7]);
1469 
1470 
1471  return static_cast<TOutput>(result);
1472  }
1473 
1474 };
1475 
1476 
1492 template <class TInput, class TOutput>
1493 class VegetationSpectralRule : public KernelSpectralRule<TInput, TOutput>
1494 {
1495 public:
1496 
1497  typedef typename TInput::ValueType PrecisionType;
1498  typedef bool OutputPixelType;
1499 
1501  std::string GetName() const override
1502  {
1503  return "LandsatTM VegetationSpectralRule";
1504  }
1505 
1508 
1509  inline TOutput operator ()(const TInput& inputPixel)
1510  {
1511  TInput newPixel(this->PrepareValues( inputPixel ));
1512  PrecisionType max13;
1513  PrecisionType max123;
1514  PrecisionType min123;
1515  PrecisionType max12347;
1516  PrecisionType min12347;
1517  PrecisionType max234;
1518  PrecisionType max45;
1519  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1520 
1521 
1522  bool result = (newPixel[this->m_TM2] >= this->m_TV2 * newPixel[this->m_TM1])
1523  && (newPixel[this->m_TM2] >= this->m_TV1 * newPixel[this->m_TM3])
1524  && (newPixel[this->m_TM3] < this->m_TV1 * newPixel[this->m_TM4])
1525  && (newPixel[this->m_TM4] > max123)
1526  && (newPixel[this->m_TM5] < this->m_TV1 * newPixel[this->m_TM4])
1527  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM3])
1528  && (newPixel[this->m_TM7] < this->m_TV1 * newPixel[this->m_TM5]);
1529 
1530 
1531  return static_cast<TOutput>(result);
1532  }
1533 
1534 };
1535 
1536 
1552 template <class TInput, class TOutput>
1553 class RangelandSpectralRule : public KernelSpectralRule<TInput, TOutput>
1554 {
1555 public:
1556 
1557  typedef typename TInput::ValueType PrecisionType;
1558  typedef bool OutputPixelType;
1559 
1561  std::string GetName() const override
1562  {
1563  return "LandsatTM RangelandSpectralRule";
1564  }
1565 
1568 
1569  inline TOutput operator ()(const TInput& inputPixel)
1570  {
1571  TInput newPixel(this->PrepareValues( inputPixel ));
1572  PrecisionType max13;
1573  PrecisionType max123;
1574  PrecisionType min123;
1575  PrecisionType max12347;
1576  PrecisionType min12347;
1577  PrecisionType max234;
1578  PrecisionType max45;
1579  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1580 
1581 
1582  bool result = (newPixel[this->m_TM2] >= this->m_TV2 * newPixel[this->m_TM1])
1583  && (newPixel[this->m_TM2] >= this->m_TV1 * newPixel[this->m_TM3])
1584  && (newPixel[this->m_TM4] > max123)
1585  && (newPixel[this->m_TM3] < this->m_TV1 * newPixel[this->m_TM4])
1586  && (newPixel[this->m_TM4] >= this->m_TV1 * newPixel[this->m_TM5])
1587  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4])
1588  && (newPixel[this->m_TM5] > max123)
1589  && (newPixel[this->m_TM7] < this->m_TV1 * max45)
1590  && (newPixel[this->m_TM5] >= newPixel[this->m_TM7]);
1591 
1592 
1593  return static_cast<TOutput>(result);
1594  }
1595 
1596 };
1597 
1613 template <class TInput, class TOutput>
1615 {
1616 public:
1617 
1618  typedef typename TInput::ValueType PrecisionType;
1619  typedef bool OutputPixelType;
1620 
1622  std::string GetName() const override
1623  {
1624  return "LandsatTM BarrenLandOrBuiltUpOrCloudsSpectralRule";
1625  }
1626 
1629 
1630  inline TOutput operator ()(const TInput& inputPixel)
1631  {
1632  TInput newPixel(this->PrepareValues( inputPixel ));
1633  PrecisionType max13;
1634  PrecisionType max123;
1635  PrecisionType min123;
1636  PrecisionType max12347;
1637  PrecisionType min12347;
1638  PrecisionType max234;
1639  PrecisionType max45;
1640  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1641 
1642 
1643  bool result = (newPixel[this->m_TM3] >= this->m_TV2 * newPixel[this->m_TM1])
1644  && (newPixel[this->m_TM3] >= this->m_TV1 * newPixel[this->m_TM2])
1645  && (newPixel[this->m_TM4] >= this->m_TV1 * max123)
1646  && (newPixel[this->m_TM5] >= max123)
1647  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4])
1648  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM7])
1649  && (newPixel[this->m_TM7] >= this->m_TV2 * max45);
1650 
1651  return static_cast<TOutput>(result);
1652  }
1653 
1654 };
1655 
1671 template <class TInput, class TOutput>
1673 {
1674 public:
1675 
1676  typedef typename TInput::ValueType PrecisionType;
1677  typedef bool OutputPixelType;
1678 
1680  std::string GetName() const override
1681  {
1682  return "LandsatTM FlatResponseBarrenLandOrBuiltUpSpectralRule";
1683  }
1684 
1687 
1688  inline TOutput operator ()(const TInput& inputPixel)
1689  {
1690  TInput newPixel(this->PrepareValues( inputPixel ));
1691  PrecisionType max13;
1692  PrecisionType max123;
1693  PrecisionType min123;
1694  PrecisionType max12347;
1695  PrecisionType min12347;
1696  PrecisionType max234;
1697  PrecisionType max45;
1698  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1699 
1700 
1701  bool result = (newPixel[this->m_TM5] >= this->m_TV1 * max12347)
1702  && (min12347 >= this->m_TV2 * newPixel[this->m_TM5]);
1703 
1704  return static_cast<TOutput>(result);
1705  }
1706 
1707 };
1708 
1709 
1725 template <class TInput, class TOutput>
1727 {
1728 public:
1729 
1730  typedef typename TInput::ValueType PrecisionType;
1731  typedef bool OutputPixelType;
1732 
1734  std::string GetName() const override
1735  {
1736  return "LandsatTM ShadowWithBarrenLandSpectralRule";
1737  }
1738 
1741 
1742  inline TOutput operator ()(const TInput& inputPixel)
1743  {
1744  TInput newPixel(this->PrepareValues( inputPixel ));
1745  bool result = (newPixel[this->m_TM1] >= newPixel[this->m_TM2])
1746  && (newPixel[this->m_TM2] >= newPixel[this->m_TM3])
1747  && (newPixel[this->m_TM3] >= this->m_TV1 * newPixel[this->m_TM4])
1748  && (newPixel[this->m_TM1] >= newPixel[this->m_TM5])
1749  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4])
1750  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM7]);
1751 
1752  return static_cast<TOutput>(result);
1753  }
1754 };
1755 
1756 
1772 template <class TInput, class TOutput>
1774 {
1775 public:
1776 
1777  typedef typename TInput::ValueType PrecisionType;
1778  typedef bool OutputPixelType;
1779 
1781  std::string GetName() const override
1782  {
1783  return "LandsatTM ShadowWithVegetationSpectralRule";
1784  }
1785 
1788 
1789  inline TOutput operator ()(const TInput& inputPixel)
1790  {
1791  TInput newPixel(this->PrepareValues( inputPixel ));
1792  bool result = (newPixel[this->m_TM1] >= newPixel[this->m_TM2])
1793  && (newPixel[this->m_TM2] >= newPixel[this->m_TM3])
1794  && (newPixel[this->m_TM1] >= this->m_TV2 * newPixel[this->m_TM4])
1795  && (newPixel[this->m_TM3] < this->m_TV1 * newPixel[this->m_TM4])
1796  && (newPixel[this->m_TM5] < this->m_TV1 * newPixel[this->m_TM4])
1797  && (newPixel[this->m_TM3] >= this->m_TV2 * newPixel[this->m_TM5])
1798  && (newPixel[this->m_TM7] < this->m_TV1 * newPixel[this->m_TM4]);
1799 
1800  return static_cast<TOutput>(result);
1801  }
1802 };
1803 
1804 
1820 template <class TInput, class TOutput>
1821 class ShadowCloudOrSnowSpectralRule : public KernelSpectralRule<TInput, TOutput>
1822 {
1823 public:
1824 
1825  typedef typename TInput::ValueType PrecisionType;
1826  typedef bool OutputPixelType;
1827 
1829  std::string GetName() const override
1830  {
1831  return "LandsatTM ShadowCloudOrSnowSpectralRule";
1832  }
1833 
1836 
1837  inline TOutput operator ()(const TInput& inputPixel)
1838  {
1839  TInput newPixel(this->PrepareValues( inputPixel ));
1840  PrecisionType max13;
1841  PrecisionType max123;
1842  PrecisionType min123;
1843  PrecisionType max12347;
1844  PrecisionType min12347;
1845  PrecisionType max234;
1846  PrecisionType max45;
1847  this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);
1848 
1849 
1850  bool result = (newPixel[this->m_TM1] >= this->m_TV1 * max234)
1851  && (max234 >= this->m_TV1 * newPixel[this->m_TM1])
1852  && (newPixel[this->m_TM5] < newPixel[this->m_TM1])
1853  && (newPixel[this->m_TM7] < this->m_TV1 * newPixel[this->m_TM1]);
1854 
1855  return static_cast<TOutput>(result);
1856  }
1857 };
1858 
1859 
1875 template <class TInput, class TOutput>
1876 class WetlandSpectralRule : public KernelSpectralRule<TInput, TOutput>
1877 {
1878 public:
1879 
1880  typedef typename TInput::ValueType PrecisionType;
1881  typedef bool OutputPixelType;
1882 
1884  std::string GetName() const override
1885  {
1886  return "LandsatTM WetlandSpectralRule";
1887  }
1888 
1890  ~WetlandSpectralRule() override {}
1891 
1892  inline TOutput operator ()(const TInput& inputPixel)
1893  {
1894  TInput newPixel(this->PrepareValues( inputPixel ));
1895  bool result = (newPixel[this->m_TM1] >= newPixel[this->m_TM2])
1896  && (newPixel[this->m_TM2] >= newPixel[this->m_TM3])
1897  && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM4])
1898  && (newPixel[this->m_TM3] < newPixel[this->m_TM4])
1899  && (newPixel[this->m_TM4] >= this->m_TV1 * newPixel[this->m_TM5])
1900  && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4])
1901  && (newPixel[this->m_TM3] >= this->m_TV2 * newPixel[this->m_TM5])
1902  && (newPixel[this->m_TM5] >= newPixel[this->m_TM7]);
1903 
1904  return static_cast<TOutput>(result);
1905  }
1906 };
1907 
1908 
1909 } // namespace LandsatTM
1910 } // namespace Functor
1911 } // namespace otb
1912 
1913 #endif
TOutput operator()(const TInput &inputPixel)
TOutput operator()(const TInput &inputPixel)
std::string GetName() const override
std::string GetName() const override
std::string GetName() const override
TOutput operator()(const TInput &inputPixel)
itk::FixedArray< unsigned int, 11 > operator()(const TInput &inputPixel)
void SetIndex(BandName::LandsatTMBandNames band, unsigned int channel)
TOutput operator()(const TInput &inputPixel)
TOutput operator()(const TInput &inputPixel)
std::string GetName() const override
DegreeType
Thermal band in Kelvin or Celsius.
TOutput operator()(const TInput &inputPixel)
TOutput operator()(const TInput &inputPixel)
otb::FuzzyVariable< unsigned short, PrecisionType > FuzzyVarType
std::string GetName() const override
TOutput operator()(const TInput &inputPixel)
TOutput operator()(const TInput &inputPixel)
std::string GetName() const override
TInput PrepareValues(const TInput &inputPixel)
Prepare the values so they are normalized and in C.
TOutput operator()(const TInput &inputPixel) const
bool operator==(const LandsatTMIndexBase &other) const
itk::FixedArray< unsigned int, 11 > OutputPixelType
ReflectanceType
Reflectances in thousands or in (0-1)
static ITK_CONSTEXPR_FUNC T max(const T &)
unsigned int GetIndex(BandName::LandsatTMBandNames band) const
TOutput operator()(const TInput &inputPixel)
std::string GetName() const override
TOutput operator()(const TInput &inputPixel)
bool operator!=(const LandsatTMIndexBase &) const
TOutput operator()(const TInput &inputPixel)
TOutput operator()(const TInput &inputPixel)
virtual std::string GetName() const =0
static ITK_CONSTEXPR_FUNC T NonpositiveMin()
std::string GetName() const override
TOutput operator()(const TInput &inputPixel)
std::string GetName() const override
std::string GetName() const override
static Pointer New()
Base class for Landsat-TM indices.
void SetMinMax(const TInput &inputPixel, PrecisionType *max13, PrecisionType *min123, PrecisionType *max123, PrecisionType *min12347, PrecisionType *max12347, PrecisionType *max234, PrecisionType *max45)
std::string GetName() const override
Class to represent a fuzzy N-valued variable.
std::string GetName() const override
TOutput operator()(const TInput &inputPixel)
TOutput operator()(const TInput &inputPixel)
std::string GetName() const override