OTB  9.0.0
Orfeo Toolbox
otbSarBurstExtractionImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbSarBurstExtractionImageFilter_hxx
22 #define otbSarBurstExtractionImageFilter_hxx
23 
25 
26 #include "otbSarSensorModel.h"
27 #include "itkImageScanlineIterator.h"
28 #include "itkImageScanlineConstIterator.h"
29 #include "itkImageRegionIterator.h"
30 #include "itkImageRegionConstIterator.h"
31 
32 namespace otb
33 {
34 // Constructor
35 template <class TImage>
36 SarBurstExtractionImageFilter<TImage>::SarBurstExtractionImageFilter() : m_LinesRecord(), m_SamplesRecord(), m_BurstIndex(0), m_AllPixels(false)
37 {
38 }
39 
40 // Needs to be re-implemented since size of output is modified
41 template <class TImage>
43 {
44  // Call superclass implementation
45  Superclass::GenerateOutputInformation();
46 
47  // Retrieve the input image pointer
48  const ImageType* inputPtr = this->GetInput();
49  ImageType* outputPtr = this->GetOutput();
50 
51  // Check that azimuth spacing has not been modified
52  if (std::abs(inputPtr->GetSignedSpacing()[1] - 1.) >= std::numeric_limits<double>::epsilon())
53  itkExceptionMacro("Can not perform deburst if input image azimuth spacing is not 1.");
54 
55  // Check that the azimuth sampling grid has not been modified
56  if (std::abs(inputPtr->GetOrigin()[1] - static_cast<long>(inputPtr->GetOrigin()[1]) - 0.5) >= std::numeric_limits<double>::epsilon())
57  itkExceptionMacro("Can not perform burst extraction if input image azimuth origin is not N.5");
58 
59  // Retrieve input image metadata
60  auto imd = inputPtr->GetImageMetadata();
61 
62  // Try to create a SarSensorModel
63  SarSensorModel sarSensorModel(imd);
64 
65  // Try to call the burst extraction function
66  bool burstExtractionOk = sarSensorModel.BurstExtraction(m_BurstIndex, m_LinesRecord, m_SamplesRecord, m_AllPixels);
67 
68  if (!burstExtractionOk)
69  itkExceptionMacro(<< "Could not extract Burst from input image");
70 
71  sarSensorModel.UpdateImageMetadata(imd);
72 
73  // Compute the actual lines to remove
74  typename ImageType::RegionType largestPossibleRegion = this->GetInput()->GetLargestPossibleRegion();
75  typename ImageType::PointType origin = this->GetInput()->GetOrigin();
76 
77  // Move origin and size (if necessary)
78  long originOffset_samples = static_cast<long>(this->GetInput()->GetOrigin()[0] - 0.5);
79  long originOffset_lines = static_cast<long>(this->GetInput()->GetOrigin()[1] - 0.5);
80  unsigned long outputOriginSample = 0;
81  unsigned long outputOriginLine = 0;
82 
83  typename ImageType::SizeType burstSize = largestPossibleRegion.GetSize();
84 
85  if (static_cast<int>(m_SamplesRecord.first) > originOffset_samples)
86  {
87  outputOriginSample = 0;
88  }
89  else
90  {
91  outputOriginSample = originOffset_samples - static_cast<int>(m_SamplesRecord.first);
92  }
93 
94  if (static_cast<int>(m_LinesRecord.first) > originOffset_lines)
95  {
96  outputOriginLine = 0;
97  }
98  else
99  {
100  outputOriginLine = originOffset_lines - static_cast<int>(m_LinesRecord.first);
101  }
102 
103  long firstOutSample = static_cast<long>(std::max(static_cast<long>(m_SamplesRecord.first), originOffset_samples));
104  long secondOutSample =
105  static_cast<long>(std::min(static_cast<long>(m_SamplesRecord.second), static_cast<long>(largestPossibleRegion.GetSize()[0] + originOffset_samples - 1)));
106 
107  long firstOutLine = static_cast<long>(std::max(static_cast<long>(m_LinesRecord.first), originOffset_lines));
108  long secondOutLine =
109  static_cast<long>(std::min(static_cast<long>(m_LinesRecord.second), static_cast<long>(largestPossibleRegion.GetSize()[1] + originOffset_lines - 1)));
110 
111  burstSize[0] = secondOutSample - firstOutSample + 1;
112  burstSize[1] = secondOutLine - firstOutLine + 1;
113 
114  origin[0] = 0.5 + outputOriginSample;
115  origin[1] = 0.5 + outputOriginLine;
116 
117  outputPtr->SetOrigin(origin);
118 
119  // Set largest possible region
120  typename ImageType::RegionType outputLargestPossibleRegion = largestPossibleRegion;
121  largestPossibleRegion.SetSize(burstSize);
122  outputPtr->SetLargestPossibleRegion(largestPossibleRegion);
123 
124  imd.Add(MDNum::NumberOfLines, burstSize[1]);
125  imd.Add(MDNum::NumberOfColumns, burstSize[0]);
126 
127  if (m_AllPixels)
128  {
129  imd.Add("invalid_pixels", "yes");
130  }
131  else
132  {
133  imd.Add("invalid_pixels", "no");
134  }
135 
136  // Update the output image metadata
137  outputPtr->SetImageMetadata(imd);
138 }
139 
140 template <class TImage>
143 {
144  RegionType inputRegion = outputRegion;
145 
146  typename RegionType::IndexType index = inputRegion.GetIndex();
147 
148  long originOffset = static_cast<long>(this->GetInput()->GetOrigin()[1] - 0.5);
149  long originOffset_samples = static_cast<long>(this->GetInput()->GetOrigin()[0] - 0.5);
150 
151  if (static_cast<int>(m_SamplesRecord.first) > originOffset_samples)
152  {
153  index[0] += m_SamplesRecord.first - originOffset_samples;
154  }
155  if (static_cast<int>(m_LinesRecord.first) > originOffset)
156  {
157  index[1] += m_LinesRecord.first - originOffset;
158  }
159 
160  inputRegion.SetIndex(index);
161 
162  return inputRegion;
163 }
164 
165 
166 // Needs to be re-implemented since size of output is modified
167 template <class TImage>
169 {
170  RegionType outputRequestedRegion = this->GetOutput()->GetRequestedRegion();
171  RegionType inputRequestedRegion = OutputRegionToInputRegion(outputRequestedRegion);
172 
173  ImageType* inputPtr = const_cast<ImageType*>(this->GetInput());
174 
175  inputPtr->SetRequestedRegion(inputRequestedRegion);
176 }
177 
178 
179 // Actual processing
180 template <class TImage>
181 void SarBurstExtractionImageFilter<TImage>::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType itkNotUsed(threadId))
182 {
183  // Compute corresponding input region
184  RegionType inputRegionForThread = OutputRegionToInputRegion(outputRegionForThread);
185 
186  itk::ImageRegionConstIterator<ImageType> inputIt(this->GetInput(), inputRegionForThread);
187  itk::ImageRegionIterator<ImageType> outputIt(this->GetOutput(), outputRegionForThread);
188 
189  inputIt.GoToBegin();
190  outputIt.GoToBegin();
191 
192  int linesRecordFirst = static_cast<int>(m_LinesRecord.first);
193  int linesRecordSecond = static_cast<int>(m_LinesRecord.second);
194  int samplesRecordFirst = static_cast<int>(m_SamplesRecord.first);
195  int samplesRecordSecond = static_cast<int>(m_SamplesRecord.second);
196 
197  while (!inputIt.IsAtEnd() && !outputIt.IsAtEnd())
198  {
199  typename ImageType::IndexType currentInputIndex = inputIt.GetIndex();
200  PointType currentInputPoint;
201  this->GetInput()->TransformIndexToPhysicalPoint(currentInputIndex, currentInputPoint);
202 
203  bool lineToKeep = false;
204  bool sampleToKeep = false;
205 
206  // Check lines
207  if (currentInputPoint[1] - 0.5 >= linesRecordFirst && currentInputPoint[1] - 0.5 <= linesRecordSecond)
208  {
209  lineToKeep = true;
210  }
211 
212  // Check samples
213  if (currentInputPoint[0] - 0.5 >= samplesRecordFirst && currentInputPoint[0] - 0.5 <= samplesRecordSecond)
214  {
215  sampleToKeep = true;
216  }
217 
218  // If ok, copy input pixel into output image
219  if (lineToKeep && sampleToKeep)
220  {
221  outputIt.Set(inputIt.Get());
222 
223  ++outputIt;
224  }
225 
226  ++inputIt;
227  }
228 }
229 
230 } // End namespace otb
231 
232 #endif
otb::SarBurstExtractionImageFilter::ThreadedGenerateData
virtual void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbSarBurstExtractionImageFilter.hxx:181
otb::SarSensorModel
Definition: otbSarSensorModel.h:36
otbSarSensorModel.h
otb::SarBurstExtractionImageFilter::ImageType
TImage ImageType
Definition: otbSarBurstExtractionImageFilter.h:59
otb::SarBurstExtractionImageFilter::GenerateInputRequestedRegion
virtual void GenerateInputRequestedRegion() override
Definition: otbSarBurstExtractionImageFilter.hxx:168
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otbSarBurstExtractionImageFilter.h
otb::MDNum::NumberOfColumns
@ NumberOfColumns
otb::SarBurstExtractionImageFilter::OutputRegionToInputRegion
RegionType OutputRegionToInputRegion(const RegionType &outputRegion) const
Definition: otbSarBurstExtractionImageFilter.hxx:142
otb::SarBurstExtractionImageFilter::PointType
ImageType::PointType PointType
Definition: otbSarBurstExtractionImageFilter.h:63
otb::SarBurstExtractionImageFilter::GenerateOutputInformation
virtual void GenerateOutputInformation() override
Definition: otbSarBurstExtractionImageFilter.hxx:42
otb::SarSensorModel::BurstExtraction
bool BurstExtraction(const unsigned int burst_index, std::pair< unsigned long, unsigned long > &lines, std::pair< unsigned long, unsigned long > &samples, bool allPixels=false)
otb::SarBurstExtractionImageFilter::SarBurstExtractionImageFilter
SarBurstExtractionImageFilter()
Definition: otbSarBurstExtractionImageFilter.hxx:36
otb::SarSensorModel::UpdateImageMetadata
void UpdateImageMetadata(ImageMetadata &imd)
otb::SarBurstExtractionImageFilter::RegionType
ImageType::RegionType RegionType
Definition: otbSarBurstExtractionImageFilter.h:62
otb::MDNum::NumberOfLines
@ NumberOfLines