Orfeo ToolBox  4.2
Orfeo ToolBox is not a black box
otbObjectDetectionClassifier.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 #ifndef __otbObjectDetectionClassifier_txx
19 #define __otbObjectDetectionClassifier_txx
20 
22 
23 #include "itkContinuousIndex.h"
24 
25 namespace otb
26 {
27 
28 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
31  : m_NeighborhoodRadius(0),
32  m_ClassKey("Class"),
33  m_NoClassLabel(0),
34  m_GridStep(10)
35 {
36  // Need 2 inputs : a vector image, and a SVMModel
37  this->SetNumberOfRequiredInputs(2);
38 
39  // Have 2 outputs : the image created by Superclass, a vector data with points
40  this->SetNumberOfRequiredOutputs(3);
41  this->itk::ProcessObject::SetNthOutput(1, this->MakeOutput(1).GetPointer());
42  this->itk::ProcessObject::SetNthOutput(2, this->MakeOutput(2).GetPointer());
43 }
44 
45 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
48 {
49 }
50 
51 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
52 void
55 {
56  // This is commented to prevent the streaming of the whole image for the first stream strip
57  // It shall not cause any problem because the output image of this filter is not intended to be used.
58  //InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
59  //this->GraftOutput( image );
60  // Nothing that needs to be allocated for the remaining outputs
61 }
62 
63 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
64 void
67 {
68  Superclass::GenerateOutputInformation();
69  if (this->GetInput())
70  {
71  this->GetOutput()->CopyInformation(this->GetInput());
72  this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
73 
74  if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
75  {
76  this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
77  }
78  }
79 }
80 
81 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
82 void
85 {
86  this->SetNthInput(1, model);
87 }
88 
89 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
93 {
94  return static_cast<VectorDataType*>(this->itk::ProcessObject::GetOutput(1));
95 }
96 
97 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
98 itk::DataObject::Pointer
100 ::MakeOutput(unsigned int idx)
101 {
102  itk::DataObject::Pointer output;
103  switch (idx)
104  {
105  case 0:
106  output = static_cast<itk::DataObject*>(InputImageType::New().GetPointer());
107  break;
108  case 1:
109  {
110  output = static_cast<itk::DataObject*>(VectorDataType::New().GetPointer());
111  break;
112  }
113  default:
114  output = static_cast<itk::DataObject*>(InputImageType::New().GetPointer());
115  break;
116  }
117  return output;
118 }
119 
120 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
121 void
124 {
125  m_ThreadPointArray = PointArrayContainer(this->GetNumberOfThreads());
126 
127 }
128 
129 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
130 void
133 {
134  // merge all points in a single vector data
135  //std::copy(m_ThreadPointArray[0].begin(), m_ThreadPointArray[0].end(),
136  //std::ostream_iterator<DescriptorsFunctionPointType>(std::cout, "\n") );
137 
138  VectorDataType* vdata = this->GetOutputVectorData();
139 
140  // Retrieving root node
141  VectorDataNodePointerType root = vdata->GetDataTree()->GetRoot()->Get();
142  // Create the document node
143  VectorDataNodePointerType document = VectorDataNodeType::New();
144  document->SetNodeType(otb::DOCUMENT);
145  VectorDataNodePointerType folder = VectorDataNodeType::New();
146  folder->SetNodeType(otb::FOLDER);
147  // Adding the layer to the data tree
148  vdata->GetDataTree()->Add(document, root);
149  vdata->GetDataTree()->Add(folder, document);
150 
151  for (itk::ThreadIdType threadId = 0; threadId < m_ThreadPointArray.size(); ++threadId)
152  {
153  PointArray& pointArray = m_ThreadPointArray[threadId];
154  typename PointArray::const_iterator it = pointArray.begin();
155  typename PointArray::const_iterator end = pointArray.end();
156 
157  for (; it != end; ++it)
158  {
159  VectorDataNodePointerType currentGeometry = VectorDataNodeType::New();
160  currentGeometry->SetNodeId("FEATURE_POINT");
161  currentGeometry->SetNodeType(otb::FEATURE_POINT);
163  p[0] = it->first[0];
164  p[1] = it->first[1];
165  currentGeometry->SetPoint(p);
166  currentGeometry->SetFieldAsInt(m_ClassKey, it->second);
167  vdata->GetDataTree()->Add(currentGeometry, folder);
168  }
169  }
170 }
171 
172 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
173 void
175 ::PrintSelf(std::ostream& os, itk::Indent indent) const
176 {
177  Superclass::PrintSelf(os, indent);
178 }
179 
180 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
181 void
184 {
185  Superclass::GenerateInputRequestedRegion();
186 
187  // get pointers to the input and output
188  typename Superclass::InputImagePointer inputPtr =
189  const_cast< TInputImage * >( this->GetInput() );
190  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
191 
192  if ( !inputPtr || !outputPtr )
193  {
194  return;
195  }
196 
197  // get a copy of the input requested region (should equal the output
198  // requested region)
199  typename TInputImage::RegionType inputRequestedRegion;
200  inputRequestedRegion = inputPtr->GetRequestedRegion();
201 
202  // pad the input requested region by the operator radius
203  inputRequestedRegion.PadByRadius( m_NeighborhoodRadius + 1 );
204 
205  // crop the input requested region at the input's largest possible region
206  if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
207  {
208  inputPtr->SetRequestedRegion( inputRequestedRegion );
209  return;
210  }
211  else
212  {
213  // Couldn't crop the region (requested region is outside the largest
214  // possible region). Throw an exception.
215 
216  // store what we tried to request (prior to trying to crop)
217  inputPtr->SetRequestedRegion( inputRequestedRegion );
218  }
219 }
220 
221 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
222 void
225 {
226  // Compute the 1/(sigma) vector
227  m_InvertedScales = m_Scales;
228  for(unsigned int idx = 0; idx < m_Scales.Size(); ++idx)
229  {
230  if(m_Scales[idx]-1e-10 < 0.)
231  m_InvertedScales[idx] = 0.;
232  else
233  m_InvertedScales[idx] = 1 / m_Scales[idx];
234  }
235 
236 }
237 
238 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionType>
239 void
241 ::ThreadedGenerateData(const RegionType& outputRegionForThread,
242  itk::ThreadIdType threadId)
243 {
244  InputImageType* input = static_cast<InputImageType*>(this->itk::ProcessObject::GetInput(0));
245  SVMModelType* model = static_cast<SVMModelType*>(this->itk::ProcessObject::GetInput(1));
246 
247  typedef typename RegionType::IndexType IndexType;
248  IndexType begin = outputRegionForThread.GetIndex();
249  IndexType end = begin;
250  end[0] += outputRegionForThread.GetSize(0);
251  end[1] += outputRegionForThread.GetSize(1);
252 
253  IndexType current = begin;
254  for (; current[1] != end[1]; current[1]++)
255  {
256  if (current[1] % m_GridStep == 0)
257  {
258  for(current[0] = begin[0]; current[0] != end[0]; current[0]++)
259  {
260  if (current[0] % m_GridStep == 0)
261  {
263  input->TransformIndexToPhysicalPoint(current, point);
264 
265  DescriptorType descriptor = m_DescriptorsFunction->Evaluate(point);
266  SVMModelMeasurementType modelMeasurement(descriptor.GetSize());
267  for (unsigned int i = 0; i < descriptor.GetSize(); ++i)
268  {
269  modelMeasurement[i] = (descriptor[i] - m_Shifts[i]) * m_InvertedScales[i];
270  }
271  LabelType label = model->EvaluateLabel(modelMeasurement);
272 
273  if (label != m_NoClassLabel)
274  {
275  m_ThreadPointArray[threadId].push_back(std::make_pair(point, label));
276  }
277  }
278  }
279  }
280  }
281 }
282 
283 
284 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionPrecision, class TCoordRep>
287 {
288 
289 }
290 
291 template <class TInputImage, class TOutputVectorData, class TLabel, class TFunctionPrecision, class TCoordRep>
294 {
295 
296 }
297 
298 
299 } // end namespace otb
300 
301 #endif
DescriptorsFunctionType::OutputType DescriptorType
DescriptorsFunctionType::InputType DescriptorsFunctionPointType
itk::DataObject::Pointer MakeOutput(unsigned int idx)
VectorDataType::DataNodePointerType VectorDataNodePointerType
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId)
LabelType EvaluateLabel(const MeasurementType &measure) const
Class for SVM models.
Definition: otbSVMModel.h:59
void PrintSelf(std::ostream &os, itk::Indent indent) const
unsigned int ThreadIdType