23 #ifndef otbSurfaceAdjacencyEffectCorrectionSchemeFilter_hxx
24 #define otbSurfaceAdjacencyEffectCorrectionSchemeFilter_hxx
28 #include "itkConstNeighborhoodIterator.h"
29 #include "itkNeighborhoodInnerProduct.h"
30 #include "itkImageRegionIterator.h"
31 #include "itkNeighborhoodAlgorithm.h"
32 #include "itkOffset.h"
33 #include "itkProgressReporter.h"
41 template <
class TInputImage,
class TOutputImage>
43 : m_IsSetAtmosphericRadiativeTerms(false),
44 m_IsSetAtmoCorrectionParameters(false),
45 m_IsSetAcquiCorrectionParameters(false),
47 m_FunctorParametersHaveBeenComputed(false),
48 m_PixelSpacingInKilometers(1.),
49 m_ZenithalViewingAngle(361.)
56 template <
class TInputImage,
class TOutputImage>
59 Superclass::BeforeThreadedGenerateData();
60 this->GenerateParameters();
63 template <
class TInputImage,
class TOutputImage>
66 Superclass::Modified();
67 m_FunctorParametersHaveBeenComputed =
false;
70 template <
class TInputImage,
class TOutputImage>
73 if (this->GetInput() ==
nullptr)
75 itkExceptionMacro(<<
"Input must be set before updating the atmospheric radiative terms");
79 if (!m_IsSetAtmoCorrectionParameters)
81 itkExceptionMacro(<<
"Atmospheric correction parameters must be provided before updating the atmospheric radiative terms");
87 if (!m_IsSetAcquiCorrectionParameters)
89 const auto & metadata = this->GetInput()->GetImageMetadata();
91 m_AcquiCorrectionParameters = AcquiCorrectionParametersType::New();
96 m_AcquiCorrectionParameters->SetViewingAzimutalAngle(metadata[
MDNum::SatAzimuth]);
104 auto spectralSensitivity = AcquiCorrectionParametersType::InternalWavelengthSpectralBandVectorType::New();
105 for (
const auto & band : metadata.Bands)
108 const auto & axis = spectralSensitivityLUT.Axis[0];
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);
119 m_AcquiCorrectionParameters->SetWavelengthSpectralBand(spectralSensitivity);
125 spectralDummy->Clear();
126 for (
unsigned int i = 0; i < this->GetInput()->GetNumberOfComponentsPerPixel(); ++i)
128 spectralDummy->PushBack(FilterFunctionValuesType::New());
130 m_AcquiCorrectionParameters->SetWavelengthSpectralBand(spectralDummy);
135 m_AtmosphericRadiativeTerms = CorrectionParametersToRadiativeTermsType::Compute(m_AtmoCorrectionParameters, m_AcquiCorrectionParameters);
138 template <
class TInputImage,
class TOutputImage>
141 if (!m_IsSetAtmosphericRadiativeTerms)
143 this->UpdateAtmosphericRadiativeTerms();
144 m_IsSetAtmosphericRadiativeTerms =
true;
147 if (!m_FunctorParametersHaveBeenComputed)
149 this->UpdateFunctors();
150 m_FunctorParametersHaveBeenComputed =
true;
154 template <
class TInputImage,
class TOutputImage>
158 typename InputImageType::Pointer inputPtr =
const_cast<TInputImage*
>(this->GetInput());
159 typename OutputImageType::Pointer outputPtr =
const_cast<TOutputImage*
>(this->GetOutput());
162 radiusMatrix.Fill(0.);
164 double center =
static_cast<double>(m_WindowRadius);
166 for (
unsigned int i = 0; i < m_WindowRadius + 1; ++i)
168 for (
unsigned int j = 0; j < m_WindowRadius + 1; ++j)
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;
180 for (
unsigned int band = 0; band < inputPtr->GetNumberOfComponentsPerPixel(); ++band)
182 double rayleigh = m_AtmosphericRadiativeTerms->GetUpwardDiffuseTransmittanceForRayleigh(band);
183 double aerosol = m_AtmosphericRadiativeTerms->GetUpwardDiffuseTransmittanceForAerosol(band);
185 WeightingMatrixType currentWeightingMatrix(2 * m_WindowRadius + 1, 2 * m_WindowRadius + 1);
186 currentWeightingMatrix.Fill(0.);
188 for (
unsigned int i = 0; i < 2 * m_WindowRadius + 1; ++i)
190 for (
unsigned int j = 0; j < 2 * m_WindowRadius + 1; ++j)
192 double notUsed1, notUsed2;
198 currentWeightingMatrix(i, j) = factor;
201 m_WeightingValues.push_back(currentWeightingMatrix);
206 for (
unsigned int band = 0; band < inputPtr->GetNumberOfComponentsPerPixel(); ++band)
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));
212 this->GetFunctor().SetUpwardTransmittanceRatio(upwardTransmittanceRatio);
213 this->GetFunctor().SetDiffuseRatio(diffuseRatio);
214 this->GetFunctor().SetWeightingValues(m_WeightingValues);
219 template <
class TInputImage,
class TOutput>
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;