Orfeo Toolbox  4.0
otbBinaryFunctorNeighborhoodImageFilter.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 __otbBinaryFunctorNeighborhoodImageFilter_txx
19 #define __otbBinaryFunctorNeighborhoodImageFilter_txx
20 
22 #include "itkImageRegionIterator.h"
25 #include "itkProgressReporter.h"
26 
27 namespace otb
28 {
29 
33 template <class TInputImage1, class TInputImage2,
34  class TOutputImage, class TFunction>
37 {
38  this->SetNumberOfRequiredInputs(2);
39  m_Radius.Fill(3);
40 }
41 
45 template <class TInputImage1, class TInputImage2,
46  class TOutputImage, class TFunction>
47 void
49 ::SetInput1(const TInputImage1 * image1)
50 {
51  // Process object is not const-correct so the const casting is required.
52  this->SetNthInput(0, const_cast<TInputImage1 *>(image1));
53 }
54 
58 template <class TInputImage1, class TInputImage2,
59  class TOutputImage, class TFunction>
60 void
62 ::SetInput2(const TInputImage2 * image2)
63 {
64  // Process object is not const-correct so the const casting is required.
65  this->SetNthInput(1, const_cast<TInputImage2 *>(image2));
66 }
67 
68 template <class TInputImage1, class TInputImage2,
69  class TOutputImage, class TFunction>
70 const TInputImage1 *
73 {
74  if (this->GetNumberOfInputs() < 1)
75  {
76  return 0;
77  }
78  return static_cast<const TInputImage1 *>(this->itk::ProcessObject::GetInput(0));
79 }
80 
81 template <class TInputImage1, class TInputImage2,
82  class TOutputImage, class TFunction>
83 const TInputImage2 *
86 {
87  if (this->GetNumberOfInputs() < 2)
88  {
89  return 0;
90  }
91  return static_cast<const TInputImage2 *>(this->itk::ProcessObject::GetInput(1));
92 }
93 
94 template <class TInputImage1, class TInputImage2,
95  class TOutputImage, class TFunction>
96 void
99 {
100  // call the superclass' implementation of this method
101  Superclass::GenerateInputRequestedRegion();
102 
103  // get pointers to the input and output
104  Input1ImagePointer inputPtr1 =
105  const_cast<TInputImage1 *>(this->GetInput1());
106  Input2ImagePointer inputPtr2 =
107  const_cast<TInputImage2 *>(this->GetInput2());
108  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
109 
110  if (!inputPtr1 || !inputPtr2 || !outputPtr)
111  {
112  return;
113  }
114  // get a copy of the input requested region (should equal the output
115  // requested region)
116  typename TInputImage1::RegionType inputRequestedRegion1, inputRequestedRegion2;
117  inputRequestedRegion1 = inputPtr1->GetRequestedRegion();
118 
119  // pad the input requested region by the operator radius
120  inputRequestedRegion1.PadByRadius(m_Radius);
121  inputRequestedRegion2 = inputRequestedRegion1;
122 
123  // crop the input requested region at the input's largest possible region
124  if (inputRequestedRegion1.Crop(inputPtr1->GetLargestPossibleRegion()))
125  {
126  inputPtr1->SetRequestedRegion(inputRequestedRegion1);
127  }
128  else
129  {
130  // Couldn't crop the region (requested region is outside the largest
131  // possible region). Throw an exception.
132 
133  // store what we tried to request (prior to trying to crop)
134  inputPtr1->SetRequestedRegion(inputRequestedRegion1);
135 
136  // build an exception
137  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
138  std::ostringstream msg;
139  msg << this->GetNameOfClass()
140  << "::GenerateInputRequestedRegion()";
141  e.SetLocation(msg.str().c_str());
142  e.SetDescription("Requested region is (at least partially) outside the largest possible region of image 1.");
143  e.SetDataObject(inputPtr1);
144  throw e;
145  }
146  if (inputRequestedRegion2.Crop(inputPtr2->GetLargestPossibleRegion()))
147  {
148  inputPtr2->SetRequestedRegion(inputRequestedRegion2);
149  }
150  else
151  {
152  // Couldn't crop the region (requested region is outside the largest
153  // possible region). Throw an exception.
154 
155  // store what we tried to request (prior to trying to crop)
156  inputPtr2->SetRequestedRegion(inputRequestedRegion2);
157 
158  // build an exception
159  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
160  std::ostringstream msg;
161  msg << this->GetNameOfClass()
162  << "::GenerateInputRequestedRegion()";
163  e.SetLocation(msg.str().c_str());
164  e.SetDescription("Requested region is (at least partially) outside the largest possible region of image 1.");
165  e.SetDataObject(inputPtr2);
166  throw e;
167  }
168  return;
169 }
170 
174 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
175 void
177 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
178  itk::ThreadIdType threadId)
179 {
180 
181  //unsigned int i;
184 
185 // We use dynamic_cast since inputs are stored as DataObjects. The
186 // ImageToImageFilter::GetInput(int) always returns a pointer to a
187 // TInputImage1 so it cannot be used for the second input.
188  Input1ImageConstPointer inputPtr1
189  = dynamic_cast<const TInputImage1*>(ProcessObjectType::GetInput(0));
190  Input2ImageConstPointer inputPtr2
191  = dynamic_cast<const TInputImage2*>(ProcessObjectType::GetInput(1));
192  OutputImagePointer outputPtr = this->GetOutput(0);
193 
194  RadiusType1 r1;
195  r1[0] = m_Radius[0];
196  r1[1] = m_Radius[1];
197  NeighborhoodIteratorType1 neighInputIt1;
198 
199  RadiusType2 r2;
200  r2[0] = m_Radius[0];
201  r2[1] = m_Radius[1];
202  NeighborhoodIteratorType2 neighInputIt2;
203 
205 
206  // Find the data-set boundary "faces"
209  faceList1 = bC1(inputPtr1, outputRegionForThread, r1);
210 
213  faceList2 = bC2(inputPtr2, outputRegionForThread, r2);
214 
217 
218  // support progress methods/callbacks
219  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
220 
221  // Process each of the boundary faces. These are N-d regions which border
222  // the edge of the buffer.
223  for (fit1 = faceList1.begin(), fit2 = faceList2.begin();
224  fit1 != faceList1.end() && fit2 != faceList2.end();
225  ++fit1, ++fit2)
226  {
227  neighInputIt1 = itk::ConstNeighborhoodIterator<TInputImage1>(r1, inputPtr1, *fit1);
228  neighInputIt2 = itk::ConstNeighborhoodIterator<TInputImage2>(r2, inputPtr2, *fit2);
229  // outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, outputRegionForThread);
230 
231  outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, *fit1);
232  neighInputIt1.OverrideBoundaryCondition(&nbc1);
233  neighInputIt1.GoToBegin();
234  neighInputIt2.OverrideBoundaryCondition(&nbc2);
235  neighInputIt2.GoToBegin();
236 
237  while (!outputIt.IsAtEnd())
238  {
239 
240  outputIt.Set(m_Functor(neighInputIt1, neighInputIt2));
241 
242  ++neighInputIt1;
243  ++neighInputIt2;
244  ++outputIt;
245  progress.CompletedPixel();
246  }
247  }
248 
249 }
250 
251 } // end namespace otb
252 
253 #endif

Generated at Sat Mar 8 2014 15:51:05 for Orfeo Toolbox with doxygen 1.8.3.1