OTB  9.0.0
Orfeo Toolbox
otbSurfaceAdjacencyEffectCorrectionSchemeFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2022 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 
23 #ifndef otbSurfaceAdjacencyEffectCorrectionSchemeFilter_hxx
24 #define otbSurfaceAdjacencyEffectCorrectionSchemeFilter_hxx
25 
27 
28 #include "itkConstNeighborhoodIterator.h"
29 #include "itkNeighborhoodInnerProduct.h"
30 #include "itkImageRegionIterator.h"
31 #include "itkNeighborhoodAlgorithm.h"
32 #include "itkOffset.h"
33 #include "itkProgressReporter.h"
34 #include "otbImage.h"
35 #include "otbSIXSTraits.h"
36 #include "otbMath.h"
37 
38 namespace otb
39 {
40 
41 template <class TInputImage, class TOutputImage>
43  : m_IsSetAtmosphericRadiativeTerms(false),
44  m_IsSetAtmoCorrectionParameters(false),
45  m_IsSetAcquiCorrectionParameters(false),
46  m_WindowRadius(1),
47  m_FunctorParametersHaveBeenComputed(false),
48  m_PixelSpacingInKilometers(1.),
49  m_ZenithalViewingAngle(361.)
50 {
54 }
55 
56 template <class TInputImage, class TOutputImage>
58 {
59  Superclass::BeforeThreadedGenerateData();
60  this->GenerateParameters();
61 }
62 
63 template <class TInputImage, class TOutputImage>
65 {
66  Superclass::Modified();
67  m_FunctorParametersHaveBeenComputed = false;
68 }
69 
70 template <class TInputImage, class TOutputImage>
72 {
73  if (this->GetInput() == nullptr)
74  {
75  itkExceptionMacro(<< "Input must be set before updating the atmospheric radiative terms");
76  }
77 
78  // Atmospheric parameters
79  if (!m_IsSetAtmoCorrectionParameters)
80  {
81  itkExceptionMacro(<< "Atmospheric correction parameters must be provided before updating the atmospheric radiative terms");
82  }
83 
84 
85 
86  // Acquisition parameters
87  if (!m_IsSetAcquiCorrectionParameters) // Get info from image metadata
88  {
89  const auto & metadata = this->GetInput()->GetImageMetadata();
90 
91  m_AcquiCorrectionParameters = AcquiCorrectionParametersType::New();
92 
93  m_AcquiCorrectionParameters->SetSolarZenithalAngle(90. - metadata[MDNum::SunElevation]);
94  m_AcquiCorrectionParameters->SetSolarAzimutalAngle(metadata[MDNum::SunAzimuth]);
95  m_AcquiCorrectionParameters->SetViewingZenithalAngle(90. - metadata[MDNum::SatElevation]);
96  m_AcquiCorrectionParameters->SetViewingAzimutalAngle(metadata[MDNum::SatAzimuth]);
97 
98  m_AcquiCorrectionParameters->SetDay(metadata[MDTime::AcquisitionDate].GetDay());
99  m_AcquiCorrectionParameters->SetMonth(metadata[MDTime::AcquisitionDate].GetMonth());
100 
101 
102  if (metadata.HasBandMetadata(MDL1D::SpectralSensitivity))
103  {
104  auto spectralSensitivity = AcquiCorrectionParametersType::InternalWavelengthSpectralBandVectorType::New();
105  for (const auto & band : metadata.Bands)
106  {
107  const auto & spectralSensitivityLUT = band[MDL1D::SpectralSensitivity];
108  const auto & axis = spectralSensitivityLUT.Axis[0];
109  auto filterFunction = FilterFunctionValues::New();
110  // LUT1D stores a double vector whereas FilterFunctionValues stores a float vector
111  std::vector<float> vec(spectralSensitivityLUT.Array.begin(), spectralSensitivityLUT.Array.end());
112  filterFunction->SetFilterFunctionValues(vec);
113  filterFunction->SetMinSpectralValue(axis.Origin);
114  filterFunction->SetMaxSpectralValue(axis.Origin + axis.Spacing * (axis.Size-1));
115  filterFunction->SetUserStep(axis.Spacing);
116  spectralSensitivity->PushBack(filterFunction);
117  }
118 
119  m_AcquiCorrectionParameters->SetWavelengthSpectralBand(spectralSensitivity);
120  }
121  else
122  {
123  otbMsgDevMacro(<< "use dummy filter");
124  WavelengthSpectralBandVectorType spectralDummy = AcquiCorrectionParametersType::InternalWavelengthSpectralBandVectorType::New();
125  spectralDummy->Clear();
126  for (unsigned int i = 0; i < this->GetInput()->GetNumberOfComponentsPerPixel(); ++i)
127  {
128  spectralDummy->PushBack(FilterFunctionValuesType::New());
129  }
130  m_AcquiCorrectionParameters->SetWavelengthSpectralBand(spectralDummy);
131  }
132 
133  }
134 
135  m_AtmosphericRadiativeTerms = CorrectionParametersToRadiativeTermsType::Compute(m_AtmoCorrectionParameters, m_AcquiCorrectionParameters);
136 }
137 
138 template <class TInputImage, class TOutputImage>
140 {
141  if (!m_IsSetAtmosphericRadiativeTerms)
142  {
143  this->UpdateAtmosphericRadiativeTerms();
144  m_IsSetAtmosphericRadiativeTerms = true;
145  }
146 
147  if (!m_FunctorParametersHaveBeenComputed)
148  {
149  this->UpdateFunctors();
150  m_FunctorParametersHaveBeenComputed = true;
151  }
152 }
153 
154 template <class TInputImage, class TOutputImage>
156 {
157  // get pointers to the input and output
158  typename InputImageType::Pointer inputPtr = const_cast<TInputImage*>(this->GetInput());
159  typename OutputImageType::Pointer outputPtr = const_cast<TOutputImage*>(this->GetOutput());
160 
161  WeightingMatrixType radiusMatrix(2 * m_WindowRadius + 1, 2 * m_WindowRadius + 1);
162  radiusMatrix.Fill(0.);
163 
164  double center = static_cast<double>(m_WindowRadius);
165 
166  for (unsigned int i = 0; i < m_WindowRadius + 1; ++i)
167  {
168  for (unsigned int j = 0; j < m_WindowRadius + 1; ++j)
169  {
170  double id = static_cast<double>(i);
171  double jd = static_cast<double>(j);
172  double currentRadius = m_PixelSpacingInKilometers * std::sqrt(std::pow(id - center, 2) + std::pow(jd - center, 2));
173  radiusMatrix(i, j) = currentRadius;
174  radiusMatrix(2 * m_WindowRadius - i, j) = currentRadius;
175  radiusMatrix(2 * m_WindowRadius - i, 2 * m_WindowRadius - j) = currentRadius;
176  radiusMatrix(i, 2 * m_WindowRadius - j) = currentRadius;
177  }
178  }
179 
180  for (unsigned int band = 0; band < inputPtr->GetNumberOfComponentsPerPixel(); ++band)
181  {
182  double rayleigh = m_AtmosphericRadiativeTerms->GetUpwardDiffuseTransmittanceForRayleigh(band);
183  double aerosol = m_AtmosphericRadiativeTerms->GetUpwardDiffuseTransmittanceForAerosol(band);
184 
185  WeightingMatrixType currentWeightingMatrix(2 * m_WindowRadius + 1, 2 * m_WindowRadius + 1);
186  currentWeightingMatrix.Fill(0.);
187 
188  for (unsigned int i = 0; i < 2 * m_WindowRadius + 1; ++i)
189  {
190  for (unsigned int j = 0; j < 2 * m_WindowRadius + 1; ++j)
191  {
192  double notUsed1, notUsed2;
193  double factor = 1;
194  double palt = 1000.;
195  SIXSTraits::ComputeEnvironmentalContribution(rayleigh, aerosol, radiusMatrix(i, j), palt, std::cos(m_ZenithalViewingAngle * CONST_PI_180), notUsed1,
196  notUsed2,
197  factor); // Call to 6S
198  currentWeightingMatrix(i, j) = factor;
199  }
200  }
201  m_WeightingValues.push_back(currentWeightingMatrix);
202  }
203 
204  DoubleContainerType upwardTransmittanceRatio, diffuseRatio;
205 
206  for (unsigned int band = 0; band < inputPtr->GetNumberOfComponentsPerPixel(); ++band)
207  {
208  upwardTransmittanceRatio.push_back(m_AtmosphericRadiativeTerms->GetUpwardTransmittance(band) /
209  m_AtmosphericRadiativeTerms->GetUpwardDirectTransmittance(band));
210  diffuseRatio.push_back(m_AtmosphericRadiativeTerms->GetUpwardDiffuseTransmittance(band) / m_AtmosphericRadiativeTerms->GetUpwardDirectTransmittance(band));
211  }
212  this->GetFunctor().SetUpwardTransmittanceRatio(upwardTransmittanceRatio);
213  this->GetFunctor().SetDiffuseRatio(diffuseRatio);
214  this->GetFunctor().SetWeightingValues(m_WeightingValues);
215 }
219 template <class TInputImage, class TOutput>
221 {
222  os << indent << "Radius : " << m_WindowRadius << std::endl;
223  os << indent << "Pixel spacing in kilometers: " << m_PixelSpacingInKilometers << std::endl;
224  os << indent << "Zenithal viewing angle in degree: " << m_AcquiCorrectionParameters->GetViewingZenithalAngle() << std::endl;
225 }
227 
228 } // end namespace otb
229 
230 #endif
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::WavelengthSpectralBandVectorType
AcquiCorrectionParametersType::WavelengthSpectralBandVectorType WavelengthSpectralBandVectorType
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h:197
otb::MDNum::SatElevation
@ SatElevation
otb::SIXSTraits::ComputeEnvironmentalContribution
static void ComputeEnvironmentalContribution(const double diffuseTransmittanceForRayleighScattering, const double diffuseTransmittanceForAerosolScattering, const double radiusInKilometers, const double altitude, const double cosineOfViewingAngle, double &rayleighEstimation, double &aerosolEstimation, double &globalEstimation)
otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::m_AcquiCorrectionParameters
AcquiCorrectionParametersPointerType m_AcquiCorrectionParameters
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h:299
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::BeforeThreadedGenerateData
void BeforeThreadedGenerateData() override
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.hxx:57
otbImage.h
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::DoubleContainerType
std::vector< double > DoubleContainerType
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h:159
otb::MDTime::AcquisitionDate
@ AcquisitionDate
otbMath.h
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::Modified
void Modified() const override
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.hxx:64
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::SurfaceAdjacencyEffectCorrectionSchemeFilter
SurfaceAdjacencyEffectCorrectionSchemeFilter()
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.hxx:42
otb::CONST_PI_180
constexpr double CONST_PI_180
Definition: otbMath.h:56
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::WeightingMatrixType
itk::VariableSizeMatrix< double > WeightingMatrixType
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h:202
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.hxx:220
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::m_AtmosphericRadiativeTerms
AtmosphericRadiativeTermsPointerType m_AtmosphericRadiativeTerms
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h:297
otb::MDNum::SunAzimuth
@ SunAzimuth
otb::MDNum::SatAzimuth
@ SatAzimuth
otb::FilterFunctionValues::New
static Pointer New()
otbSIXSTraits.h
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::UpdateFunctors
void UpdateFunctors()
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.hxx:155
otbMsgDevMacro
#define otbMsgDevMacro(x)
Definition: otbMacro.h:64
otb::ImageMetadataCorrectionParameters::New
static Pointer New()
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::UpdateAtmosphericRadiativeTerms
void UpdateAtmosphericRadiativeTerms()
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.hxx:71
otb::AtmosphericRadiativeTerms::New
static Pointer New()
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::GenerateParameters
void GenerateParameters()
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.hxx:139
otb::AtmosphericCorrectionParameters::New
static Pointer New()
otb::SurfaceAdjacencyEffectCorrectionSchemeFilter::m_AtmoCorrectionParameters
AtmoCorrectionParametersPointerType m_AtmoCorrectionParameters
Definition: otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h:298
otb::MDL1D::SpectralSensitivity
@ SpectralSensitivity
otb::MDNum::SunElevation
@ SunElevation