OTB  6.7.0
Orfeo Toolbox
otbImageToReflectanceImageFilter.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 otbImageToReflectanceImageFilter_h
23 #define otbImageToReflectanceImageFilter_h
24 
27 
28 namespace otb
29 {
30 namespace Functor
31 {
45 template <class TInput, class TOutput>
47 {
48 public:
51 
54 
55  void SetAlpha(double alpha)
56  {
58  }
59  void SetBeta(double beta)
60  {
62  }
63  void SetSolarIllumination(double solarIllumination)
64  {
65  m_LumToReflecFunctor.SetSolarIllumination(solarIllumination);
66  }
68  {
70  }
71  void SetUseClamp(bool useClamp)
72  {
74  }
75 
76  double GetAlpha()
77  {
78  return m_ImToLumFunctor.GetAlpha();
79  }
80  double GetBeta()
81  {
82  return m_ImToLumFunctor.GetBeta();
83  }
85  {
87  }
89  {
91  }
92  bool GetUseClamp()
93  {
95  }
96 
97  inline TOutput operator ()(const TInput& inPixel) const
98  {
99  TOutput outPixel;
100  TOutput tempPix;
101  tempPix = m_ImToLumFunctor(inPixel);
102  outPixel = m_LumToReflecFunctor(tempPix);
103 
104  return outPixel;
105  }
106 
107 private:
110 
111 };
112 }
113 
133 template <class TInputImage, class TOutputImage>
135  public UnaryImageFunctorWithVectorImageFilter<TInputImage,
136  TOutputImage,
137  typename Functor::ImageToReflectanceImageFunctor<typename
138  TInputImage::
139  InternalPixelType,
140  typename
141  TOutputImage::
142  InternalPixelType> >
143 {
144 public:
146  itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension);
147  itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension);
149 
151  typedef TInputImage InputImageType;
152  typedef TOutputImage OutputImageType;
153  typedef typename Functor::ImageToReflectanceImageFunctor<typename InputImageType::InternalPixelType,
154  typename OutputImageType::InternalPixelType> FunctorType;
155 
161 
163  itkNewMacro(Self);
164 
166  itkTypeMacro(ImageToReflectanceImageFilter, 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(Alpha, VectorType);
183 
185  itkGetConstReferenceMacro(Alpha, VectorType);
186 
188  itkSetMacro(Beta, VectorType);
189 
191  itkGetConstReferenceMacro(Beta, VectorType);
192 
194  itkSetMacro(SolarIllumination, VectorType);
195 
197  itkGetConstReferenceMacro(SolarIllumination, VectorType);
198 
200  itkSetMacro(ZenithalSolarAngle, double);
201 
203  itkGetConstReferenceMacro(ZenithalSolarAngle, double);
204 
206  itkSetMacro(UseClamp,bool);
207 
209  itkGetConstReferenceMacro(UseClamp,bool);
210 
212  virtual void SetElevationSolarAngle(double elevationAngle)
213  {
214  double zenithalAngle = 90.0 - elevationAngle;
215  if (this->m_ZenithalSolarAngle != zenithalAngle)
216  {
217  this->m_ZenithalSolarAngle = zenithalAngle;
218  this->Modified();
219  }
220  }
222 
223  virtual double GetElevationSolarAngle() const
224  {
225  return 90.0 - this->m_ZenithalSolarAngle;
226  }
227 
230  {
231  m_FluxNormalizationCoefficient = coef;
232  m_IsSetFluxNormalizationCoefficient = true;
233  this->Modified();
234  }
236 
238  void SetSolarDistance(double value)
239  {
240  m_SolarDistance = value;
241  m_IsSetSolarDistance = true;
242  this->Modified();
243  }
244 
246  itkGetConstReferenceMacro(SolarDistance, double);
247 
249  itkSetMacro(IsSetSolarDistance, bool);
250 
252  itkGetConstReferenceMacro(IsSetSolarDistance, bool);
253 
255  itkSetClampMacro(Day, int, 1, 31);
256 
258  itkGetConstReferenceMacro(Day, int);
259 
261  itkSetClampMacro(Month, int, 1, 12);
262 
264  itkGetConstReferenceMacro(Month, int);
265 
266 protected:
269  m_ZenithalSolarAngle(120.), //invalid value which will lead to negative radiometry
270  m_FluxNormalizationCoefficient(1.),
271  m_UseClamp(true),
272  m_IsSetFluxNormalizationCoefficient(false),
273  m_Day(0),
274  m_Month(0),
275  m_SolarDistance(1.0),
276  m_IsSetSolarDistance(false)
277  {
278  m_Alpha.SetSize(0);
279  m_Beta.SetSize(0);
280  m_SolarIllumination.SetSize(0);
281  };
283 
286 
288  void BeforeThreadedGenerateData(void) override
289  {
290 
292  this->GetInput()->GetMetaDataDictionary());
293  if (m_Alpha.GetSize() == 0)
294  {
295  m_Alpha = imageMetadataInterface->GetPhysicalGain();
296  }
297 
298  if (m_Beta.GetSize() == 0)
299  {
300  m_Beta = imageMetadataInterface->GetPhysicalBias();
301  }
302 
303  if ((m_Day == 0) && (!m_IsSetFluxNormalizationCoefficient) && (!m_IsSetSolarDistance))
304  {
305  m_Day = imageMetadataInterface->GetDay();
306  }
307 
308  if ((m_Month == 0) && (!m_IsSetFluxNormalizationCoefficient) && (!m_IsSetSolarDistance))
309  {
310  m_Month = imageMetadataInterface->GetMonth();
311  }
312 
313  if (m_SolarIllumination.GetSize() == 0)
314  {
315  m_SolarIllumination = imageMetadataInterface->GetSolarIrradiance();
316  }
317 
318  if (m_ZenithalSolarAngle == 120.0)
319  {
320  //the zenithal angle is the complementary of the elevation angle
321  m_ZenithalSolarAngle = 90.0 - imageMetadataInterface->GetSunElevation();
322  }
323 
324  otbMsgDevMacro(<< "Using correction parameters: ");
325  otbMsgDevMacro(<< "Alpha (gain): " << m_Alpha);
326  otbMsgDevMacro(<< "Beta (bias): " << m_Beta);
327  otbMsgDevMacro(<< "Day: " << m_Day);
328  otbMsgDevMacro(<< "Month: " << m_Month);
329  otbMsgDevMacro(<< "Solar irradiance: " << m_SolarIllumination);
330  otbMsgDevMacro(<< "Zenithal angle: " << m_ZenithalSolarAngle);
331 
332  if ((m_Alpha.GetSize() != this->GetInput()->GetNumberOfComponentsPerPixel())
333  || (m_Beta.GetSize() != this->GetInput()->GetNumberOfComponentsPerPixel())
334  || (m_SolarIllumination.GetSize() != this->GetInput()->GetNumberOfComponentsPerPixel()))
335  {
336  itkExceptionMacro(
337  << "Alpha, Beta and SolarIllumination parameters should have the same size as the number of bands");
338  }
339 
340  this->GetFunctorVector().clear();
341  for (unsigned int i = 0; i < this->GetInput()->GetNumberOfComponentsPerPixel(); ++i)
342  {
343  FunctorType functor;
344  double coefTemp = 0.;
345 
346  if(m_IsSetFluxNormalizationCoefficient){
347  coefTemp =
348  std::cos(m_ZenithalSolarAngle *
349  CONST_PI_180) * m_FluxNormalizationCoefficient * m_FluxNormalizationCoefficient;
350  }
351  else if(m_IsSetSolarDistance){
352  coefTemp = std::cos(m_ZenithalSolarAngle * CONST_PI_180) / (m_SolarDistance * m_SolarDistance);
353  }
354  else if (m_Day * m_Month != 0 && m_Day < 32 && m_Month < 13){
355  coefTemp = std::cos(m_ZenithalSolarAngle * CONST_PI_180) * VarSol::GetVarSol(m_Day, m_Month);
356  }
357  else{
358  itkExceptionMacro(<< "Day has to be included between 1 and 31, Month between 1 and 12.");
359  }
360 
361  functor.SetIlluminationCorrectionCoefficient(1. / coefTemp);
362  functor.SetAlpha(m_Alpha[i]);
363  functor.SetBeta(m_Beta[i]);
364  functor.SetSolarIllumination(m_SolarIllumination[i]);
365  functor.SetUseClamp(m_UseClamp);
366  this->GetFunctorVector().push_back(functor);
367  }
368  }
369 
370 private:
374 
377 
380 
383 
386 
390 
392  int m_Day;
393 
395  int m_Month;
396 
399 
403 };
404 
405 } // end namespace otb
406 
407 #endif
Functor::ImageToReflectanceImageFunctor< typename InputImageType::InternalPixelType, typename OutputImageType::InternalPixelType > FunctorType
itk::Size< Monteverdi_DIMENSION > SizeType
Definition: mvdTypes.h:137
Call the ImageToRadianceFunctor over the input and the RadianceToReflectanceFunctor to this result...
Functor::ImageToRadianceImageFunctor< TInput, TOutput > ImToLumFunctorType
virtual void SetElevationSolarAngle(double elevationAngle)
UnaryImageFunctorWithVectorImageFilter< InputImageType, OutputImageType, FunctorType > Superclass
static double GetVarSol(const int day, const int month)
Definition: otbVarSol.h:48
itk::VariableLengthVector< double > VectorType
constexpr double CONST_PI_180
Definition: otbMath.h:55
OutputImageType::InternalPixelType OutputInternalPixelType
Functor::RadianceToReflectanceImageFunctor< TInput, TOutput > LumToReflecFunctorType
Add beta to the quotient Input over alpha.
Convert a raw value into a reflectance value.
InputImageType::InternalPixelType InputInternalPixelType
static OpticalImageMetadataInterfacePointerType CreateIMI(const MetaDataDictionaryType &dict)
#define otbMsgDevMacro(x)
Definition: otbMacro.h:66