Commit 64423db9 authored by Cédric Traizet's avatar Cédric Traizet
Browse files

ENH: implements otb::SarSensorModel::BurstExtraction (adapted from ossimplugins)

parent ec717872
......@@ -71,6 +71,21 @@ public:
std::pair<unsigned long, unsigned long>& samples,
bool onlyValidSample = false);
/**
* This method will perform an extration of one burst. It wil return the
* lines and samples to extract in the image file.
* \return true if the extraction operation succeeded. No changes is
* made to the object if the operation fails.
* \param burst_index Index of Burst.
* \param lines A container for the lines to keep in the
* standalone burst.
* \param samples A container for the samples to keep in the
* standalone burst.
*/
bool BurstExtraction(const unsigned int burst_index, std::pair<unsigned long,unsigned long> & lines,
std::pair<unsigned long,unsigned long> & samples, bool allPixels = false);
protected:
private:
......@@ -139,6 +154,9 @@ private:
Projection::GCPParam m_GCP;
SARParam m_SarParam;
TimeType m_FirstLineTime;
TimeType m_LastLineTime;
DurationType m_AzimuthTimeOffset;
double m_RangeTimeOffset; // Offset in seconds
......
......@@ -770,10 +770,9 @@ bool SarSensorModel::Deburst(std::vector<std::pair<unsigned long, unsigned long>
m_GCP.GCPs.swap(deburstGCPs);
// TODO: Adapt general metadata : theNearRangeTime, first_time_line, last_time_line
// redaptMedataAfterDeburst = true;
// theFirstLineTime = deburstBurst.azimuthStartTime;
// theLastLineTime = deburstBurst.azimuthStopTime;
m_FirstLineTime = deburstBurst.azimuthStartTime;
m_LastLineTime = deburstBurst.azimuthStopTime;
if (onlyValidSample)
m_SarParam.nearRangeTime += samples.first / m_SarParam.rangeSamplingRate;
......@@ -782,6 +781,129 @@ bool SarSensorModel::Deburst(std::vector<std::pair<unsigned long, unsigned long>
return true;
}
bool SarSensorModel::BurstExtraction(const unsigned int burst_index,
std::pair<unsigned long,unsigned long> & lines,
std::pair<unsigned long,unsigned long> & samples,
bool allPixels)
{
auto & burstRecords = m_SarParam.burstRecords;
if (burstRecords.empty())
{
return false;
}
// Check the single burst record case
if(burstRecords.size() == 1)
{
lines = {burstRecords.front().startLine, burstRecords.front().endLine};
return false;
}
if (allPixels)
{
samples = {0, m_SarParam.numberOfSamplesPerBurst - 1};
lines = {burst_index*m_SarParam.numberOfLinesPerBurst,
(burst_index+1)*m_SarParam.numberOfLinesPerBurst - 1};
//redaptMedataAfterDeburst = true;
m_FirstLineTime = burstRecords[burst_index].azimuthStartTime - (burstRecords[burst_index].startLine - lines.first)
* m_SarParam.azimuthTimeInterval;
m_LastLineTime = m_FirstLineTime + (lines.second - lines.first) * m_SarParam.azimuthTimeInterval;
// Clear the previous burst records
burstRecords.clear();
// Create the single burst
BurstRecord burst;
burst.startLine = 0;
burst.azimuthStartTime = m_FirstLineTime;
burst.endLine = lines.second - lines.first;
burst.azimuthStopTime = m_LastLineTime;
burst.startSample = 0;
burst.endSample = samples.second - samples.first;
burst.azimuthAnxTime = 0;
burstRecords.push_back(burst);
}
else
{
// Retrieve into TheBurstRecord, the required index
auto burstInd_Record = burstRecords[burst_index];
lines = {burstInd_Record.startLine, burstInd_Record.endLine};
samples = {burstInd_Record.startSample, burstInd_Record.endSample};
auto burstAzimuthStartTime = burstInd_Record.azimuthStartTime;
auto burstAzimuthStopTime = burstInd_Record.azimuthStopTime;
// Clear the previous burst records
burstRecords.clear();
// Create the single burst
BurstRecord oneBurst;
oneBurst.startLine = 0;
oneBurst.azimuthStartTime = burstAzimuthStartTime;
oneBurst.endLine = lines.second - lines.first;
oneBurst.azimuthStopTime = burstAzimuthStopTime;
oneBurst.startSample = 0;
oneBurst.endSample = samples.second - samples.first;
oneBurst.azimuthAnxTime = burstInd_Record.azimuthAnxTime;
burstRecords.push_back(oneBurst);
// Adapt general metadata : theNearRangeTime, first_time_line, last_time_line
//redaptMedataAfterDeburst = true;
m_FirstLineTime = oneBurst.azimuthStartTime;
m_LastLineTime = oneBurst.azimuthStopTime;
m_SarParam.nearRangeTime += samples.first / m_SarParam.rangeSamplingRate;
}
std::vector<GCP> oneBurstGCPs;
// Now move GCPs
for (auto const& token : m_GCP.GCPs)
{
auto currentGCP = token;
unsigned long gcpLine = std::floor(currentGCP.m_GCPY + 0.5);
unsigned long gcpSample = std::floor(currentGCP.m_GCPX + 0.5);
// Be careful about fractional part of GCPs
double fractionalLines = currentGCP.m_GCPY - gcpLine;
double fractionalSamples = currentGCP.m_GCPX - gcpSample;
// Gcp into valid samples and valid lines
unsigned long newSample = gcpSample;
bool samplesOk = false;
if (gcpSample >= samples.first && gcpSample <= samples.second)
{
samplesOk = true;
newSample -= samples.first; // Offset with first valid sample
}
unsigned long newLine = gcpLine;
bool linesOk = false;
if (gcpLine >= lines.first && gcpLine <= lines.second)
{
linesOk = true;
newLine -= lines.first; // Offset with first valid line
}
if(linesOk && samplesOk)
{
currentGCP.m_GCPY = newLine + fractionalLines;
currentGCP.m_GCPX = newSample + fractionalSamples;
oneBurstGCPs.push_back(currentGCP);
}
}
m_GCP.GCPs.swap(oneBurstGCPs);
return true;
}
bool SarSensorModel::ImageLineToDeburstLine(const std::vector<std::pair<unsigned long,unsigned long> >& lines,
unsigned long imageLine,
unsigned long & deburstLine) const
......
......@@ -68,13 +68,17 @@ BOOST_AUTO_TEST_CASE(SARDeburst)
imi->ReadSarParamAndGCPs(mds, sarParam, gcpParam);
otb::SarSensorModel model(productType, sarParam, gcpParam);
std::cout << "OTB Tests" << std::endl;
std::cout << "Deburst with OTB" << std::endl;
std::vector<std::pair<unsigned long, unsigned long> > deburstLines;
std::pair<unsigned long, unsigned long> deburstSamples;
std::cout << "Deburst with OTB" << std::endl;
{
otb::SarSensorModel model(productType, sarParam, gcpParam);
BOOST_TEST(model.Deburst(deburstLines, deburstSamples));
}
std::cout << "Deburst lines: ";
for (const auto & elem: deburstLines)
......@@ -83,11 +87,23 @@ BOOST_AUTO_TEST_CASE(SARDeburst)
}
std::cout << std::endl;
std::cout << "Deburst Samples: " << deburstSamples.first << " " << deburstSamples.second << std::endl;
std::cout << "Burst extraction" << std::endl;
unsigned int burstIndex = 3;
std::pair<unsigned long, unsigned long> burstExtractionLines;
std::pair<unsigned long, unsigned long> burstExtractionSamples;
bool allPixel = false;
{
otb::SarSensorModel model(productType, sarParam, gcpParam);
BOOST_TEST(model.BurstExtraction(burstIndex, burstExtractionLines, burstExtractionSamples, allPixel));
}
// the code below uses OssimPlugins to validate the results OTB (see ossimSentinel1ModelTest).
// TODO: generate baselines instead.
std::cout << "Deburst with OSSIM" << std::endl;
std::cout << "Ossim Tests" << std::endl;
std::auto_ptr<ossimProjection> projection
(ossimplugins::ossimPluginProjectionFactory::instance()->createProjection(annotationXml, 42));
if (!projection.get())
......@@ -95,7 +111,7 @@ BOOST_AUTO_TEST_CASE(SARDeburst)
throw std::runtime_error("Cannot read annotation file ("+annotationXml+"). Cannot create a projection from it.");
}
ossimplugins::ossimSentinel1Model * sensor = dynamic_cast<ossimplugins::ossimSentinel1Model*>(projection.get());
auto * sensor = dynamic_cast<ossimplugins::ossimSentinel1Model*>(projection.get());
if (!sensor)
{
throw std::runtime_error(
......@@ -103,9 +119,6 @@ BOOST_AUTO_TEST_CASE(SARDeburst)
}
ossimKeywordlist kwl;
sensor->saveState(kwl, "S1.");
sensor->loadState(kwl, "S1.");
std::vector<std::pair<unsigned long, unsigned long> > deburstLinesOssim;
std::pair<unsigned long, unsigned long> deburstSamplesOssim;
......@@ -128,4 +141,34 @@ BOOST_AUTO_TEST_CASE(SARDeburst)
&& std::equal(deburstLines.begin(), deburstLines.end(), deburstLinesOssim.begin()));
std::cout << "Burst extraction" << std::endl;
std::auto_ptr<ossimProjection> projection2
(ossimplugins::ossimPluginProjectionFactory::instance()->createProjection(annotationXml, 42));
auto * sensor2 = dynamic_cast<ossimplugins::ossimSentinel1Model*>(projection2.get());
if (!sensor2)
{
throw std::runtime_error(
"Unlike Expectations, the annotation file ("+annotationXml+") is not a Sentinel Annotation File");
}
std::pair<unsigned long, unsigned long> ossimBurstExtractionLines;
std::pair<unsigned long, unsigned long> ossimBurstExtractionSamples;
BOOST_TEST(sensor2->burstExtraction(burstIndex, ossimBurstExtractionLines, ossimBurstExtractionSamples, allPixel));
std::cout << "OTB : burst extraction lines " << burstExtractionLines.first << " "
<< burstExtractionLines.second << std::endl;
std::cout << "OTB : burst extraction samples " << burstExtractionSamples.first << " "
<< burstExtractionSamples.second << std::endl;
std::cout << "OSSIM : burst extraction lines " << ossimBurstExtractionLines.first << " "
<< ossimBurstExtractionLines.second << std::endl;
std::cout << "OSSIM : burst extraction samples " << ossimBurstExtractionSamples.first << " "
<< ossimBurstExtractionSamples.second << std::endl;
BOOST_CHECK(burstExtractionLines == ossimBurstExtractionLines);
BOOST_CHECK(burstExtractionSamples == ossimBurstExtractionSamples);
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment