OTB  9.0.0
Orfeo Toolbox
otbStreamingImageToOGRLayerSegmentationFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
4  *
5  * This file is part of Orfeo Toolbox
6  *
7  * https://www.orfeo-toolbox.org/
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifndef otbStreamingImageToOGRLayerSegmentationFilter_hxx
23 #define otbStreamingImageToOGRLayerSegmentationFilter_hxx
24 
26 
28 #include "itkAffineTransform.h"
29 
30 #include "otbStopwatch.h"
31 #include "otbMacro.h"
32 #include <cassert>
33 
34 namespace otb
35 {
36 
37 template <class TImageType, class TSegmentationFilter>
39  : m_TileMaxLabel(0),
40  m_StartLabel(0),
41  m_SegmentationFilter(),
42  m_FieldName("DN"),
43  m_Use8Connected(false),
44  m_FilterSmallObject(false),
45  m_MinimumObjectSize(1),
46  m_Simplify(false),
47  m_SimplificationTolerance(0.3)
48 {
49  this->SetNumberOfRequiredInputs(2);
50  this->SetNumberOfRequiredInputs(1);
51  m_SegmentationFilter = SegmentationFilterType::New();
52  m_TileNumber = 1;
53 }
54 
55 template <class TImageType, class TSegmentationFilter>
57 {
58 }
59 
60 template <class TImageType, class TSegmentationFilter>
62 {
63  this->itk::ProcessObject::SetNthInput(1, const_cast<LabelImageType*>(mask));
64 }
65 
66 template <class TImageType, class TSegmentationFilter>
69 {
70  return static_cast<const LabelImageType*>(this->itk::ProcessObject::GetInput(1));
71 }
72 
73 
74 template <class TImageType, class TSegmentationFilter>
77 {
78  otbMsgDebugMacro(<< "tile number : " << m_TileNumber);
79  ++m_TileNumber;
80 
81  // Apply an ExtractImageFilter to avoid problems with filters asking for the LargestPossibleRegion
82  typedef itk::ExtractImageFilter<InputImageType, InputImageType> ExtractImageFilterType;
83  typename ExtractImageFilterType::Pointer extract = ExtractImageFilterType::New();
84  extract->SetInput(this->GetInput());
85  extract->SetExtractionRegion(this->GetInput()->GetRequestedRegion());
86  extract->Update();
87 
88  // WARNING: itk::ExtractImageFilter does not copy the MetadataDictionary
89  extract->GetOutput()->SetMetaDataDictionary(this->GetInput()->GetMetaDataDictionary());
90 
91  const unsigned int labelImageIndex = LabeledOutputAccessor<SegmentationFilterType>::LabeledOutputIndex;
92 
93  typename LabelImageToOGRDataSourceFilterType::Pointer labelImageToOGRDataFilter = LabelImageToOGRDataSourceFilterType::New();
94 
96  m_SegmentationFilter->SetInput(extract->GetOutput());
97  m_SegmentationFilter->UpdateLargestPossibleRegion();
98 
99  otbMsgDebugMacro(<< "segmentation took " << chrono.GetElapsedMilliseconds() / 1000 << " sec");
100 
101  chrono.Restart();
102  typename LabelImageType::ConstPointer inputMask = this->GetInputMask();
103  if (!inputMask.IsNull())
104  {
105  // Apply an ExtractImageFilter to avoid problems with filters asking for the LargestPossibleRegion
106  typedef itk::ExtractImageFilter<LabelImageType, LabelImageType> ExtractLabelImageFilterType;
107  typename ExtractLabelImageFilterType::Pointer maskExtract = ExtractLabelImageFilterType::New();
108  maskExtract->SetInput(this->GetInputMask());
109  maskExtract->SetExtractionRegion(this->GetInput()->GetRequestedRegion());
110  maskExtract->Update();
111  // WARNING: itk::ExtractImageFilter does not copy the MetadataDictionary
112  maskExtract->GetOutput()->SetMetaDataDictionary(this->GetInputMask()->GetMetaDataDictionary());
113 
114  labelImageToOGRDataFilter->SetInputMask(maskExtract->GetOutput());
115  }
116 
117  labelImageToOGRDataFilter->SetInput(dynamic_cast<LabelImageType*>(m_SegmentationFilter->GetOutputs().at(labelImageIndex).GetPointer()));
118  labelImageToOGRDataFilter->SetFieldName(m_FieldName);
119  labelImageToOGRDataFilter->SetUse8Connected(m_Use8Connected);
120  labelImageToOGRDataFilter->Update();
121 
122  otbMsgDebugMacro(<< "vectorization took " << chrono.GetElapsedMilliseconds() / 1000 << " sec");
123 
124  // Relabeling & simplication of geometries & filtering small objects
125  chrono.Restart();
126  OGRDataSourcePointerType tmpDS = const_cast<OGRDataSourceType*>(labelImageToOGRDataFilter->GetOutput());
127  OGRLayerType tmpLayer = tmpDS->GetLayer(0);
128 
129  const typename InputImageType::SpacingType inSpacing = this->GetInput()->GetSignedSpacing();
130  const double tol = m_SimplificationTolerance * std::max(std::abs(inSpacing[0]), std::abs(inSpacing[1]));
131 
132  typename OGRLayerType::iterator featIt = tmpLayer.begin();
133  for (featIt = tmpLayer.begin(); featIt != tmpLayer.end(); ++featIt)
134  {
135  ogr::Field field = (*featIt)[0];
136  // field.Unset();
137  field.SetValue(m_TileMaxLabel);
138  m_TileMaxLabel++;
139 
140  // Simplify the geometry
141  if (m_Simplify)
142  {
143  const OGRGeometry* geom = (*featIt).GetGeometry();
144  assert(geom && "geometry is NULL ! Can't simplify it.");
145 
146  (*featIt).SetGeometryDirectly(ogr::Simplify(*geom, tol));
147  }
148  // Need to rewrite the feature otherwise changes are not considered.
149  tmpLayer.SetFeature(*featIt);
150 
151  // Filter small objects.
152  if (m_FilterSmallObject)
153  {
154  double area = static_cast<const OGRPolygon*>((*featIt).GetGeometry())->get_Area();
155  // convert into pixel coordinates
156  typename InputImageType::SpacingType spacing = this->GetInput()->GetSignedSpacing();
157  double pixelsArea = area / (std::abs(spacing[0] * spacing[1]));
158  otbMsgDebugMacro(<< "DN = " << field.GetValue<int>() << ", area = " << pixelsArea);
159  if (pixelsArea < m_MinimumObjectSize)
160  {
161  tmpLayer.DeleteFeature((*featIt).GetFID());
162  }
163  }
164  }
165  chrono.Stop();
166  otbMsgDebugMacro(<< "relabeling, filtering small objects and simplifying geometries took " << chrono.GetElapsedMilliseconds() / 1000 << " sec");
167 
168  return tmpDS;
169 }
170 
171 
172 } // end namespace otb
173 #endif
otb::ogr::Layer::SetFeature
void SetFeature(Feature feature)
otb::ogr::Field::SetValue
void SetValue(T const &value)
Definition: otbOGRFieldWrapper.hxx:443
otb::PersistentImageToOGRLayerSegmentationFilter::SetInputMask
virtual void SetInputMask(const LabelImageType *mask)
Definition: otbStreamingImageToOGRLayerSegmentationFilter.hxx:61
otb::PersistentImageToOGRLayerSegmentationFilter::ProcessTile
OGRDataSourcePointerType ProcessTile() override
Definition: otbStreamingImageToOGRLayerSegmentationFilter.hxx:76
otb::PersistentImageToOGRLayerSegmentationFilter::GetInputMask
virtual const LabelImageType * GetInputMask(void)
Definition: otbStreamingImageToOGRLayerSegmentationFilter.hxx:68
otb::ogr::Layer::DeleteFeature
void DeleteFeature(long nFID)
otb::PersistentImageToOGRLayerSegmentationFilter::~PersistentImageToOGRLayerSegmentationFilter
~PersistentImageToOGRLayerSegmentationFilter() override
Definition: otbStreamingImageToOGRLayerSegmentationFilter.hxx:56
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::ogr::DataSource
Collection of geometric objects.
Definition: otbOGRDataSourceWrapper.h:83
otb::PersistentImageToOGRLayerSegmentationFilter::LabelImageType
LabeledOutputAccessor< SegmentationFilterType >::LabelImageType LabelImageType
Definition: otbStreamingImageToOGRLayerSegmentationFilter.h:74
otbMacro.h
otb::LabeledOutputAccessor
Accessor to the index of the labeled output image of the Template Filter.
Definition: otbLabeledOutputAccessor.h:37
otb::ogr::Layer::begin
const_iterator begin() const
Definition: otbOGRLayerWrapper.h:412
otb::ogr::Layer::end
const_iterator end() const
Definition: otbOGRLayerWrapper.h:418
otb::LabelImageToOGRDataSourceFilter::Pointer
itk::SmartPointer< Self > Pointer
Definition: otbLabelImageToOGRDataSourceFilter.h:54
otb::ogr::Simplify
OTBGdalAdapters_EXPORT UniqueGeometryPtr Simplify(OGRGeometry const &g, double tolerance)
otb::PersistentImageToOGRLayerSegmentationFilter::m_SegmentationFilter
SegmentationFilterType::Pointer m_SegmentationFilter
Definition: otbStreamingImageToOGRLayerSegmentationFilter.h:167
otb::Stopwatch
Stopwatch timer.
Definition: otbStopwatch.h:41
otb::ogr::Layer::feature_iter
Implementation class for Feature iterator. This iterator is a single pass iterator....
Definition: otbOGRLayerWrapper.h:348
otbVectorDataTransformFilter.h
otbStreamingImageToOGRLayerSegmentationFilter.h
otb::Stopwatch::StartNew
static Stopwatch StartNew()
otb::PersistentImageToOGRLayerSegmentationFilter::m_TileNumber
unsigned int m_TileNumber
Definition: otbStreamingImageToOGRLayerSegmentationFilter.h:171
otb::ogr::Field
Encapsulation of OGRField Instances of Field are expected to be built from an existing Feature with w...
Definition: otbOGRFieldWrapper.h:117
otb::PersistentImageToOGRLayerSegmentationFilter::OGRDataSourcePointerType
Superclass::OGRDataSourcePointerType OGRDataSourcePointerType
Definition: otbStreamingImageToOGRLayerSegmentationFilter.h:79
otbMsgDebugMacro
#define otbMsgDebugMacro(x)
Definition: otbMacro.h:62
otb::PersistentImageToOGRLayerSegmentationFilter::PersistentImageToOGRLayerSegmentationFilter
PersistentImageToOGRLayerSegmentationFilter()
Definition: otbStreamingImageToOGRLayerSegmentationFilter.hxx:38
otb::ogr::Field::GetValue
T GetValue() const
Definition: otbOGRFieldWrapper.hxx:463
otb::Stopwatch::Stop
void Stop()
otb::Stopwatch::GetElapsedMilliseconds
DurationType GetElapsedMilliseconds() const
otb::Stopwatch::Restart
void Restart()
otb::ogr::Layer
Layer of geometric objects.
Definition: otbOGRLayerWrapper.h:80
otbStopwatch.h