OTB  6.1.0
Orfeo Toolbox
otbImageFittingPolygonListFilter.txx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2017 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 otbImageFittingPolygonListFilter_txx
22 #define otbImageFittingPolygonListFilter_txx
23 
27 
28 namespace otb
29 {
33 template <class TPath, class TImage>
36 {
37  this->SetNumberOfRequiredInputs(2);
38  this->SetNumberOfRequiredInputs(2);
39  m_Radius = 1;
40  m_NumberOfIterations = 1;
41 }
43 
44 template <class TPath, class TImage>
45 void
47 ::SetInputImage(const ImageType * image)
48 {
49  this->itk::ProcessObject::SetNthInput(1, const_cast<ImageType *>(image));
50 }
51 
52 template <class TPath, class TImage>
54 ::ImageType *
57 {
58  if (this->GetNumberOfInputs() < 1)
59  {
60  return ITK_NULLPTR;
61  }
62  return static_cast<const ImageType *>(this->itk::ProcessObject::GetInput(1));
63 }
64 
65 //FIXME
66 //There is an issue here with integer and continuous indexes
67 //maybe we should use the itk::LineConstIterator
68 template <class TPath, class TImage>
69 void
72 {
73  // I/O wiring
74  ImageConstPointerType inputImagePtr = this->GetInputImage();
75  const PathListType * inputPtr = this->GetInput();
76  PathListType * outputPtr = this->GetOutput();
77 
78  typename ImageType::RegionType regionLargest = inputImagePtr->GetLargestPossibleRegion();
79 
80  typedef itk::ImageRegionConstIteratorWithIndex<ImageType> NeighborhoodIteratorType;
81 
82  typename ImageType::SizeType size;
83  size[0] = 2 * m_Radius + 1;
84  size[1] = 2 * m_Radius + 1;
85  typename ImageType::RegionType region;
86  region.SetSize(size);
87  typename ImageType::IndexType start;
88 
89  //go through all the polygons in the list
90  IteratorType it = inputPtr->Begin();
91  while (it != inputPtr->End())
92  {
93  PathPointerType polygon = it.Get();
94  if (polygon->GetVertexList()->Size() > 2)
95  {
96  for (unsigned int iteration = 0; iteration < m_NumberOfIterations; ++iteration)
97  {
98  PathPointerType newPolygon = PathType::New();
99  VertexListConstIteratorType vertexIt = polygon->GetVertexList()->Begin();
100  //We are now going to go through all the vertex, we won't start to process
101  // first as we need to know the last one for that.
102  VertexType firstPoint = vertexIt.Value();
103  VertexType previousPoint = vertexIt.Value();
104  ++vertexIt;
105  VertexType currentPoint = vertexIt.Value();
106  ++vertexIt;
107  while (vertexIt != polygon->GetVertexList()->End())
108  {
109  VertexType nextPoint = vertexIt.Value();
113  {
114 
115  start[0] = static_cast<long int>(currentPoint[0] - m_Radius);
116  start[1] = static_cast<long int>(currentPoint[1] - m_Radius);
117  region.SetIndex(start);
118  region.Crop(inputImagePtr->GetLargestPossibleRegion());
119 
120  NeighborhoodIteratorType nIt(inputImagePtr, region);
121  double maxValue = 0.0;
122  VertexType maxPoint = currentPoint;
123  nIt.GoToBegin();
124  while (!nIt.IsAtEnd())
125  {
126  if (regionLargest.IsInside(nIt.GetIndex()))
127  {
128  VertexType middlePoint = static_cast<VertexType>(nIt.GetIndex());
129  double currentValue = computeValue(inputImagePtr, middlePoint, previousPoint, nextPoint);
130  if (currentValue > maxValue)
131  {
132  maxValue = currentValue;
133  maxPoint = middlePoint;
134  }
135  }
136  ++nIt;
137  }
138  currentPoint = maxPoint;
139  newPolygon->AddVertex(maxPoint);
140  }
143  ++vertexIt;
144  previousPoint = currentPoint;
145  currentPoint = nextPoint;
146 
147  }
148  //We now need to process the last and the first point
149 
150  VertexType nextPoint = firstPoint;
154  {
155  start[0] = static_cast<long int>(currentPoint[0] - m_Radius);
156  start[1] = static_cast<long int>(currentPoint[1] - m_Radius);
157  region.SetIndex(start);
159 
160  NeighborhoodIteratorType nIt(inputImagePtr, region);
161  double maxValue = 0.0;
162  VertexType maxPoint = currentPoint;
163  nIt.GoToBegin();
164 
165  while (!nIt.IsAtEnd())
166  {
167  if (regionLargest.IsInside(nIt.GetIndex()))
168  {
169  VertexType middlePoint = static_cast<VertexType>(nIt.GetIndex());
170  double currentValue = computeValue(inputImagePtr, middlePoint, previousPoint, nextPoint);
171  if (currentValue > maxValue)
172  {
173  maxValue = currentValue;
174  maxPoint = middlePoint;
175  }
176  }
177  ++nIt;
178  }
179  currentPoint = maxPoint;
180  newPolygon->AddVertex(maxPoint);
181  }
184  previousPoint = currentPoint;
185  currentPoint = firstPoint;
186  vertexIt = newPolygon->GetVertexList()->Begin();
187  nextPoint = vertexIt.Value();
188 
192  {
193 
194  start[0] = static_cast<long int>(currentPoint[0] - m_Radius);
195  start[1] = static_cast<long int>(currentPoint[1] - m_Radius);
196  region.SetIndex(start);
197 
198  NeighborhoodIteratorType nIt(inputImagePtr, region);
199  double maxValue = 0.0;
200  VertexType maxPoint = currentPoint;
201  nIt.GoToBegin();
202  while (!nIt.IsAtEnd())
203  {
204  if (regionLargest.IsInside(nIt.GetIndex()))
205  {
206  VertexType middlePoint = static_cast<VertexType>(nIt.GetIndex());
207  double currentValue = computeValue(inputImagePtr, middlePoint, previousPoint, nextPoint);
208  if (currentValue > maxValue)
209  {
210  maxValue = currentValue;
211  maxPoint = middlePoint;
212  }
213  }
214  ++nIt;
215  }
216  currentPoint = maxPoint;
217  newPolygon->AddVertex(maxPoint);
218  }
221  polygon = newPolygon; //prepare the next iteration
222  }
223  }
224 
225  outputPtr->PushBack(polygon);
226 
227  ++it;
228  } //going through the polygon list
229 }
230 
231 template <class TPath, class TImage>
232 double
234 ::computeValue(ImageConstPointerType image, VertexType middlePoint, VertexType previousPoint,
235  VertexType nextPoint) const
236 {
237  typedef typename ImageType::IndexType IndexType;
238  IndexType middleIndex;
239  IndexType previousIndex;
240  IndexType nextIndex;
241  middleIndex[0] = static_cast<long int>(middlePoint[0]);
242  middleIndex[1] = static_cast<long int>(middlePoint[1]);
243  previousIndex[0] = static_cast<long int>(previousPoint[0]);
244  previousIndex[1] = static_cast<long int>(previousPoint[1]);
245  nextIndex[0] = static_cast<long int>(nextPoint[0]);
246  nextIndex[1] = static_cast<long int>(nextPoint[1]);
247  double currentValue = 0.0;
248  unsigned int count = 0;
249  //compute for first segment
250  LineConstIteratorType itLineFirst(image, previousIndex, middleIndex);
251  while (!itLineFirst.IsAtEnd())
252  {
253  currentValue += itLineFirst.Get();
254  ++count;
255  ++itLineFirst;
256  }
257 
258  //compute for second segment
259  LineConstIteratorType itLineSecond(image, nextIndex, middleIndex);
260  while (!itLineSecond.IsAtEnd())
261  {
262  currentValue += itLineSecond.Get();
263  ++count;
264  ++itLineSecond;
265  }
266 
267  return currentValue / count;
268 }
269 
273 template <class TPath, class TImage>
274 void
276 ::PrintSelf(std::ostream& os, itk::Indent indent) const
277 {
278  Superclass::PrintSelf(os, indent);
279 }
280 
281 } // End namespace otb
282 #endif
itk::Size< Monteverdi_DIMENSION > SizeType
Definition: mvdTypes.h:146
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
Slightly deform polygon to reach higher enery from the image.
VertexListType::ConstIterator VertexListConstIteratorType
void SetSize(const SizeValueType val[VDimension])
itk::Index< Monteverdi_DIMENSION > IndexType
Definition: mvdTypes.h:142
DataObject * GetInput(const DataObjectIdentifierType &key)
const PixelType Get(void) const
virtual double computeValue(ImageConstPointerType image, VertexType middlePoint, VertexType previousPoint, VertexType nextPoint) const
virtual void SetNthInput(DataObjectPointerArraySizeType num, DataObject *input)