OTB  6.7.0
Orfeo Toolbox
otbRadianceToReflectanceImageFilter.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
4  *
5  * This file is part of Orfeo Toolbox
6  *
7  * https://www.orfeo-toolbox.org/
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifndef otbRadianceToReflectanceImageFilter_h
23 #define otbRadianceToReflectanceImageFilter_h
24 
25 #include "otbVarSol.h"
27 #include "otbMacro.h"
29 #include <iomanip>
30 
31 namespace otb
32 {
33 namespace Functor
34 {
51 template <class TInput, class TOutput>
53 {
54 public:
58  m_UseClamp(true)
59  {}
60 
62 
63  void SetSolarIllumination(double solarIllumination)
64  {
65  m_SolarIllumination = solarIllumination;
66  }
68  {
70  }
71  void SetUseClamp(bool useClamp)
72  {
73  m_UseClamp = useClamp;
74  }
75 
77  {
78  return m_SolarIllumination;
79  }
81  {
83  }
84  bool GetUseClamp()
85  {
86  return m_UseClamp;
87  }
88 
89  inline TOutput operator ()(const TInput& inPixel) const
90  {
91  TOutput outPixel;
92  double temp;
93  temp = static_cast<double>(inPixel)
94  * static_cast<double>(CONST_PI)
97 
98  if (m_UseClamp)
99  {
100  temp = std::max(temp,0.);
101  temp = std::min(temp,1.);
102  }
103  outPixel = static_cast<TOutput>(temp);
104 
105  return outPixel;
106  }
107 
108 private:
112 };
113 }
114 
132 template <class TInputImage, class TOutputImage>
134  public UnaryImageFunctorWithVectorImageFilter<TInputImage,
135  TOutputImage,
136  typename Functor::RadianceToReflectanceImageFunctor<typename
137  TInputImage::
138  InternalPixelType,
139  typename
140  TOutputImage::
141  InternalPixelType> >
142 {
143 public:
145  itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension);
146  itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension);
148 
150  typedef TInputImage InputImageType;
151  typedef TOutputImage OutputImageType;
152  typedef typename Functor::RadianceToReflectanceImageFunctor<typename InputImageType::InternalPixelType,
153  typename OutputImageType::InternalPixelType>
155 
161 
163  itkNewMacro(Self);
164 
166  itkTypeMacro(RadianceToReflectanceImageFilter, UnaryImageFunctorWithVectorImageFiltermageFilter);
167 
169  typedef typename InputImageType::PixelType InputPixelType;
170  typedef typename InputImageType::InternalPixelType InputInternalPixelType;
171  typedef typename InputImageType::RegionType InputImageRegionType;
172  typedef typename OutputImageType::PixelType OutputPixelType;
173  typedef typename OutputImageType::InternalPixelType OutputInternalPixelType;
174  typedef typename OutputImageType::RegionType OutputImageRegionType;
175 
177 
180 
182  itkSetMacro(SolarIllumination, VectorType);
183 
185  itkGetConstReferenceMacro(SolarIllumination, VectorType);
186 
188  itkSetMacro(ZenithalSolarAngle, double);
189 
191  itkGetConstReferenceMacro(ZenithalSolarAngle, double);
192 
194  virtual void SetElevationSolarAngle(double elevationAngle)
195  {
196  double zenithalAngle = 90.0 - elevationAngle;
197  if (this->m_ZenithalSolarAngle != zenithalAngle)
198  {
199  this->m_ZenithalSolarAngle = zenithalAngle;
200  this->Modified();
201  }
202  }
204 
205  virtual double GetElevationSolarAngle() const
206  {
207  return 90.0 - this->m_ZenithalSolarAngle;
208  }
209 
211  itkSetClampMacro(Day, int, 1, 31);
212 
214  itkGetConstReferenceMacro(Day, int);
215 
217  itkSetClampMacro(Month, int, 1, 12);
218 
220  itkGetConstReferenceMacro(Month, int);
221 
224  {
225  m_FluxNormalizationCoefficient = coef;
226  m_IsSetFluxNormalizationCoefficient = true;
227  this->Modified();
228  }
229 
231  itkGetConstReferenceMacro(FluxNormalizationCoefficient, double);
232 
234  void SetSolarDistance(double value)
235  {
236  m_SolarDistance = value;
237  m_IsSetSolarDistance = true;
238  this->Modified();
239  }
240 
242  itkGetConstReferenceMacro(SolarDistance, double);
243 
245  itkSetMacro(IsSetSolarDistance, bool);
246 
248  itkGetConstReferenceMacro(IsSetSolarDistance, bool);
249 
251  itkSetMacro(IsSetFluxNormalizationCoefficient, bool);
252 
254  itkGetConstReferenceMacro(IsSetFluxNormalizationCoefficient, bool);
255 
257  itkSetMacro(UseClamp, bool);
258 
260  itkGetConstReferenceMacro(UseClamp, bool);
261 
262 protected:
265  m_ZenithalSolarAngle(120.0), //invalid value which will lead to negative radiometry
266  m_FluxNormalizationCoefficient(1.),
267  m_Day(0),
268  m_Month(0),
269  m_SolarDistance(1.0),
270  m_IsSetFluxNormalizationCoefficient(false),
271  m_IsSetSolarDistance(false),
272  m_UseClamp(true)
273  {
274  m_SolarIllumination.SetSize(0);
275  };
277 
280 
282  void BeforeThreadedGenerateData(void) override
283  {
285  this->GetInput()->GetMetaDataDictionary());
286  if ((m_Day == 0) && (!m_IsSetFluxNormalizationCoefficient) && (!m_IsSetSolarDistance))
287  {
288  m_Day = imageMetadataInterface->GetDay();
289  }
291 
292  if ((m_Month == 0) && (!m_IsSetFluxNormalizationCoefficient) && (!m_IsSetSolarDistance))
293  {
294  m_Month = imageMetadataInterface->GetMonth();
295  }
296 
297  if (m_SolarIllumination.GetSize() == 0)
298  {
299  m_SolarIllumination = imageMetadataInterface->GetSolarIrradiance();
300  }
301 
302  if (m_ZenithalSolarAngle == 120.0)
303  {
304  //the zenithal angle is the complementary of the elevation angle
305  m_ZenithalSolarAngle = 90.0 - imageMetadataInterface->GetSunElevation();
306  }
307 
308  otbMsgDevMacro(<< "Using correction parameters: ");
309  otbMsgDevMacro(<< "Day: " << m_Day);
310  otbMsgDevMacro(<< "Month: " << m_Month);
311  otbMsgDevMacro(<< "Solar irradiance: " << m_SolarIllumination);
312  otbMsgDevMacro(<< "Zenithal angle: " << m_ZenithalSolarAngle);
313 
314  if ((m_SolarIllumination.GetSize() != this->GetInput()->GetNumberOfComponentsPerPixel()))
315  {
316  itkExceptionMacro(<< "SolarIllumination parameter should have the same size as the number of bands");
317  }
318 
319  this->GetFunctorVector().clear();
320 
321  for (unsigned int i = 0; i < this->GetInput()->GetNumberOfComponentsPerPixel(); ++i)
322  {
323  FunctorType functor;
324  double coefTemp = 0.;
325  if (m_IsSetFluxNormalizationCoefficient){
326  coefTemp =
327  std::cos(m_ZenithalSolarAngle *
328  CONST_PI_180) * m_FluxNormalizationCoefficient * m_FluxNormalizationCoefficient;
329  }
330  else if(m_IsSetSolarDistance){
331  coefTemp = std::cos(m_ZenithalSolarAngle * CONST_PI_180) / (m_SolarDistance * m_SolarDistance);
332  }
333  else if (m_Day * m_Month != 0 && m_Day < 32 && m_Month < 13){
334  coefTemp = std::cos(m_ZenithalSolarAngle * CONST_PI_180) * VarSol::GetVarSol(m_Day, m_Month);
335  }
336  else{
337  itkExceptionMacro(<< "Day has to be included between 1 and 31, Month between 1 and 12.");
338  }
339 
340  functor.SetIlluminationCorrectionCoefficient(1. / coefTemp);
341  functor.SetSolarIllumination(static_cast<double>(m_SolarIllumination[i]));
342  functor.SetUseClamp(m_UseClamp);
343 
344  this->GetFunctorVector().push_back(functor);
345  }
346  }
347 
348 private:
349 
352 
355 
357  int m_Day;
358 
360  int m_Month;
361 
364 
367 
371 
375 
378 
379 };
380 
381 } // end namespace otb
382 #endif
itk::Size< Monteverdi_DIMENSION > SizeType
Definition: mvdTypes.h:137
InputImageType::InternalPixelType InputInternalPixelType
UnaryImageFunctorWithVectorImageFilter< InputImageType, OutputImageType, FunctorType > Superclass
virtual void SetElevationSolarAngle(double elevationAngle)
Functor::RadianceToReflectanceImageFunctor< typename InputImageType::InternalPixelType, typename OutputImageType::InternalPixelType > FunctorType
constexpr double CONST_PI
Definition: otbMath.h:48
static double GetVarSol(const int day, const int month)
Definition: otbVarSol.h:48
constexpr double CONST_PI_180
Definition: otbMath.h:55
Convert radiance value into reflectance value.
OutputImageType::InternalPixelType OutputInternalPixelType
static OpticalImageMetadataInterfacePointerType CreateIMI(const MetaDataDictionaryType &dict)
#define otbMsgDevMacro(x)
Definition: otbMacro.h:66