OTB  10.0.0
Orfeo Toolbox
otbSarRadiometricCalibrationToImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2024 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 otbSarRadiometricCalibrationToImageFilter_hxx
23 #define otbSarRadiometricCalibrationToImageFilter_hxx
24 
27 #include "otbSARMetadata.h"
28 #include <boost/any.hpp>
29 
30 namespace otb
31 {
32 
36 template <class TInputImage, class TOutputImage>
38 {
39 }
40 
41 template <class TInputImage, class TOutputImage>
43 {
44  Superclass::GenerateOutputInformation();
45 
46  // Retrieving input/output pointers
47  InputImagePointer inputPtr = this->GetInput();
48 
49  if (inputPtr.IsNull())
50  {
51  itkExceptionMacro(<< "At least one input is missing."
52  << " Input is missing :" << inputPtr.GetPointer())
53  }
54 
55  OutputImagePointer outputPtr = this->GetOutput();
56  if (outputPtr.IsNull())
57  {
58  itkExceptionMacro(<< "At least one output is missing."
59  << " Output is missing :" << outputPtr.GetPointer())
60  }
61 }
62 
63 template <class TInputImage, class TOutputImage>
65 {
66  // will SetInputImage on the function
67  Superclass::BeforeThreadedGenerateData();
68 
70  auto imd = this->GetInput()->GetImageMetadata();
71 
73  std::unique_ptr<SARCalib> sarCalibPtr;
74  if (imd.Has(MDGeom::SARCalib))
75  {
76  sarCalibPtr = std::make_unique<SARCalib>(boost::any_cast<SARCalib>(imd[MDGeom::SARCalib]));
77  }
78  else if ((imd.Bands.size() > 0) && imd.Bands[0].Has(MDGeom::SARCalib))
79  {
80  sarCalibPtr = std::make_unique<SARCalib>(boost::any_cast<SARCalib>(imd.Bands[0][MDGeom::SARCalib]));
81  }
82  else
83  throw std::runtime_error("otbSarRadiometricCalibrationToImageFilter was not able to fetch the SARCalib metadata.");
85 
87  FunctionPointer function = this->GetFunction();
88 
95  bool apply = sarCalibPtr->calibrationLookupFlag;
96 
97  /* Below lines will toggle the necessary flags which can help skip some
98  * computation. For example, if there is lookup value and ofcourse antenna
99  * pattern gain is not required. Even if we try to compute the value with
100  * sarCalibetricFunction we get 1. This is the safe side. But as we are so sure
101  * we skip all those calls to EvaluateParametricCoefficient and also the
102  * Evaluate(). For the function the value is 1 by default.
103  */
104  function->SetApplyAntennaPatternGain(!apply);
105  function->SetApplyIncidenceAngleCorrection(!apply);
106  function->SetApplyRangeSpreadLossCorrection(!apply);
107  function->SetApplyRescalingFactor(!apply);
108  function->SetApplyLookupDataCorrection(apply);
109 
110  if (imd.Has(MDNum::CalScale))
111  function->SetScale(imd[MDNum::CalScale]);
112  else if ((imd.Bands.size() > 0) && (imd.Bands[0].Has(MDNum::CalScale)))
113  function->SetScale(imd.Bands[0][MDNum::CalScale]);
114 
115  /* Compute noise if enabled */
116  if (function->GetEnableNoise())
117  {
118  // Use a denoising LUT if available (e.g Sentinel 1 thermal noise LUT)
119  if (sarCalibPtr->calibrationLookupData.find(SarCalibrationLookupData::NOISE)
120  != sarCalibPtr->calibrationLookupData.end())
121  {
122  function->SetNoiseLookupData(sarCalibPtr->calibrationLookupData[SarCalibrationLookupData::NOISE]);
123  }
124  // Use a parametric function instead
125  else
126  {
128  noise = function->GetNoise();
129  noise->SetPointSet(sarCalibPtr->radiometricCalibrationNoise);
130  noise->SetPolynomalSize(sarCalibPtr->radiometricCalibrationNoisePolynomialDegree);
131  noise->EvaluateParametricCoefficient();
132  }
133  }
134 
135  /* Compute old and new antenna pattern gain */
136  if (function->GetApplyAntennaPatternGain())
137  {
138  ParametricFunctionPointer antennaPatternNewGain;
139  antennaPatternNewGain = function->GetAntennaPatternNewGain();
140  antennaPatternNewGain->SetPointSet(sarCalibPtr->radiometricCalibrationAntennaPatternNewGain);
141  antennaPatternNewGain->SetPolynomalSize(sarCalibPtr->radiometricCalibrationAntennaPatternNewGainPolynomialDegree);
142  antennaPatternNewGain->EvaluateParametricCoefficient();
143 
144  ParametricFunctionPointer antennaPatternOldGain;
145  antennaPatternOldGain = function->GetAntennaPatternOldGain();
146  antennaPatternOldGain->SetPointSet(sarCalibPtr->radiometricCalibrationAntennaPatternOldGain);
147  antennaPatternOldGain->SetPolynomalSize(sarCalibPtr->radiometricCalibrationAntennaPatternOldGainPolynomialDegree);
148  antennaPatternOldGain->EvaluateParametricCoefficient();
149  }
150 
151  /* Compute incidence angle */
152  if (function->GetApplyIncidenceAngleCorrection())
153  {
154  ParametricFunctionPointer incidenceAngle;
155  incidenceAngle = function->GetIncidenceAngle();
156  incidenceAngle->SetPointSet(sarCalibPtr->radiometricCalibrationIncidenceAngle);
157  incidenceAngle->SetPolynomalSize(sarCalibPtr->radiometricCalibrationIncidenceAnglePolynomialDegree);
158  incidenceAngle->EvaluateParametricCoefficient();
159  }
160 
161  /* Compute Range spread Loss */
162  if (function->GetApplyRangeSpreadLossCorrection())
163  {
164  ParametricFunctionPointer rangeSpreadLoss;
165  rangeSpreadLoss = function->GetRangeSpreadLoss();
166  rangeSpreadLoss->SetPointSet(sarCalibPtr->radiometricCalibrationRangeSpreadLoss);
167  rangeSpreadLoss->SetPolynomalSize(sarCalibPtr->radiometricCalibrationRangeSpreadLossPolynomialDegree);
168  rangeSpreadLoss->EvaluateParametricCoefficient();
169  }
170 
180  if (function->GetApplyLookupDataCorrection())
181  {
182  function->SetCalibrationLookupData(sarCalibPtr->calibrationLookupData[this->GetLookupSelected()]);
183  }
184 
186  if (function->GetApplyRescalingFactor())
187  {
188  function->SetRescalingFactor(sarCalibPtr->rescalingFactor);
189  }
190 }
192 
193 } // end namespace otb
194 
195 #endif
TResult apply(TGeometry *geometry, TFunctor functor)
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.