OTB  6.7.0
Orfeo Toolbox
otbLandsatTMSpectralRuleBasedClassifier.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 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 otbLandsatTMSRBC_h
22 #define otbLandsatTMSRBC_h
23 
24 #include "otbLandsatTMIndices.h"
25 #include <string>
26 
27 namespace otb
28 {
29 
30 namespace Functor
31 {
32 
33 namespace LandsatTM
34 {
35 
62 template <class TInput, class TOutput>
63 class SpectralRuleBasedClassifier : public KernelSpectralRule<TInput, TOutput>
64 {
65 public:
66  // Spectral categories
68  NOCLASS, // 0 -if the pixel is not classified; just for error
69  // checking; different from SU, which is a real rejection
70  // class
71  TKCL, // 1 -thick clouds
72  TNCL, // 2 -thin clouds; possible confusions with cold light toned
73  // (highly reflective) barren land and range land
74  SN, // 3 -snow
75  ICSN, // 4 -ice or snow
76  DPWASH, // 5 -deep clear water and shadow areas; possible confusions
77  // with lava rocks
78  SLWASH, // 6 -shallow clear water and shadow areas
79  PBHNDVI, // 7 -pit bog with high NDVI
80  PBMNDVI, // 8 -pit bog with medium NDVI
81  PBLNDVI, // 9 -pit bog with low NDVI; possible confusions with
82  // greenhouses
83  SVHNIR, // 10 - strong vegetation with high NIR; includes broadleaved
84  // decideous forests, vegetated cropland and pastures;
85  // possible confusions with mixed forests
86  SVLNIR, // 11 -strong vegetation with low NIR; includes evergreen
87  // forests and mixed forests; possible confusions with
88  // forest land in shadow areas
89  AVHNIR, // 12 -average vegetation with high NIR; includes cropland and
90  // pastures; possible confusions with evergreen forests
91  // and mixed forests
92  AVLNIR, // 13 -average vegetation with low NIR; includes evergreen
93  // forests, especially coniferous; possible confusions
94  // with forest land in shadow areas
95  WVHNIR, // 14 -weak vegetation with high NIR; includes scarcely
96  // vegetated areas
97  WVLNIR, // 15 -weak vegetation with low NIR; includes forested wetland
98  SSRHNIR, // 16 -strong shrub rangeland with high NIR; includes
99  // herbaceous rangeland; possible confusions with shrub
100  // and brush rangeland
101  SSRLNIR, // 17 -strong shrub rangeland with low NIR; includes shrub
102  // and brush rangeland; possible confusions with
103  // herbaceous rangeland
104  ASRHNIR, // 18 -average shrub rangeland with high NIR; includes
105  // herbaceous rangeland; possible confusions with shrub
106  // and brush rangeland
107  ASRLNIR, // 19 -average shrub rangeland with low NIR; includes shrub
108  // and brush rangeland; possible confusions with
109  // herbaceous rangeland
110  SHR, // 20 - strong herbaceous rangeland; possible confusions with
111  // vegetated cropland ans pastures
112  AHR, // 21 -average herbaceous rangeland; includes herbaceous
113  // rangeland and barren land scarcely vegetated; possible
114  // confusions with vegetated cropland and pastures
115  DR, // 22 -dark rangeland; includes mixed rangeland eventually in
116  // shadow areas and non forested wetland; possible
117  // confusions with mixed urban or built up
118  BBBHTIRF, // 23 -bright barren land or built up with high TIR and flat
119  // spectral response; includes urban or built up and
120  // concrete roads
121  BBBHTIRNF, // 24 -bright barren land or built up with high TIR and non flat
122  // spectral response;
123  BBBLTIRF, // 25 -bright barren land or built up with low TIR and flat
124  // spectral response; includes urban or built up and
125  // concrete roads
126  BBBLTIRNF, // 26 -bright barren land or built up with low TIR and non flat
127  // spectral response;
128  SBBHTIRF, // 27 -strong barren land or built up with high TIR and flat
129  // spectral response; includes urban or built up and
130  // concrete roads
131  SBBHTIRNF, // 28 -strong barren land or built up with high TIR with non flat
132  // spectral response; includes ploughed fields, barren
133  // land -- including bare exposed rocks -- and beaches
134  SBBLTIRF, // 29 -strong barren land or built up with low TIR and flat
135  // spectral response; includes urban or built up and
136  // concrete roads
137  SBBLTIRNF, // 30 -strong barren land or built up with low TIR with non flat
138  // spectral response; includes ploughed fields, barren
139  // land -- including bare exposed rocks -- and beaches
140  ABBHTIRF, // 31 -average barren land or built up with high TIR and flat
141  // spectral response; includes urban or built up and
142  // concrete roads
143  ABBHTIRNF, // 32 -average barren land or built up with high TIR with non flat
144  // spectral response
145  ABBLTIRF, // 33 -average barren land or built up with low TIR and flat
146  // spectral response; includes urban or built up and
147  // concrete roads
148  ABBLTIRNF, // 34 -average barren land or built up with low TIR with non flat
149  // spectral response
150  DBBHTIRF, // 35 -dark barren land or built up with high TIR and flat
151  // spectral response; includes urban or built up land,
152  // in particular parking lots, concrete roads, asphalt
153  // roads, grey-brown tile roofs, tan composite shingle
154  // roofs; possible confusions with barren land on dark
155  // mountain slopes including burned areas and bare
156  // exposed rocks, especially dark-toned soil
157  DBBHTIRNF, // 36 -dark barren land or built up with high TIR and non
158  // flat spectral response; includes barren land, bare
159  // exposed rocks, especially dark-toned soil
160  DBBLTIRF, // 37 -dark barren land or built up with low TIR and flat
161  // spectral response; includes urban or built up land,
162  // in particular parking lots, concrete roads, asphalt
163  // roads, grey-brown tile roofs, tan composite shingle
164  // roofs; possible confusions with barren land on dark
165  // mountain slopes including burned areas and bare
166  // exposed rocks, especially dark-toned soil
167  DBBLTIRNF, // 38 -dark barren land or built up with low TIR and non
168  // flat spectral response; includes barren land, bare
169  // exposed rocks, especially dark-toned soil
170  WR, // 39 -weak rangeland; includes herbaceous rangeland
171  SHV, // 40 -shadow area with vegetation; possible confusions
172  // with non forested wetland
173  SHB, // 41 -shadow with barren land; includes also lava rock;
174  // possible confusions with built up areas, especially
175  // asphalt roads
176  SHCL, // 42 -clouds in shadow areas
177  TWASHSN, // 43 -snow in shadow areas
178  WE, // 44 -non forested wetland; possible confusions with
179  // shadow areas with vegetation
180  TWA, // 45 -turbid water; possible confusions with shadow areas
181  SU // 46 -shadow areas or unknown pixels
182  };
183  typedef typename TInput::ValueType PrecisionType;
184  typedef bool OutputPixelType;
185 
187  std::string GetName() const override
188  {
189  return "LandsatTM SpectralRuleBasedClassifier";
190  }
191 
194 
195  inline TOutput operator ()(const TInput& inputPixel)
196  {
197  // We normalize the pixel just once, so that the indices do not
198  // need to do it
199  TInput newPixel(this->PrepareValues( inputPixel ));
200 
201 
202  // Get the linguistic variables
203  typedef LinguisticVariables<TInput> LVType;
204  LVType lvf = LVType();
205  lvf.SetSAT( this->m_SAT );
206  typename LVType::OutputPixelType lv = lvf( newPixel );
207 
208 
209  typedef ThickCloudsSpectralRule<TInput, bool> TKCLSRType;
210  TKCLSRType tkclsrf = TKCLSRType();
211  tkclsrf.SetTV1( this->m_TV1 );
212  tkclsrf.SetTV2( this->m_TV2 );
213  tkclsrf.SetSAT( this->m_SAT );
214 
215  bool tkclsr = tkclsrf( newPixel );
216 
217  typedef ThinCloudsSpectralRule<TInput, bool> TNCLSRType;
218  TNCLSRType tnclsrf = TNCLSRType();
219  tnclsrf.SetTV1( this->m_TV1 );
220  tnclsrf.SetTV2( this->m_TV2 );
221  tnclsrf.SetSAT( this->m_SAT );
222 
223  bool tnclsr = tnclsrf( newPixel );
224 
225  bool lBright = (lv[ LVType::bright ] == LVType::Low);
226  bool lVis = (lv[ LVType::vis ] == LVType::Low);
227  bool lNIR = (lv[ LVType::nir ] == LVType::Low);
228  bool hNDSIVis = (lv[ LVType::ndsivis ] == LVType::High);
229  bool lMIR1 = (lv[ LVType::mir1 ] == LVType::Low);
230  bool lMIR2 = (lv[ LVType::mir2 ] == LVType::Low);
231  bool hTIR = (lv[ LVType::tir ] == LVType::High);
232  bool hMIRTIR = (lv[ LVType::mirtir ] == LVType::High);
233  bool mMIRTIR = (lv[ LVType::mirtir ] == LVType::Medium);
234  bool lMIRTIR = (lv[ LVType::mirtir ] == LVType::Low);
235 
236 
237  // cloud spectral category
238  bool clsc = (tkclsr || tnclsr) && !(lBright ||
239  lVis || lNIR ||
240  hNDSIVis ||
241  lMIR1 ||
242  lMIR2 || hTIR
243  || hMIRTIR);
244 
245  // thick cloud spectral category
246  if(clsc && lMIRTIR)
247  return static_cast<TOutput>(TKCL);
248 
249  // thin cloud spectral category
250  if(clsc && mMIRTIR)
251  return static_cast<TOutput>(TNCL);
252 
253 
254  typedef SnowOrIceSpectralRule<TInput, bool> SNICSRType;
255  SNICSRType snicsrf = SNICSRType();
256  snicsrf.SetTV1( this->m_TV1 );
257  snicsrf.SetTV2( this->m_TV2 );
258  snicsrf.SetSAT( this->m_SAT );
259 
260  bool snicsr = snicsrf( newPixel );
261 
262  bool lNDBSI = (lv[ LVType::ndbsi ] == LVType::Low);
263  bool lNDSIVis = (lv[ LVType::ndsivis ] == LVType::Low);
264  bool hMIR1 = (lv[ LVType::mir1 ] == LVType::High);
265  bool hMIR2 = (lv[ LVType::mir2 ] == LVType::High);
266 
267  // snow or ice spectral category
268  bool snicsc = (snicsr && lNDBSI && !(lBright ||
269  lVis || lNDSIVis || lNIR || hMIR1 || hMIR2 || hTIR ));
270 
271  // snow spectral category
272  if(snicsc && hNDSIVis)
273  return static_cast<TOutput>(SN);
274 
275  bool mNDSIVis = (lv[ LVType::ndsivis ] == LVType::Medium);
276  // ice or snow spectral category
277  if(snicsc && mNDSIVis)
278  return static_cast<TOutput>(ICSN);
279 
280 
281  typedef WaterOrShadowSpectralRule<TInput, bool> WASHSRType;
282  WASHSRType washsrf = WASHSRType();
283  washsrf.SetTV1( this->m_TV1 );
284  washsrf.SetTV2( this->m_TV2 );
285  washsrf.SetSAT( this->m_SAT );
286 
287  bool washsr = washsrf( newPixel );
288 
289 
290  bool lNDVI = (lv[ LVType::ndvi ] == LVType::Low);
291  bool lTIR = (lv[ LVType::tir ] == LVType::Low);
292  // water or shadow spectral category
293  bool washsc = washsr && lBright && lVis && lNDVI && lNIR && lMIR1 && lMIR2 && !(lTIR);
294 
295 
296  // deep water or shadow spectral category
297  if( washsc && hNDSIVis)
298  return static_cast<TOutput>(DPWASH);
299 
300  // shallow water or shadow spectral category
301  if( washsc && !(hNDSIVis))
302  return static_cast<TOutput>(SLWASH);
303 
304 
306  PBGHSRType pbghsrf = PBGHSRType();
307  pbghsrf.SetTV1( this->m_TV1 );
308  pbghsrf.SetTV2( this->m_TV2 );
309  pbghsrf.SetSAT( this->m_SAT );
310 
311  bool pbghsr = pbghsrf( newPixel );
312 
313  // Pit bog spectral category
314  bool pbsc = pbghsr && lMIR1 && lMIR2 && lNDBSI && !(lNIR);
315 
316  bool mNDVI = (lv[ LVType::ndvi ] == LVType::Medium);
317  bool hNDVI = (lv[ LVType::ndvi ] == LVType::High);
318  // Pit bog categories for each ndvi
319  if( pbsc && hNDVI)
320  return static_cast<TOutput>(PBHNDVI);
321  if( pbsc && mNDVI)
322  return static_cast<TOutput>(PBMNDVI);
323  if( pbsc && lNDVI)
324  return static_cast<TOutput>(PBLNDVI);
325 
326 
327  typedef VegetationSpectralRule<TInput, bool> VSRType;
328  VSRType vsrf = VSRType();
329  vsrf.SetTV1( this->m_TV1 );
330  vsrf.SetTV2( this->m_TV2 );
331  vsrf.SetSAT( this->m_SAT );
332 
333  bool vsr = vsrf( newPixel );
334 
335  bool hNDBSI = (lv[ LVType::ndbsi ] == LVType::High);
336  bool hNIR = (lv[ LVType::nir ] == LVType::High);
337 
338  // strong vegetation spectral category
339  bool svsc = vsr && hNDVI && !(hMIR1 || hMIR2 || hNDBSI);
340 
341  if( svsc && hNIR)
342  return static_cast<TOutput>(SVHNIR);
343  if( svsc && !(hNIR))
344  return static_cast<TOutput>(SVLNIR);
345 
347  SHVSRType shvsrf = SHVSRType();
348  shvsrf.SetTV1( this->m_TV1 );
349  shvsrf.SetTV2( this->m_TV2 );
350  shvsrf.SetSAT( this->m_SAT );
351 
352  bool shvsr = shvsrf( newPixel );
353 
354 
356  DBSRType dbsrf = DBSRType();
357  dbsrf.SetTV1( this->m_TV1 );
358  dbsrf.SetTV2( this->m_TV2 );
359  dbsrf.SetSAT( this->m_SAT );
360 
361  bool dbsr = dbsrf( newPixel );
362 
363  // average vegetation spectral category
364  bool avsc = (vsr || shvsr) && mNDVI && !(hMIR1 || hMIR2 || hNDBSI || dbsr);
365 
366  if( avsc && hNIR)
367  return static_cast<TOutput>(AVHNIR);
368  if( avsc && !(hNIR))
369  return static_cast<TOutput>(AVLNIR);
370 
371  typedef RangelandSpectralRule<TInput, bool> RSRType;
372  RSRType rsrf = RSRType();
373  rsrf.SetTV1( this->m_TV1 );
374  rsrf.SetTV2( this->m_TV2 );
375  rsrf.SetSAT( this->m_SAT );
376 
377  bool rsr = rsrf( newPixel );
378 
379  // weak vegetation spectral category
380  bool wvsc = (vsr || rsr || shvsr) && lNDVI && lNDBSI && lMIR1 && lMIR2 && !(dbsr);
381 
382  if( wvsc && hNIR)
383  return static_cast<TOutput>(WVHNIR);
384  if( wvsc && !(hNIR))
385  return static_cast<TOutput>(WVLNIR);
386 
387  bool mNDBSI = (lv[ LVType::ndbsi ] == LVType::Medium);
388  // strong shrub rangeland spectral category
389  bool ssrsc = rsr && hNDVI && mNDBSI;
390  if( ssrsc && hNIR)
391  return static_cast<TOutput>(SSRHNIR);
392  if( ssrsc && !(hNIR))
393  return static_cast<TOutput>(SSRLNIR);
394 
395  typedef WetlandSpectralRule<TInput, bool> WESRType;
396  WESRType wesrf = WESRType();
397  wesrf.SetTV1( this->m_TV1 );
398  wesrf.SetTV2( this->m_TV2 );
399  wesrf.SetSAT( this->m_SAT );
400 
401  bool wesr = wesrf( newPixel );
402 
403  // average shrub rangeland spectral category
404  bool asrsc = rsr && mNDVI && mNDBSI && !(shvsr || wesr);
405  if( asrsc && hNIR)
406  return static_cast<TOutput>(ASRHNIR);
407  if( asrsc && !(hNIR))
408  return static_cast<TOutput>(ASRLNIR);
409 
410 
411  // strong herbaceous rangeland spectral category
412  bool shrsc = rsr && hNDVI && hNDBSI;
413  if( shrsc )
414  return static_cast<TOutput>(SHR);
415 
417  BBCSRType bbcsrf = BBCSRType();
418  bbcsrf.SetTV1( this->m_TV1 );
419  bbcsrf.SetTV2( this->m_TV2 );
420  bbcsrf.SetSAT( this->m_SAT );
421 
422  bool bbcsr = bbcsrf( newPixel );
423  // average herbaceous rangeland spectral category
424  bool ahrsc = (rsr || bbcsr) && mNDVI && hNDBSI;
425  if( ahrsc )
426  return static_cast<TOutput>(AHR);
427 
428  // dark rangeland spectral category
429  bool drsc = (vsr || rsr) && lNDVI && lMIR2 && !(hNIR || hMIR1 || lNDBSI);
430  if( drsc )
431  return static_cast<TOutput>(DR);
432 
433  // bright barren land or built up spectral category
434  bool bbbsc = bbcsr && hNIR && lNDVI && hNDBSI && !(lMIR1 || lMIR2);
435 
436  bool lNDBBBI = (lv[ LVType::ndbbbi ] == LVType::Low);
437 
438  bool bbbhtirsc = bbbsc && hTIR;
439 
440  if( bbbhtirsc && !(lNDBBBI) )
441  return static_cast<TOutput>(BBBHTIRF);
442  if( bbbhtirsc && lNDBBBI )
443  return static_cast<TOutput>(BBBHTIRNF);
444 
445  bool bbbltirsc = bbbsc && !(hTIR);
446  if( bbbltirsc && !(lNDBBBI) )
447  return static_cast<TOutput>(BBBLTIRF);
448  if( bbbltirsc && lNDBBBI )
449  return static_cast<TOutput>(BBBLTIRNF);
450 
452  FBBSRType fbbsrf = FBBSRType();
453  fbbsrf.SetTV1( this->m_TV1 );
454  fbbsrf.SetTV2( this->m_TV2 );
455  fbbsrf.SetSAT( this->m_SAT );
456 
457  bool fbbsr = fbbsrf( newPixel );
458  // strong barren land or built up spectral category
459  bool sbbsc = (bbcsr || fbbsr) && lNDVI && hNDBSI && !( hNIR || lMIR1);
460 
461  bool sbbhtirsc = sbbsc && hTIR;
462 
463  if( sbbhtirsc && (dbsr || fbbsr) )
464  return static_cast<TOutput>(SBBHTIRF);
465  if( sbbhtirsc && !(dbsr || fbbsr) )
466  return static_cast<TOutput>(SBBHTIRNF);
467 
468  bool sbbltirsc = sbbsc && !(hTIR);
469  if( sbbltirsc && (dbsr || fbbsr) )
470  return static_cast<TOutput>(SBBLTIRF);
471  if( sbbltirsc && !((dbsr || fbbsr)) )
472  return static_cast<TOutput>(SBBLTIRNF);
473 
474  // average barren land or built up spectral category
475  bool abbsc = (bbcsr || fbbsr) && lNDVI && mNDBSI && !(lMIR1);
476 
477  bool abbhtirsc = abbsc && hTIR;
478 
479  if( abbhtirsc && !(lNDBBBI) )
480  return static_cast<TOutput>(ABBHTIRF);
481  if( abbhtirsc && lNDBBBI )
482  return static_cast<TOutput>(ABBHTIRNF);
483 
484  bool abbltirsc = abbsc && !(hTIR);
485  if( abbltirsc && !(lNDBBBI) )
486  return static_cast<TOutput>(ABBLTIRF);
487  if( abbltirsc && lNDBBBI )
488  return static_cast<TOutput>(ABBLTIRNF);
489 
490  // dark barren land or built
491  bool dbbsc = (bbcsr || fbbsr) && lNDVI && lMIR1 && !( hNIR || hMIR2 || lNDBSI);
492 
493  bool dbbhtirsc = dbbsc && hTIR;
494 
495  if( dbbhtirsc && (dbsr || fbbsr) )
496  return static_cast<TOutput>(DBBHTIRF);
497  if( dbbhtirsc && !(dbsr || fbbsr) )
498  return static_cast<TOutput>(DBBHTIRNF);
499 
500  bool dbbltirsc = dbbsc && !(hTIR);
501  if( dbbltirsc && (dbsr || fbbsr) )
502  return static_cast<TOutput>(DBBLTIRF);
503  if( dbbltirsc && !((dbsr || fbbsr)) )
504  return static_cast<TOutput>(DBBLTIRNF);
505 
506  // weak rangeland spectral category
507  bool wrsc = rsr && lNDVI && !(lNDBSI);
508  if( wrsc )
509  return static_cast<TOutput>(WR);
510 
511  // shadow area with vegetation spectral category
512  bool shvsc = dbsr && shvsr && lBright && lVis && lNIR && lMIR1 && lMIR2 && !(hNDVI);
513  if( shvsc )
514  return static_cast<TOutput>(SHV);
515 
517  SHBSRType shbsrf = SHBSRType();
518  shbsrf.SetTV1( this->m_TV1 );
519  shbsrf.SetTV2( this->m_TV2 );
520  shbsrf.SetSAT( this->m_SAT );
521 
522  bool shbsr = shbsrf( newPixel );
523  // shadow with barren land spectral category
524  bool shbsc = dbsr && shbsr && lBright && lVis && lNDVI && lNIR && lMIR1 && lMIR2;
525  if( shbsc )
526  return static_cast<TOutput>(SHB);
527 
528  typedef ShadowCloudOrSnowSpectralRule<TInput, bool> SHCLSNSRType;
529  SHCLSNSRType shclsnsrf = SHCLSNSRType();
530  shclsnsrf.SetTV1( this->m_TV1 );
531  shclsnsrf.SetTV2( this->m_TV2 );
532  shclsnsrf.SetSAT( this->m_SAT );
533 
534  bool shclsnsr = shclsnsrf( newPixel );
535  // clouds in shadow areas spectral category
536  bool shclsc = dbsr && shclsnsr && !(hNDSIVis || lNIR || lBright || lVis || hNDBSI || hTIR);
537  if( shclsc )
538  return static_cast<TOutput>(SHCL);
539 
540  bool hBright = (lv[ LVType::bright ] == LVType::High);
541  bool hVis = (lv[ LVType::vis ] == LVType::High);
542  // turbid water or shadow snow spectral category
543  bool twashsnsc = dbsr && shclsnsr && hNDSIVis && lNIR && lMIR1 && lMIR2 && !(hBright || hVis || hNDBSI || hTIR);
544  if( twashsnsc )
545  return static_cast<TOutput>(TWASHSN);
546 
547  // non forested wetland spectral category
548  bool wesc = dbsr && wesr && lBright && lVis && lNIR && lMIR1 && lMIR2 && !(hNDVI || hNDBSI || lNDSIVis);
549  if( wesc )
550  return static_cast<TOutput>(WE);
551 
552  // turbid water spectral category
553  bool twasc = dbsr && lNDVI && lMIR1 && lMIR2 && !(hBright || hVis || hNIR || lNDSIVis);
554  if( twasc )
555  return static_cast<TOutput>(TWA);
556 
557  return static_cast<TOutput>(SU);
558 
559  }
560 };
561 
562 
563 } // namespace LandsatTM
564 } // namespace Functor
565 } // namespace otb
566 
567 #endif
Implementation of the SpectralRuleBasedClassifier for Landsat TM image land cover classification as d...
TInput PrepareValues(const TInput &inputPixel)
Prepare the values so they are normalized and in C.