OTB  5.11.0
Orfeo Toolbox
otbObjectDetectionClassifier.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 otbObjectDetectionClassifier_txx
22 #define otbObjectDetectionClassifier_txx
23 
25 
26 #include "itkContinuousIndex.h"
27 
28 namespace otb
29 {
30 
31 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
34  : m_NeighborhoodRadius(0),
35  m_ClassKey("Class"),
36  m_NoClassLabel(0),
37  m_GridStep(10)
38 {
39  // Need 2 inputs : a vector image, and a SVMModel
40  this->SetNumberOfRequiredInputs(2);
41 
42  // Have 2 outputs : the image created by Superclass, a vector data with points
43  this->SetNumberOfRequiredOutputs(3);
44  this->itk::ProcessObject::SetNthOutput(1, this->MakeOutput(1).GetPointer());
45  this->itk::ProcessObject::SetNthOutput(2, this->MakeOutput(2).GetPointer());
46 }
47 
48 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
51 {
52 }
53 
54 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
55 void
58 {
59  // This is commented to prevent the streaming of the whole image for the first stream strip
60  // It shall not cause any problem because the output image of this filter is not intended to be used.
61  //InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
62  //this->GraftOutput( image );
63  // Nothing that needs to be allocated for the remaining outputs
64 }
65 
66 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
67 void
70 {
71  Superclass::GenerateOutputInformation();
72  if (this->GetInput())
73  {
74  this->GetOutput()->CopyInformation(this->GetInput());
75  this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
76 
77  if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
78  {
79  this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
80  }
81  }
82 }
83 
84 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
85 void
88 {
89  this->SetNthInput(1, model);
90 }
91 
92 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
96 {
97  return static_cast<VectorDataType*>(this->itk::ProcessObject::GetOutput(1));
98 }
99 
100 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
104 {
106  switch (idx)
107  {
108  case 0:
109  output = static_cast<itk::DataObject*>(InputImageType::New().GetPointer());
110  break;
111  case 1:
112  {
113  output = static_cast<itk::DataObject*>(VectorDataType::New().GetPointer());
114  break;
115  }
116  default:
117  output = static_cast<itk::DataObject*>(InputImageType::New().GetPointer());
118  break;
119  }
120  return output;
121 }
122 
123 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
124 void
127 {
128  m_ThreadPointArray = PointArrayContainer(this->GetNumberOfThreads());
129 
130 }
131 
132 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
133 void
136 {
137  // merge all points in a single vector data
138  //std::copy(m_ThreadPointArray[0].begin(), m_ThreadPointArray[0].end(),
139  //std::ostream_iterator<DescriptorsFunctionPointType>(std::cout, "\n") );
140 
141  VectorDataType* vdata = this->GetOutputVectorData();
142 
143  // Retrieving root node
144  VectorDataNodePointerType root = vdata->GetDataTree()->GetRoot()->Get();
145  // Create the document node
146  VectorDataNodePointerType document = VectorDataNodeType::New();
147  document->SetNodeType(otb::DOCUMENT);
148  VectorDataNodePointerType folder = VectorDataNodeType::New();
149  folder->SetNodeType(otb::FOLDER);
150  // Adding the layer to the data tree
151  vdata->GetDataTree()->Add(document, root);
152  vdata->GetDataTree()->Add(folder, document);
153 
154  for (itk::ThreadIdType threadId = 0; threadId < m_ThreadPointArray.size(); ++threadId)
155  {
156  PointArray& pointArray = m_ThreadPointArray[threadId];
157  typename PointArray::const_iterator it = pointArray.begin();
158  typename PointArray::const_iterator end = pointArray.end();
159 
160  for (; it != end; ++it)
161  {
162  VectorDataNodePointerType currentGeometry = VectorDataNodeType::New();
163  currentGeometry->SetNodeId("FEATURE_POINT");
164  currentGeometry->SetNodeType(otb::FEATURE_POINT);
166  p[0] = it->first[0];
167  p[1] = it->first[1];
168  currentGeometry->SetPoint(p);
169  currentGeometry->SetFieldAsInt(m_ClassKey, it->second);
170  vdata->GetDataTree()->Add(currentGeometry, folder);
171  }
172  }
173 }
174 
175 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
176 void
178 ::PrintSelf(std::ostream& os, itk::Indent indent) const
179 {
180  Superclass::PrintSelf(os, indent);
181 }
182 
183 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
184 void
187 {
188  Superclass::GenerateInputRequestedRegion();
189 
190  // get pointers to the input and output
191  typename Superclass::InputImagePointer inputPtr =
192  const_cast< TInputImage * >( this->GetInput() );
193  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
194 
195  if ( !inputPtr || !outputPtr )
196  {
197  return;
198  }
199 
200  // get a copy of the input requested region (should equal the output
201  // requested region)
202  typename TInputImage::RegionType inputRequestedRegion;
203  inputRequestedRegion = inputPtr->GetRequestedRegion();
204 
205  // pad the input requested region by the operator radius
206  inputRequestedRegion.PadByRadius( m_NeighborhoodRadius + 1 );
207 
208  // crop the input requested region at the input's largest possible region
209  if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
210  {
211  inputPtr->SetRequestedRegion( inputRequestedRegion );
212  return;
213  }
214  else
215  {
216  // Couldn't crop the region (requested region is outside the largest
217  // possible region). Throw an exception.
218 
219  // store what we tried to request (prior to trying to crop)
220  inputPtr->SetRequestedRegion( inputRequestedRegion );
221  }
222 }
223 
224 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
225 void
228 {
229  // Compute the 1/(sigma) vector
230  m_InvertedScales = m_Scales;
231  for(unsigned int idx = 0; idx < m_Scales.Size(); ++idx)
232  {
233  if(m_Scales[idx]-1e-10 < 0.)
234  m_InvertedScales[idx] = 0.;
235  else
236  m_InvertedScales[idx] = 1 / m_Scales[idx];
237  }
238 
239 }
240 
241 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
242 void
244 ::ThreadedGenerateData(const RegionType& outputRegionForThread,
245  itk::ThreadIdType threadId)
246 {
247  InputImageType* input = static_cast<InputImageType*>(this->itk::ProcessObject::GetInput(0));
248  SVMModelType* model = static_cast<SVMModelType*>(this->itk::ProcessObject::GetInput(1));
249 
250  typedef typename RegionType::IndexType IndexType;
251  IndexType begin = outputRegionForThread.GetIndex();
252  IndexType end = begin;
253  end[0] += outputRegionForThread.GetSize(0);
254  end[1] += outputRegionForThread.GetSize(1);
255 
256  IndexType current = begin;
257  for (; current[1] != end[1]; current[1]++)
258  {
259  if (current[1] % m_GridStep == 0)
260  {
261  for(current[0] = begin[0]; current[0] != end[0]; current[0]++)
262  {
263  if (current[0] % m_GridStep == 0)
264  {
266  input->TransformIndexToPhysicalPoint(current, point);
267 
268  DescriptorType descriptor = m_DescriptorsFunction->Evaluate(point);
269  SVMModelMeasurementType modelMeasurement(descriptor.GetSize());
270  for (unsigned int i = 0; i < descriptor.GetSize(); ++i)
271  {
272  modelMeasurement[i] = (descriptor[i] - m_Shifts[i]) * m_InvertedScales[i];
273  }
274  LabelType label = model->EvaluateLabel(modelMeasurement);
275 
276  if (label != m_NoClassLabel)
277  {
278  m_ThreadPointArray[threadId].push_back(std::make_pair(point, label));
279  }
280  }
281  }
282  }
283  }
284 }
285 
286 
287 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionPrecision, class TCoordRep>
290 {
291 
292 }
293 
294 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionPrecision, class TCoordRep>
297 {
298 
299 }
300 
301 
302 } // end namespace otb
303 
304 #endif
DescriptorsFunctionType::OutputType DescriptorType
DescriptorsFunctionType::InputType DescriptorsFunctionPointType
Superclass::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
itk::DataObject::Pointer MakeOutput(DataObjectPointerArraySizeType idx) ITK_OVERRIDE
VectorDataType::DataNodePointerType VectorDataNodePointerType
itk::Index< Monteverdi_DIMENSION > IndexType
Definition: mvdTypes.h:142
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) ITK_OVERRIDE
LabelType EvaluateLabel(const MeasurementType &measure) const
Class for SVM models.
Definition: otbSVMModel.h:64
unsigned int ThreadIdType
DataObject * GetInput(const DataObjectIdentifierType &key)
virtual void SetNthOutput(DataObjectPointerArraySizeType num, DataObject *output)
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
DataObject * GetOutput(const DataObjectIdentifierType &key)