diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.h b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.h index 541afff72d4dc35ffc3ae3055abda78f4ef74846..32799f20d870082da2e4b92214439843e10f961b 100644 --- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.h +++ b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.h @@ -20,11 +20,10 @@ #include "otbSarRadiometricCalibrationFunctor.h" #include "otbSarParametricMapFunction.h" - +#include "otbSarCalibrationLookupData.h" namespace otb { - /** * \class SarRadiometricCalibrationFunction * \brief Calculate the backscatter for the given pixel @@ -71,33 +70,31 @@ public: itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension); - /** Datatype used for the evaluation */ typedef double RealType; - typedef otb::Functor::SarRadiometricCalibrationFunctor<RealType, RealType> FunctorType; - typedef typename FunctorType::RealType FunctorRealType; +// typedef otb::Functor::SarRadiometricCalibrationFunctor<RealType, RealType> FunctorType; +// typedef typename FunctorType::RealType FunctorRealType; typedef otb::SarParametricMapFunction<InputImageType> ParametricFunctionType; typedef typename ParametricFunctionType::Pointer ParametricFunctionPointer; typedef typename ParametricFunctionType::ConstPointer ParametricFunctionConstPointer; - /** Evaluate the function at non-integer positions */ - virtual OutputType Evaluate(const PointType& point) const; - /** Evalulate the function at specified index */ - virtual OutputType EvaluateAtIndex(const IndexType& index) const + virtual OutputType EvaluateAtIndex(const IndexType& index) const; + + /** Evaluate the function at non-integer positions */ + virtual OutputType Evaluate(const PointType& point) const { - PointType point; - this->GetInputImage()->TransformIndexToPhysicalPoint( index, point); - return this->Evaluate(point); + IndexType index; + this->ConvertPointToNearestIndex(point, index); + return this->EvaluateAtIndex(index); } - virtual OutputType EvaluateAtContinuousIndex( - const ContinuousIndexType& cindex) const + virtual OutputType EvaluateAtContinuousIndex(const ContinuousIndexType& cindex) const { - PointType point; - this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( cindex, point); - return this->Evaluate(point); + IndexType index; + this->ConvertContinuousIndexToNearestIndex(cindex, index); + return this->EvaluateAtIndex(index); } /** Set the input image. @@ -108,10 +105,10 @@ public: /** Get/Set the Scale value */ - itkSetMacro(Scale, FunctorRealType); - itkGetMacro(Scale, FunctorRealType); + itkSetMacro(Scale, RealType); + itkGetMacro(Scale, RealType); - /** Get/Set the Offset value */ + /** Get/Set the Noise value */ itkSetObjectMacro(Noise, ParametricFunctionType); itkGetConstObjectMacro(Noise, ParametricFunctionType); itkGetObjectMacro(Noise, ParametricFunctionType); @@ -140,23 +137,66 @@ public: itkGetConstObjectMacro(RangeSpreadLoss, ParametricFunctionType); itkGetObjectMacro(RangeSpreadLoss, ParametricFunctionType); + /** Set the RescalingFactor value */ + itkSetMacro(RescalingFactor, RealType); + + /** Get/Set flag to indicate if these are used */ + itkSetMacro(ApplyAntennaPatternGain, bool); + itkGetMacro(ApplyAntennaPatternGain, bool); + + itkSetMacro(ApplyIncidenceAngleCorrection, bool); + itkGetMacro(ApplyIncidenceAngleCorrection, bool); + + itkSetMacro(ApplyRangeSpreadLossCorrection, bool); + itkGetMacro(ApplyRangeSpreadLossCorrection, bool); + + itkSetMacro(ApplyLookupDataCorrection, bool); + itkGetMacro(ApplyLookupDataCorrection, bool); + + itkSetMacro(ApplyRescalingFactor, bool); + itkGetMacro(ApplyRescalingFactor, bool); + + typedef SarCalibrationLookupData::Pointer LookupDataPointer; + + /** Set SetCalibrationLookupData instance */ + void SetCalibrationLookupData(LookupDataPointer lut) + { + m_Lut = lut; + } protected: + + /** ctor */ SarRadiometricCalibrationFunction(); + + /** default, empty, virtual dtor */ virtual ~SarRadiometricCalibrationFunction(){} + + /** print method */ void PrintSelf(std::ostream& os, itk::Indent indent) const; + /** Flags to indiciate if these values needs to be applied in calibration*/ + private: SarRadiometricCalibrationFunction(const Self &); //purposely not implemented void operator =(const Self&); //purposely not implemented - FunctorRealType m_Scale; - ParametricFunctionPointer m_Noise; + RealType m_Scale; bool m_EnableNoise; + RealType m_RescalingFactor; + bool m_ApplyAntennaPatternGain; + bool m_ApplyIncidenceAngleCorrection; + bool m_ApplyRangeSpreadLossCorrection; + bool m_ApplyLookupDataCorrection; + bool m_ApplyRescalingFactor; + ParametricFunctionPointer m_Noise; ParametricFunctionPointer m_AntennaPatternNewGain; ParametricFunctionPointer m_AntennaPatternOldGain; ParametricFunctionPointer m_IncidenceAngle; ParametricFunctionPointer m_RangeSpreadLoss; + LookupDataPointer m_Lut; + + }; } // end namespace otb diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.txx b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.txx index b04ee4c8fc450006826cf3db1f5ad80777ca518b..2c3cf2aa4740854bd9028c5e17675939eaf48732 100644 --- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.txx +++ b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.txx @@ -24,27 +24,38 @@ namespace otb { - /** * Constructor */ template <class TInputImage, class TCoordRep> SarRadiometricCalibrationFunction<TInputImage, TCoordRep> -::SarRadiometricCalibrationFunction(): - m_Scale(1.0) +::SarRadiometricCalibrationFunction() +: m_Scale(1.0) +, m_EnableNoise(false) +, m_RescalingFactor(1.0) +, m_ApplyAntennaPatternGain(true) +, m_ApplyIncidenceAngleCorrection(true) +, m_ApplyRangeSpreadLossCorrection(true) +, m_ApplyLookupDataCorrection(false) +, m_ApplyRescalingFactor(false) + { + /* intialize parametric functions */ m_Noise = ParametricFunctionType::New(); m_AntennaPatternNewGain = ParametricFunctionType::New(); m_AntennaPatternOldGain = ParametricFunctionType::New(); m_IncidenceAngle = ParametricFunctionType::New(); m_RangeSpreadLoss = ParametricFunctionType::New(); + /* intialize default values in paramerticFunction instances */ m_Noise->SetConstantValue(0.0); - m_EnableNoise = true; m_AntennaPatternNewGain->SetConstantValue(1.0); m_AntennaPatternOldGain->SetConstantValue(1.0); m_IncidenceAngle->SetConstantValue(CONST_PI_2); m_RangeSpreadLoss->SetConstantValue(1.0); + +// m_Lut = 0; //new LookupTableBase(); + } /** @@ -65,7 +76,7 @@ SarRadiometricCalibrationFunction<TInputImage, TCoordRep> } /** - * + * Print */ template <class TInputImage, class TCoordRep> void @@ -75,23 +86,16 @@ SarRadiometricCalibrationFunction<TInputImage, TCoordRep> this->Superclass::PrintSelf(os, indent); } -/** - * - */ +/* Function: EvaluateAtIndex. This computes the required values for each pixel +* whose index is given in indexType argument. To convert index to point it uses +* InputImage::TransformIndexToPhysicalPoint(). IncidenceAngle and similar are +* computed based on this calculated point in SarParametricFunction */ template <class TInputImage, class TCoordRep> typename SarRadiometricCalibrationFunction<TInputImage, TCoordRep> ::OutputType SarRadiometricCalibrationFunction<TInputImage, TCoordRep> -::Evaluate(const PointType& point) const +::EvaluateAtIndex(const IndexType& index) const { - IndexType index; - this->GetInputImage()->TransformPhysicalPointToIndex(point, index); - - if (!this->GetInputImage()) - { - itkDebugMacro( <<"ERROR with GetInputImage()"); - return (itk::NumericTraits<OutputType>::max()); - } if (!this->IsInsideBuffer(index)) { @@ -99,21 +103,63 @@ SarRadiometricCalibrationFunction<TInputImage, TCoordRep> return (itk::NumericTraits<OutputType>::max()); } - FunctorType functor; + /* convert index to point */ + PointType point; + if (m_ApplyAntennaPatternGain || m_ApplyIncidenceAngleCorrection || m_ApplyRangeSpreadLossCorrection) + this->GetInputImage()->TransformIndexToPhysicalPoint( index, point); + + /** digitalNumber: + * The pixel is of type of std::complex and we use vcl_abs to get real + imaginary as RealType */ + + RealType digitalNumber = static_cast<RealType>(vcl_abs(this->GetInputImage()->GetPixel(index))); + RealType sigma = m_Scale * digitalNumber * digitalNumber; + + /** substract noise if enabled. */ if (m_EnableNoise) { - functor.SetNoise(static_cast<FunctorRealType>(m_Noise->Evaluate(point))); + sigma -= static_cast<RealType>(m_Noise->Evaluate(point)); + } + + /** Apply incidence angle correction if needed */ + if (m_ApplyIncidenceAngleCorrection) + { + sigma *= vcl_sin(static_cast<RealType>(m_IncidenceAngle->Evaluate(point))); } - functor.SetScale(m_Scale); - functor.SetAntennaPatternNewGain(static_cast<FunctorRealType>(m_AntennaPatternNewGain->Evaluate(point))); - functor.SetAntennaPatternOldGain(static_cast<FunctorRealType>(m_AntennaPatternOldGain->Evaluate(point))); - functor.SetIncidenceAngle(static_cast<FunctorRealType>(m_IncidenceAngle->Evaluate(point))); - functor.SetRangeSpreadLoss(static_cast<FunctorRealType>(m_RangeSpreadLoss->Evaluate(point))); - const RealType value = static_cast<RealType>(vcl_abs(this->GetInputImage()->GetPixel(index))); - RealType result = functor(value); + /** Apply old and new antenna pattern gain. */ + if (m_ApplyAntennaPatternGain) + { + sigma *= static_cast<RealType>(m_AntennaPatternNewGain->Evaluate(point)); + sigma /= static_cast<RealType>(m_AntennaPatternOldGain->Evaluate(point)); + } + + /** Apply range spread loss if needed. */ + if (m_ApplyRangeSpreadLossCorrection) + { + sigma *= static_cast<RealType>(m_RangeSpreadLoss->Evaluate(point)); + } + + /** Lookup value has effect on for some sensors which does not required the + * above values (incidence angle, rangespreadloss etc.. */ + if (m_ApplyLookupDataCorrection) + { + RealType lutVal = static_cast<RealType>(m_Lut->GetValue(index[0], index[1])); + sigma /= vcl_pow(lutVal, 2); + } + + /** rescaling factor has effect only with CosmoSkymed Products */ + if (m_ApplyRescalingFactor) + { + sigma /= m_RescalingFactor; + } + + + if(sigma < 0.0) + { + sigma = 0.0; + } - return static_cast<OutputType>(result); + return static_cast<OutputType>(sigma); } } // end namespace otb diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunctor.h b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunctor.h deleted file mode 100644 index db02de332b500272b71d92b3844816cf81d6f628..0000000000000000000000000000000000000000 --- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunctor.h +++ /dev/null @@ -1,161 +0,0 @@ -/*========================================================================= - - Program: ORFEO Toolbox - Language: C++ - Date: $Date$ - Version: $Revision$ - - - Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. - See OTBCopyright.txt for details. - - - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - -#ifndef __otbSarRadiometricCalibrationFunctor_h -#define __otbSarRadiometricCalibrationFunctor_h - -#include "otbMath.h" -#include "itkNumericTraits.h" - -namespace otb -{ - -namespace Functor -{ -/** - * \class SarRadiometricCalibrationFunctor - * \brief Compute the backscatter value. - * \f$ \sigma^{0} = (scale * DN^{2} + offset) * sin( \theta_{inc}) * OldGain / NewGain * RangeSpreadLoss \f$ - * - * - * \ingroup OTBSARCalibration - */ -template<class TInput, class TOutput> -class ITK_EXPORT SarRadiometricCalibrationFunctor -{ -public: - typedef TInput InputType; - typedef TOutput OutputType; - typedef typename itk::NumericTraits<InputType>::AbsType RealType; - - SarRadiometricCalibrationFunctor() - { - m_Noise = 0.0; - m_Scale = 1.0; - m_IncidenceAngle = CONST_PI_2; - m_AntennaPatternOldGain = 1.0; - m_AntennaPatternNewGain = 1.0; - m_RangeSpreadLoss = 1.0; - }; - - ~SarRadiometricCalibrationFunctor(){}; - - inline TOutput operator ()(const TInput& value) const - { - RealType digitalNumber = static_cast<RealType> (vcl_abs(value)); - RealType sigma; - - sigma = m_Scale * (digitalNumber * digitalNumber - m_Noise); - sigma *= vcl_sin(m_IncidenceAngle); - sigma *= m_AntennaPatternOldGain; - sigma /= m_AntennaPatternNewGain; - sigma *= m_RangeSpreadLoss; - - if(sigma < 0.0) - { - sigma = 0.0; - } - - return static_cast<OutputType>(sigma); - } - - /** Set offset method */ - void SetNoise(RealType value) - { - m_Noise = value; - } - - /** Get offset method */ - RealType GetNoise() const - { - return m_Noise; - } - - /** Set scale method */ - void SetScale(RealType value) - { - m_Scale = value; - } - - /** Get scale method */ - RealType GetScale() const - { - return m_Scale; - } - - /** Set antennaPatternNewGain method */ - void SetAntennaPatternNewGain(RealType value) - { - m_AntennaPatternNewGain = value; - } - - /** Get antennaPatternNewGain method */ - RealType GetAntennaPatternNewGain() const - { - return m_AntennaPatternNewGain; - } - - /** Set antennaPatternOldGain method */ - void SetAntennaPatternOldGain(RealType value) - { - m_AntennaPatternOldGain = value; - } - - /** Get antennaPatternOldGain method */ - RealType GetAntennaPatternOldGain() const - { - return m_AntennaPatternOldGain; - } - - /** Set incidenceAngle method */ - void SetIncidenceAngle(RealType value) - { - m_IncidenceAngle = value; - } - - /** Get incidenceAngle method */ - RealType GetIncidenceAngle() const - { - return m_IncidenceAngle; - } - - /** Set rangeSpreadLoss method */ - void SetRangeSpreadLoss(RealType value) - { - m_RangeSpreadLoss = value; - } - - /** Get scale method */ - RealType GetRangeSpreadLoss() const - { - return m_RangeSpreadLoss; - } - -private: - RealType m_Noise; - RealType m_Scale; - RealType m_AntennaPatternNewGain; - RealType m_AntennaPatternOldGain; - RealType m_IncidenceAngle; - RealType m_RangeSpreadLoss; -}; -} - -} - -#endif diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.h b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.h index 1212e9ae682de9b3f46e885d24efee34ebef12ba..6e3e962f52991faf6dbd2e54eb7df4859f5b3111 100644 --- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.h +++ b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.h @@ -28,9 +28,31 @@ namespace otb { /** \class SarRadiometricCalibrationToImageFilter - * \brief Evaluates the SarRadiometricCalibrationFunction onto a source image + * \brief Evaluates the SarRadiometricCalibrationFunction onto a source image + * The BeforeThreadedGenerateData create an SarIMI from + * input metadatadictionary. It will then reads Scale, Noise, + * Old antenna pattern gain, New antenna pattern gain, rangespreadloss, + * incidence angle. All these are set to the imageFunction used to compute the + * backscatter value. + * + * Noise, Antenna pattern gain (old && new), range spread loss, incidence angle + * data members used in this class are all instances of SarPrametricFunction + * class. Each have a Evaluate() method and a special + * EvaluateParametricCoefficient() which computes the actual value. + * + * OTB 5.2.0 - added two more values, Rescaling factor and lookupdata from IMI + * to have the generic equation form. The improvement of SarCalibation is + * discussed in jira story #863 + * * The function has to inherit from itkImageFunction + * See Also: SarParametricFunction, SarCalibrationLookupBase + * The equation for computaion is evalue in otbSarRadiometricCalibationFunctor + * class. Below lised are the references used to do the calibation of respective + * products. Retreived on 08-Sept-2015, 12:26:30 + * Sentinel1 - https://sentinel.esa.int/web/sentinel/sentinel-1-sar-wiki/-/wiki/Sentinel%20One/Application+of+Radiometric+Calibration+LUT + * Radarsat2 - http://gs.mdacorporation.com/products/sensor/radarsat2/RS2_Product_Description.pdf + * CosmoSkymed - http://www.e-geos.it/products/pdf/COSMO-SkyMed-Image_Calibration.pdf * * \ingroup ImageFilters * @@ -76,20 +98,37 @@ public: typedef typename FunctionType::ParametricFunctionConstPointer ParametricFunctionConstPointer; typedef typename FunctionType::ParametricFunctionType ParametricFunctionType; + + /** Enable/disable the noise flag in SarRadiometricCalibrationFunction */ void SetEnableNoise(bool inArg) { this->GetFunction()->SetEnableNoise(inArg); } + + itkSetMacro(LookupSelected, short); + itkGetConstMacro(LookupSelected, short); + protected: + /** Default ctor */ SarRadiometricCalibrationToImageFilter(); + + /** Empty, default virtual dtor */ virtual ~SarRadiometricCalibrationToImageFilter() {} + /** Generate output information */ + virtual void GenerateOutputInformation(); + /** Update the function list and input parameters*/ virtual void BeforeThreadedGenerateData(); + private: + SarRadiometricCalibrationToImageFilter(const Self &); //purposely not implemented void operator =(const Self&); //purposely not implemented + + short m_LookupSelected; + }; } // end namespace otb diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.txx b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.txx index 15b09c7fd73a1381545b48a64bcd16593fd24b38..7e69331710ab4361fc64f9c38f2eb9aa0191a9c1 100644 --- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.txx +++ b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.txx @@ -22,8 +22,8 @@ #define __otbSarRadiometricCalibrationToImageFilter_txx #include "otbSarRadiometricCalibrationToImageFilter.h" - #include "otbSarImageMetadataInterfaceFactory.h" +#include "otbSarCalibrationLookupData.h" namespace otb { @@ -34,7 +34,36 @@ namespace otb template<class TInputImage, class TOutputImage> SarRadiometricCalibrationToImageFilter<TInputImage, TOutputImage> ::SarRadiometricCalibrationToImageFilter() +: m_LookupSelected(0) { + +} + +/*This method is called once from BeforeThreadedGenerateData(). Usage of this +* outside or without a call to BeforeThreadedGenerateData() is supposed to +* fail. */ +template<class TInputImage, class TOutputImage> +void +SarRadiometricCalibrationToImageFilter<TInputImage, TOutputImage> +::GenerateOutputInformation( ) +{ + Superclass::GenerateOutputInformation(); + + // Retrieving input/output pointers + InputImagePointer inputPtr = this->GetInput(); + + if (inputPtr.IsNull()) + { + itkExceptionMacro(<< "At least one input is missing." + << " Input is missing :" << inputPtr.GetPointer() ) + } + + OutputImagePointer outputPtr = this->GetOutput(); + if (outputPtr.IsNull()) + { + itkExceptionMacro(<< "At least one output is missing." + << " Output is missing :" << outputPtr.GetPointer() ) + } } template<class TInputImage, class TOutputImage> @@ -45,60 +74,104 @@ SarRadiometricCalibrationToImageFilter<TInputImage, TOutputImage> // will SetInputImage on the function Superclass::BeforeThreadedGenerateData(); + /** cretate a SarImageMetadataInterface instance from + * GetMetaDataDictionary(). This will return the appropriate IMI depending on + * the Sensor information & co available in GetMetaDataDictionary() */ SarImageMetadataInterface::Pointer imageMetadataInterface = SarImageMetadataInterfaceFactory::CreateIMI( this->GetInput()->GetMetaDataDictionary()); + /** Get the SarRadiometricCalibrationFunction function instance. */ FunctionPointer function = this->GetFunction(); - function->SetScale(imageMetadataInterface->GetRadiometricCalibrationScale()); + /** check if there is a calibration lookupdata is available with the + * product. eg. Sentinel1. This means + * A. The computation of the backscatter is based on this lookup value which + * depends on the given product.* + * B. The other value such as antenna pattern gain, rangespread loss, incidence + * angle has no effect in calibration */ + + bool apply = imageMetadataInterface->HasCalibrationLookupDataFlag(); + /* Below lines will toggle the necessary flags which can help skip some + * computation. For example, if there is lookup value and ofcourse antenna + * pattern gain is not required. Even if we try to compute the value with + * SarParametricFuntion we get 1. This is the safe side. But as we are so sure + * we skip all those calls to EvaluateParametricCoefficient and also the + * Evalute(). For the function the value is 1 by default. + */ + function->SetApplyAntennaPatternGain(!apply); + function->SetApplyIncidenceAngleCorrection(!apply); + function->SetApplyRangeSpreadLossCorrection(!apply); + function->SetApplyRescalingFactor(!apply); + function->SetApplyLookupDataCorrection(apply); - ParametricFunctionPointer noise; - ParametricFunctionPointer antennaPatternNewGain; - ParametricFunctionPointer antennaPatternOldGain; - ParametricFunctionPointer incidenceAngle; - ParametricFunctionPointer rangeSpreadLoss; - - noise = function->GetNoise(); - noise->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationNoise()); - noise->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationNoisePolynomialDegree()); - noise->EvaluateParametricCoefficient(); - - antennaPatternNewGain = function->GetAntennaPatternNewGain(); - antennaPatternNewGain->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternNewGain()); - antennaPatternNewGain->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternNewGainPolynomialDegree()); - antennaPatternNewGain->EvaluateParametricCoefficient(); - - antennaPatternOldGain = function->GetAntennaPatternOldGain(); - antennaPatternOldGain->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternOldGain()); - antennaPatternOldGain->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternOldGainPolynomialDegree()); - antennaPatternOldGain->EvaluateParametricCoefficient(); - - incidenceAngle = function->GetIncidenceAngle(); - incidenceAngle->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle()); - - typename ParametricFunctionType::PointType point; - point.Fill(0); - typename ParametricFunctionType::PointSetType::PixelType pointValue; - pointValue = itk::NumericTraits<typename ParametricFunctionType::PointSetType::PixelType>::Zero; - unsigned int nbRecords = imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle()->GetNumberOfPoints(); - - // Fill the linear system - for (unsigned int i = 0; i < nbRecords; ++i) - { - imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle()->GetPoint(i, &point); - imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle()->GetPointData(i, &pointValue); - } - incidenceAngle->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationIncidenceAnglePolynomialDegree()); - - incidenceAngle->EvaluateParametricCoefficient(); - rangeSpreadLoss = function->GetRangeSpreadLoss(); - rangeSpreadLoss->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationRangeSpreadLoss()); - rangeSpreadLoss->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationRangeSpreadLossPolynomialDegree()); - rangeSpreadLoss->EvaluateParametricCoefficient(); + function->SetScale(imageMetadataInterface->GetRadiometricCalibrationScale()); + /* Compute noise if enabled */ + if( function->GetEnableNoise()) + { + ParametricFunctionPointer noise; + noise = function->GetNoise(); + noise->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationNoise()); + noise->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationNoisePolynomialDegree()); + noise->EvaluateParametricCoefficient(); + } + + /* Compute old and new antenna pattern gain */ + if(function->GetApplyAntennaPatternGain()) + { + ParametricFunctionPointer antennaPatternNewGain; + antennaPatternNewGain = function->GetAntennaPatternNewGain(); + antennaPatternNewGain->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternNewGain()); + antennaPatternNewGain->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternNewGainPolynomialDegree()); + antennaPatternNewGain->EvaluateParametricCoefficient(); + + ParametricFunctionPointer antennaPatternOldGain; + antennaPatternOldGain = function->GetAntennaPatternOldGain(); + antennaPatternOldGain->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternOldGain()); + antennaPatternOldGain->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternOldGainPolynomialDegree()); + antennaPatternOldGain->EvaluateParametricCoefficient(); + } + + /* Compute incidence angle */ + if (function->GetApplyIncidenceAngleCorrection()) + { + ParametricFunctionPointer incidenceAngle; + incidenceAngle = function->GetIncidenceAngle(); + incidenceAngle->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle()); + incidenceAngle->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationIncidenceAnglePolynomialDegree()); + incidenceAngle->EvaluateParametricCoefficient(); + } + + /* Compute Range spread Loss */ + if (function->GetApplyRangeSpreadLossCorrection()) + { + ParametricFunctionPointer rangeSpreadLoss; + rangeSpreadLoss = function->GetRangeSpreadLoss(); + rangeSpreadLoss->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationRangeSpreadLoss()); + rangeSpreadLoss->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationRangeSpreadLossPolynomialDegree()); + rangeSpreadLoss->EvaluateParametricCoefficient(); + } + + /** Get the lookupdata instance. unlike the all the above this is not a +* parametricFunction instance. But rather an internal class in IMI called +* SarCalibrationLookupData. +* +*NOTE: As the computation of lookup data for sensors is not universal. One must +*provide a sub-class. +See Also: otbSentinel1ImageMetadataInterface, otbTerraSarImageMetadataInterface, +*otbRadarsat2ImageMetadataInterface */ + if (function->GetApplyLookupDataCorrection()) + { + function->SetCalibrationLookupData(imageMetadataInterface->GetCalibrationLookupData(this->GetLookupSelected())); + } + + /** This was introduced for cosmoskymed which required a rescaling factor */ + if (function->GetApplyRescalingFactor()) + { + function->SetRescalingFactor(imageMetadataInterface->GetRescalingFactor()); + } } - } // end namespace otb #endif diff --git a/Modules/Radiometry/SARCalibration/test/CMakeLists.txt b/Modules/Radiometry/SARCalibration/test/CMakeLists.txt index 0e3ddd573154ea1c3c393d1206cee83df23c20fc..1299faddd099e113089de1157ac54cdf97848e5b 100644 --- a/Modules/Radiometry/SARCalibration/test/CMakeLists.txt +++ b/Modules/Radiometry/SARCalibration/test/CMakeLists.txt @@ -127,6 +127,39 @@ otb_add_test(NAME raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWith 1000 1000 250 250 # Extract ) +#Sentinel-1 L1, SLC +otb_add_test(NAME raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_SENTINEL1 COMMAND otbSARCalibrationTestDriver + --compare-image ${EPSILON_12} + ${BASELINE}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_SENTINEL1_VV.tif + ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_SENTINEL1_VV.tif + otbSarRadiometricCalibrationToImageFilterWithComplexPixelTestWithoutNoise + LARGEINPUT{SENTINEL1/S1A_S6_SLC__1SSV_20150619T195043/measurement/s1a-s6-slc-vv-20150619t195043-20150619t195101-006447-00887d-001.tiff} + ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_SENTINEL1_VV.tif + 1100 1900 450 450 # Extract + ) + +#Radarsat2 +otb_add_test(NAME raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_RADARSAT2 COMMAND otbSARCalibrationTestDriver + --compare-image ${EPSILON_12} + ${BASELINE}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_RADARSAT2_HV.tif + ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_RADARSAT2_HV.tif + otbSarRadiometricCalibrationToImageFilterWithComplexPixelTestWithoutNoise + LARGEINPUT{RADARSAT2/ALTONA/Fine_Quad-Pol_Dataset/PK6621_DK406_FQ9_20080405_124900_HH_VV_HV_VH_SLC_Altona/imagery_HV.tif} + ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_RADARSAT2_HV.tif + 11 11 650 750 # Extract + ) + +#CosmoSkymed +otb_add_test(NAME raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_COSMOSKYMED COMMAND otbSARCalibrationTestDriver + --compare-image ${EPSILON_12} + ${BASELINE}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_COSMOSKYMED_HH.tif + ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_COSMOSKYMED_HH.tif + otbSarRadiometricCalibrationToImageFilterWithComplexPixelTestWithoutNoise + LARGEINPUT{RADARSAT2/ALTONA/Fine_Quad-Pol_Dataset/PK6621_DK406_FQ9_20080405_124900_HH_VV_HV_VH_SLC_Altona/imagery_HV.tif} + ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_COSMOSKYMED_HH.tif + 13 19 650 750 # Extract + ) + otb_add_test(NAME raTuSarBrightnessFunctorWithoutNoise COMMAND otbSARCalibrationTestDriver otbSarBrightnessFunctorWithoutNoise ) @@ -259,4 +292,3 @@ otb_add_test(NAME raTvSarBrightnessToImageFilter COMMAND otbSARCalibrationTestD ${TEMP}/raTvSarBrightnessToImageFilter_TSX_PANGKALANBUUN_HH.tif 1000 1000 250 250 # Extract ) -