From 43ae9e413aaa8249c9992819a56392ae77643c71 Mon Sep 17 00:00:00 2001 From: Valentin Genin <valentin.genin@cnes.fr> Date: Tue, 10 Oct 2023 13:10:34 +0000 Subject: [PATCH] ENH: Adapt SARESD to otb V8 --- app/CMakeLists.txt | 8 +- app/otbSARESD.cxx | 15 ++- .../otbSARDopplerCentroidFreqImageFilter.h | 8 +- .../otbSARDopplerCentroidFreqImageFilter.txx | 120 +++++++++--------- ...eamingMeanPhaseAndAzimutShiftImageFilter.h | 13 +- 5 files changed, 79 insertions(+), 85 deletions(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index e8cd2e3..33046d1 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -85,10 +85,10 @@ OTB_CREATE_APPLICATION(NAME SARDeramp # LINK_LIBRARIES ${${otb-module}_LIBRARIES} # ) -# OTB_CREATE_APPLICATION(NAME SARESD -# SOURCES otbSARESD.cxx -# LINK_LIBRARIES ${${otb-module}_LIBRARIES} -# ) +OTB_CREATE_APPLICATION(NAME SARESD + SOURCES otbSARESD.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES} +) # OTB_CREATE_APPLICATION(NAME SARCorrelationRough # SOURCES otbSARCorrelationRough.cxx diff --git a/app/otbSARESD.cxx b/app/otbSARESD.cxx index 171a00c..7de4489 100644 --- a/app/otbSARESD.cxx +++ b/app/otbSARESD.cxx @@ -182,15 +182,15 @@ void DoExecute() override } // Check invalid Pixel Key - const bool inputWithInvalidPixels1 = InterfUpPtr->GetImageKeywordlist().HasKey("support_data.invalid_pixels") - && InterfUpPtr->GetImageKeywordlist().GetMetadataByKey("support_data.invalid_pixels") == "yes"; - const bool inputWithInvalidPixels2 = InterfLowPtr->GetImageKeywordlist().HasKey("support_data.invalid_pixels") - && InterfLowPtr->GetImageKeywordlist().GetMetadataByKey("support_data.invalid_pixels") == "yes"; + const bool inputWithInvalidPixels1 = InterfUpPtr->GetImageMetadata().Has("invalid_pixels") + && InterfUpPtr->GetImageMetadata()["invalid_pixels"] == "yes"; + const bool inputWithInvalidPixels2 = InterfLowPtr->GetImageMetadata().Has("invalid_pixels") + && InterfLowPtr->GetImageMetadata()["invalid_pixels"] == "yes"; if (inputWithInvalidPixels1!= inputWithInvalidPixels2) { // Throw an execption - otbAppLogFATAL(<< "Incoherency between input images (for support_data.invalid_pixels key)."); + otbAppLogFATAL(<< "Incoherency between input images (for invalid_pixels key)."); } @@ -199,7 +199,7 @@ void DoExecute() override std::pair<unsigned long,unsigned long> linesLow; std::pair<unsigned long,unsigned long> samplesUp; std::pair<unsigned long,unsigned long> samplesLow; - meanPhase->getOverlapLinesAndSamples(GetParameterComplexFloatImage("insar")->GetImageKeywordlist(), + meanPhase->getOverlapLinesAndSamples(GetParameterComplexFloatImage("insar")->GetImageMetadata(), linesUp, linesLow, samplesUp, samplesLow, burstindex, inputWithInvalidPixels1); @@ -340,7 +340,8 @@ void DoExecute() override // //////////// ESD Filter //////////// esdFilter->SetPhaseDiffMean(meanPhase->GetMean()); - double aziInterval = std::stod(InterfUpPtr->GetImageKeywordlist().GetMetadataByKey("support_data.line_time_interval")); + //double aziInterval = std::stod(InterfUpPtr->GetImageMetadata().GetMetadataByKey("line_time_interval")); + double aziInterval = boost::any_cast<const otb::SARParam&>(InterfUpPtr->GetImageMetadata()[otb::MDGeom::SAR]).azimuthTimeInterval.TotalSeconds(); esdFilter->SetAziTimeInt(aziInterval); //esdFilter->SetInput(subPhase->GetOutput()); esdFilter->SetInput1(dcfUp->GetOutput()); diff --git a/include/otbSARDopplerCentroidFreqImageFilter.h b/include/otbSARDopplerCentroidFreqImageFilter.h index 0f20ca2..b3bff31 100644 --- a/include/otbSARDopplerCentroidFreqImageFilter.h +++ b/include/otbSARDopplerCentroidFreqImageFilter.h @@ -28,8 +28,8 @@ #include "itkImageScanlineConstIterator.h" #include "itkImageScanlineIterator.h" -#include "otbImageKeywordlist.h" -#include "otbSarSensorModelAdapter.h" +#include "otbImageMetadata.h" +#include "otbSarSensorModel.h" #include "otbDateTime.h" @@ -165,8 +165,8 @@ protected: void BeforeThreadedGenerateData() ITK_OVERRIDE; - void getAllCoefs(ImageKeywordlist const& kwl, std::vector<FMRateRecordType> & FMRateRecords); - void getAllCoefs(ImageKeywordlist const& kwl, std::vector<DCFRecordType> & DCFRecords); + void getAllCoefs(ImageMetadata const& kwl, std::vector<FMRateRecordType> & FMRateRecords); + void getAllCoefs(ImageMetadata const& kwl, std::vector<DCFRecordType> & DCFRecords); long double applyFMRateCoefs(double index_sample); long double applyDCFCoefs(double index_sample); diff --git a/include/otbSARDopplerCentroidFreqImageFilter.txx b/include/otbSARDopplerCentroidFreqImageFilter.txx index 5837319..62604d1 100644 --- a/include/otbSARDopplerCentroidFreqImageFilter.txx +++ b/include/otbSARDopplerCentroidFreqImageFilter.txx @@ -28,7 +28,7 @@ #include "itkProgressReporter.h" #include "itkNumericTraitsPointPixel.h" -#include "otbSarSensorModelAdapter.h" +#include "otbSarSensorModel.h" #include <cmath> #include <algorithm> @@ -70,12 +70,12 @@ namespace otb template<class TImage> void SARDopplerCentroidFreqImageFilter< TImage > - ::getAllCoefs(ImageKeywordlist const& kwl, std::vector<FMRateRecordType> & FMRateRecords) + ::getAllCoefs(ImageMetadata const& kwl, std::vector<FMRateRecordType> & FMRateRecords) { char fmRatePrefix_[1024]; std::size_t nbLists(0); - nbLists = std::stoi(kwl.GetMetadataByKey("azimuthFmRate.azi_fm_rate_coef_nb_list")); + nbLists = std::stoi(kwl["azimuthFmRate.azi_fm_rate_coef_nb_list"]); std::string FM_PREFIX = "azimuthFmRate.azi_fm_rate_coef_list"; @@ -86,12 +86,12 @@ namespace otb const std::string FMPrefix(fmRatePrefix_, pos); FMRateRecordType fmRateRecord; - fmRateRecord.azimuthFMRateTime = otb::MetaData::ReadFormattedDate(kwl.GetMetadataByKey(FMPrefix+ - "azi_fm_rate_coef_time")); - fmRateRecord.coef0FMRate = std::stod(kwl.GetMetadataByKey(FMPrefix + "1.azi_fm_rate_coef")); - fmRateRecord.coef1FMRate = std::stod(kwl.GetMetadataByKey(FMPrefix + "2.azi_fm_rate_coef")); - fmRateRecord.coef2FMRate = std::stod(kwl.GetMetadataByKey(FMPrefix + "3.azi_fm_rate_coef")); - fmRateRecord.tau0FMRate = std::stod(kwl.GetMetadataByKey(FMPrefix + "slant_range_time")); + fmRateRecord.azimuthFMRateTime = otb::MetaData::ReadFormattedDate(kwl[FMPrefix+ + "azi_fm_rate_coef_time"]); + fmRateRecord.coef0FMRate = std::stod(kwl[FMPrefix + "1.azi_fm_rate_coef"]); + fmRateRecord.coef1FMRate = std::stod(kwl[FMPrefix + "2.azi_fm_rate_coef"]); + fmRateRecord.coef2FMRate = std::stod(kwl[FMPrefix + "3.azi_fm_rate_coef"]); + fmRateRecord.tau0FMRate = std::stod(kwl[FMPrefix + "slant_range_time"]); FMRateRecords.push_back(fmRateRecord); } @@ -100,12 +100,12 @@ namespace otb template<class TImage> void SARDopplerCentroidFreqImageFilter< TImage > - ::getAllCoefs(ImageKeywordlist const& kwl, std::vector<DCFRecordType> & DCFRecords) + ::getAllCoefs(ImageMetadata const& kwl, std::vector<DCFRecordType> & DCFRecords) { char dcfPrefix_[1024]; std::size_t nbLists(0); - nbLists = std::stoi(kwl.GetMetadataByKey("dopplerCentroid.dop_coef_nb_list")); + nbLists = std::stoi(kwl["dopplerCentroid.dop_coef_nb_list"]); std::string DCF_PREFIX = "dopplerCentroid.dop_coef_list"; @@ -116,12 +116,12 @@ namespace otb const std::string DCFPrefix(dcfPrefix_, pos); DCFRecordType dcfRecord; - dcfRecord.azimuthDCFTime = otb::MetaData::ReadFormattedDate(kwl.GetMetadataByKey(DCFPrefix + - "dop_coef_time")); - dcfRecord.coef0DCF = std::stod(kwl.GetMetadataByKey(DCFPrefix + "1.dop_coef")); - dcfRecord.coef1DCF = std::stod(kwl.GetMetadataByKey(DCFPrefix + "2.dop_coef")); - dcfRecord.coef2DCF = std::stod(kwl.GetMetadataByKey(DCFPrefix + "3.dop_coef")); - dcfRecord.tau0DCF = std::stod(kwl.GetMetadataByKey(DCFPrefix + "slant_range_time")); + dcfRecord.azimuthDCFTime = otb::MetaData::ReadFormattedDate(kwl[DCFPrefix + + "dop_coef_time"]); + dcfRecord.coef0DCF = std::stod(kwl[DCFPrefix + "1.dop_coef"]); + dcfRecord.coef1DCF = std::stod(kwl[DCFPrefix + "2.dop_coef"]); + dcfRecord.coef2DCF = std::stod(kwl[DCFPrefix + "3.dop_coef"]); + dcfRecord.tau0DCF = std::stod(kwl[DCFPrefix + "slant_range_time"]); DCFRecords.push_back(dcfRecord); } @@ -139,27 +139,28 @@ namespace otb ImagePointer inputPtr = const_cast< ImageType * >( this->GetInput() ); // Retrieve all polynomials - std::vector<FMRateRecordType> FMRateRecords; + std::vector<otb::AzimuthFmRate> FMRateRecords; - ImageKeywordlist inputKWL = inputPtr->GetImageKeywordlist(); + ImageMetadata inputKWL = inputPtr->GetImageMetadata(); - this->getAllCoefs(inputKWL, FMRateRecords); + //this->getAllCoefs(inputKWL, FMRateRecords); + FMRateRecords = boost::any_cast<const otb::SARParam&>(inputKWL[otb::MDGeom::SAR]).azimuthFmRates; - DurationType diffAziTimeMin(0); + DurationType diffAziTimeMin; unsigned int polySelected = 0; // Select one polynomial (with m_MidAziTime) for (unsigned int i = 0; i < FMRateRecords.size(); i++) { // Difference between midAziTime and aziTime of the current polynomial - DurationType diffAziTime(0); - if (m_MidAziTime > FMRateRecords[i].azimuthFMRateTime) + DurationType diffAziTime; + if (m_MidAziTime > FMRateRecords[i].azimuthTime) { - diffAziTime = DurationType(m_MidAziTime - FMRateRecords[i].azimuthFMRateTime); + diffAziTime = DurationType(m_MidAziTime - FMRateRecords[i].azimuthTime); } else { - diffAziTime = DurationType(FMRateRecords[i].azimuthFMRateTime - m_MidAziTime); + diffAziTime = DurationType(FMRateRecords[i].azimuthTime - m_MidAziTime); } if (diffAziTime < diffAziTimeMin || i == 0) @@ -170,10 +171,10 @@ namespace otb } // Assign m_FM_C0, m_FM_C1, m_FM_C2, m_FM_Tau0 - m_FM_C0 = FMRateRecords[polySelected].coef0FMRate; - m_FM_C1 = FMRateRecords[polySelected].coef1FMRate; - m_FM_C2 = FMRateRecords[polySelected].coef2FMRate; - m_FM_Tau0 = FMRateRecords[polySelected].tau0FMRate; + m_FM_C0 = FMRateRecords[polySelected].azimuthFmRatePolynomial[0]; + m_FM_C1 = FMRateRecords[polySelected].azimuthFmRatePolynomial[1]; + m_FM_C2 = FMRateRecords[polySelected].azimuthFmRatePolynomial[2]; + m_FM_Tau0 = FMRateRecords[polySelected].t0; return true; } @@ -190,27 +191,28 @@ namespace otb ImagePointer inputPtr = const_cast< ImageType * >( this->GetInput() ); // Retrieve all polynomials - std::vector<DCFRecordType> DCFRecords; + std::vector<otb::DopplerCentroid> DCFRecords; - ImageKeywordlist inputKWL = inputPtr->GetImageKeywordlist(); + ImageMetadata inputKWL = inputPtr->GetImageMetadata(); - this->getAllCoefs(inputKWL, DCFRecords); + // this->getAllCoefs(inputKWL, DCFRecords); + DCFRecords = boost::any_cast<const otb::SARParam&>(inputKWL[otb::MDGeom::SAR]).dopplerCentroids; - DurationType diffAziTimeMin(0); + DurationType diffAziTimeMin; unsigned int polySelected = 0; // Select one polynomial (with m_MidAziTime) for (unsigned int i = 0; i < DCFRecords.size(); i++) { // Difference between midAziTime and aziTime of the current polynomial - DurationType diffAziTime(0); - if (m_MidAziTime > DCFRecords[i].azimuthDCFTime) + DurationType diffAziTime; + if (m_MidAziTime > DCFRecords[i].azimuthTime) { - diffAziTime = DurationType(m_MidAziTime - DCFRecords[i].azimuthDCFTime); + diffAziTime = DurationType(m_MidAziTime - DCFRecords[i].azimuthTime); } else { - diffAziTime = DurationType(DCFRecords[i].azimuthDCFTime - m_MidAziTime); + diffAziTime = DurationType(DCFRecords[i].azimuthTime - m_MidAziTime); } if (diffAziTime < diffAziTimeMin || i == 0) @@ -221,10 +223,10 @@ namespace otb } // Assign m_FM_C0, m_FM_C1, m_FM_C2, m_FM_Tau0 - m_DCF_C0 = DCFRecords[polySelected].coef0DCF; - m_DCF_C1 = DCFRecords[polySelected].coef1DCF; - m_DCF_C2 = DCFRecords[polySelected].coef2DCF; - m_DCF_Tau0 = DCFRecords[polySelected].tau0DCF; + m_DCF_C0 = DCFRecords[polySelected].dopCoef[0]; + m_DCF_C1 = DCFRecords[polySelected].dopCoef[1]; + m_DCF_C2 = DCFRecords[polySelected].dopCoef[2]; + m_DCF_Tau0 = DCFRecords[polySelected].t0; return true; } @@ -292,42 +294,38 @@ namespace otb // Get input ImagePointer inputPtr = const_cast< ImageType * >( this->GetInput() ); - // Choose KeyWordList - ImageKeywordlist inputKWL = inputPtr->GetImageKeywordlist(); + // Choose Metadata + ImageMetadata inputKWL = inputPtr->GetImageMetadata(); // Check version of header/kwl (at least 3) - int headerVersion = std::stoi(inputKWL.GetMetadataByKey("header.version")); + // int headerVersion = std::stoi(inputKWL.GetMetadataByKey("header.version")); - if (headerVersion < 3) - { - itkExceptionMacro(<<"Header version is inferior to 3. Please Upgrade your geom file"); - } + // if (headerVersion < 3) + // { + // itkExceptionMacro(<<"Header version is inferior to 3. Please Upgrade your geom file"); + // } // Get some metadata - double aziSteeringRate = std::stod(inputKWL.GetMetadataByKey("support_data.azimuth_steering_rate")); + double aziSteeringRate = boost::any_cast<const otb::SARParam&>(inputKWL[otb::MDGeom::SAR]).azimuthSteeringRate; // Conversion to radians per seconds aziSteeringRate *= (M_PI/180); - m_FirstAziTime = otb::MetaData::ReadFormattedDate((inputKWL.GetMetadataByKey("support_data.first_line_time"))); - m_FirstRangeTime = std::stod(inputKWL.GetMetadataByKey("support_data.slant_range_to_first_pixel")); + m_FirstAziTime = inputKWL[MDTime::AcquisitionStartTime]; + m_FirstRangeTime = boost::any_cast<const otb::SARParam&>(inputKWL[otb::MDGeom::SAR]).nearRangeTime; - m_AziTimeInt = std::stod(inputKWL.GetMetadataByKey("support_data.line_time_interval")); - m_RangeSamplingRate = std::stod(inputKWL.GetMetadataByKey("support_data.range_sampling_rate")); + m_AziTimeInt = boost::any_cast<const otb::SARParam&>(inputKWL[otb::MDGeom::SAR]).azimuthTimeInterval.TotalSeconds(); + m_RangeSamplingRate = boost::any_cast<const otb::SARParam&>(inputKWL[otb::MDGeom::SAR]).rangeSamplingRate; - double radarFrequency = std::stod(inputKWL.GetMetadataByKey("support_data.radar_frequency")); + double radarFrequency = inputKWL[MDNum::RadarFrequency]; - int nbLineBurst = std::stod(inputKWL.GetMetadataByKey("support_data.geom.bursts.number_lines_per_burst")); - int nbSampleBurst = std::stod(inputKWL.GetMetadataByKey("support_data.geom.bursts.number_samples_per_burst")); + int nbLineBurst = boost::any_cast<const otb::SARParam&>(inputKWL[otb::MDGeom::SAR]).numberOfLinesPerBurst; + int nbSampleBurst = boost::any_cast<const otb::SARParam&>(inputKWL[otb::MDGeom::SAR]).numberOfSamplesPerBurst; // Estimation m_Ks m_LineAtMidBurst = nbLineBurst/2.; m_MidAziTime = m_FirstAziTime + DurationType::Seconds(m_AziTimeInt * m_LineAtMidBurst); // Try to create a SarSensorModelAdapter - SarSensorModelAdapter::Pointer sarSensorModel = SarSensorModelAdapter::New(); - bool loadOk = sarSensorModel->LoadState(inputKWL); - - if(!loadOk || !sarSensorModel->IsValidSensorModel()) - itkExceptionMacro(<<"Input image does not contain a valid SAR sensor model."); + SarSensorModel* sarSensorModel = new SarSensorModel(inputKWL); Point3DType satpos, satvel; diff --git a/include/otbSARStreamingMeanPhaseAndAzimutShiftImageFilter.h b/include/otbSARStreamingMeanPhaseAndAzimutShiftImageFilter.h index 36b9ad7..9f8294d 100644 --- a/include/otbSARStreamingMeanPhaseAndAzimutShiftImageFilter.h +++ b/include/otbSARStreamingMeanPhaseAndAzimutShiftImageFilter.h @@ -27,8 +27,8 @@ #include "itkSimpleDataObjectDecorator.h" #include "otbPersistentFilterStreamingDecorator.h" -#include "otbSarSensorModelAdapter.h" -#include "otbImageKeywordlist.h" +#include "otbSarSensorModel.h" +#include "otbImageMetadata.h" #include <complex> #include <cmath> @@ -301,7 +301,7 @@ public: return mean; } - bool getOverlapLinesAndSamples(ImageKeywordlist SLCImageKWL, + bool getOverlapLinesAndSamples(ImageMetadata SLCImageKWL, std::pair<unsigned long,unsigned long> & linesUp, std::pair<unsigned long,unsigned long> & linesLow, std::pair<unsigned long,unsigned long> & samplesUp, @@ -310,13 +310,8 @@ public: bool inputWithInvalidPixels) { // Try to create a SarSensorModelAdapter - SarSensorModelAdapter::Pointer sarSensorModel = SarSensorModelAdapter::New(); + SarSensorModel* sarSensorModel = new SarSensorModel(SLCImageKWL); - bool loadOk = sarSensorModel->LoadState(SLCImageKWL); - - if(!loadOk || !sarSensorModel->IsValidSensorModel()) - itkExceptionMacro(<<"Input image does not contain a valid SAR sensor model."); - // Try to call the deburstAndConcatenate function bool deburstAndConcatenateOk = sarSensorModel->Overlap(linesUp, linesLow, samplesUp, samplesLow, -- GitLab