Orfeo Toolbox  3.16
otbTouziEdgeDetectorImageFilter.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 __otbTouziEdgeDetectorImageFilter_txx
19 #define __otbTouziEdgeDetectorImageFilter_txx
20 
22 
23 #include "itkDataObject.h"
24 
27 #include "itkImageRegionIterator.h"
30 #include "itkProgressReporter.h"
31 #include "otbMacro.h"
32 #include "otbMath.h"
33 
34 namespace otb
35 {
36 
40 template <class TInputImage, class TOutputImage, class TOutputImageDirection>
42 {
43  m_Radius.Fill(1);
44 }
45 
46 template <class TInputImage, class TOutputImage, class TOutputImageDirection>
47 void TouziEdgeDetectorImageFilter<TInputImage, TOutputImage,
48  TOutputImageDirection>::GenerateInputRequestedRegion() throw (
49  itk::InvalidRequestedRegionError)
50  {
51  // call the superclass' implementation of this method
52  Superclass::GenerateInputRequestedRegion();
53 
54  // get pointers to the input and output
55  typename Superclass::InputImagePointer inputPtr = const_cast<TInputImage *>(this->GetInput());
56  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
57 
58  if (!inputPtr || !outputPtr)
59  {
60  return;
61  }
62 
63  // get a copy of the input requested region (should equal the output
64  // requested region)
65  typename TInputImage::RegionType inputRequestedRegion;
66  inputRequestedRegion = inputPtr->GetRequestedRegion();
67 
68  // pad the input requested region by the operator radius
69  inputRequestedRegion.PadByRadius(m_Radius);
70 
71  // crop the input requested region at the input's largest possible region
72  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
73  {
74  inputPtr->SetRequestedRegion(inputRequestedRegion);
75  return;
76  }
77  else
78  {
79  // Couldn't crop the region (requested region is outside the largest
80  // possible region). Throw an exception.
81 
82  // store what we tried to request (prior to trying to crop)
83  inputPtr->SetRequestedRegion(inputRequestedRegion);
84 
85  // build an exception
86  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
87  std::ostringstream msg;
88  msg << static_cast<const char *>(this->GetNameOfClass())
89  << "::GenerateInputRequestedRegion()";
90  e.SetLocation(msg.str().c_str());
91  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
92  e.SetDataObject(inputPtr);
93  throw e;
94  }
95  }
96 
102 template <class TInputImage, class TOutputImage, class TOutputImageDirection>
103 void
106 {
107 
108  typename OutputImageDirectionType::RegionType region;
109  typename OutputImageType::Pointer output = this->GetOutput();
110 
111  OutputImageDirectionType * direction = this->GetOutputDirection();
112 
113  region.SetSize(output->GetRequestedRegion().GetSize());
114  region.SetIndex(output->GetRequestedRegion().GetIndex());
115  direction->SetRegions(region);
116  direction->SetOrigin(output->GetOrigin());
117  direction->SetSpacing(output->GetSpacing());
118  direction->Allocate();
119 }
120 
121 template <class TInputImage, class TOutputImage, class TOutputImageDirection>
122 void
125  const OutputImageRegionType& outputRegionForThread,
126  int threadId
127  )
128 {
129  unsigned int i;
134 
135  // Allocate output
136  typename OutputImageType::Pointer output = this->GetOutput();
137  typename InputImageType::ConstPointer input = this->GetInput();
138  typename OutputImageDirectionType::Pointer outputDir = this->GetOutputDirection();
139 
140  // Find the data-set boundary "faces"
143 
145  faceList = bC(input, outputRegionForThread, m_Radius);
146 
147  // support progress methods/callbacks
148  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
149 
150  typename TInputImage::IndexType bitIndex;
151 
152  // Initializations
153  // ---------------
154  // Number of direction
155  const int NB_DIR = 4;
156  // Number of region of the filter
157  const int NB_REGION = 2;
158  // Definition of the 4 directions
159  double Theta[NB_DIR];
160 
161  Theta[0] = 0.;
162  Theta[1] = CONST_PI_4;
163  Theta[2] = CONST_PI_2;
164  Theta[3] = 3 * CONST_PI / 4.;
165 
166  // contains for the 4 directions the sum of the pixels belonging to each region
167  double Sum[NB_DIR][NB_REGION];
168  // Mean of region 1
169  double M1;
170  // Mean of region 2
171  double M2;
172  // Result of the filter for each direction
173  double R_theta[NB_DIR];
174  double Sum_R_theta = 0.;
175  // Intensity of the contour
176  double R_contour;
177  // Direction of the contour
178  double Dir_contour = 0.;
179  // sign of the contour
180  int sign;
181 
182  // Pixel location in the input image
183  int x;
184  int y;
185  // Location of the central pixel in the input image
186  int xc;
187  int yc;
188 
189  int cpt = 0;
190 
191  // Process each of the boundary faces. These are N-d regions which border
192  // the edge of the buffer.
193  for (fit = faceList.begin(); fit != faceList.end(); ++fit)
194  {
195 
196  cpt += 1;
197 
198  bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
199  unsigned int neighborhoodSize = bit.Size();
200 
202  it_dir = itk::ImageRegionIterator<OutputImageDirectionType>(outputDir, *fit);
203 
204  bit.OverrideBoundaryCondition(&nbc);
205  bit.GoToBegin();
206 
207  while (!bit.IsAtEnd())
208  {
209 
210  // Location of the pixel central
211  bitIndex = bit.GetIndex();
212 
213  xc = bitIndex[0];
214  yc = bitIndex[1];
215 
216  // Initializations
217  for (int dir = 0; dir < NB_DIR; ++dir)
218  {
219  for (int m = 0; m < NB_REGION; m++)
220  Sum[dir][m] = 0.;
221  }
222 
223  R_contour = -1;
224  Dir_contour = 0.;
225  Sum_R_theta = 0.;
226 
227  // Loop on pixels of the filter
228  for (i = 0; i < neighborhoodSize; ++i)
229  {
230 
231  bitIndex = bit.GetIndex(i);
232  x = bitIndex[0];
233  y = bitIndex[1];
234 
235  // We determine for each direction with which region the pixel belongs.
236 
237  // Horizontal direction
238  if (y < yc) Sum[0][0] += static_cast<double>(bit.GetPixel(i));
239  else if (y > yc) Sum[0][1] += static_cast<double>(bit.GetPixel(i));
240 
241  // Diagonal direction 1
242  if ((y - yc) < (x - xc)) Sum[1][0] += static_cast<double>(bit.GetPixel(i));
243  else if ((y - yc) > (x - xc)) Sum[1][1] += static_cast<double>(bit.GetPixel(i));
244 
245  // Vertical direction
246  if (x > xc) Sum[2][0] += static_cast<double>(bit.GetPixel(i));
247  else if (x < xc) Sum[2][1] += static_cast<double>(bit.GetPixel(i));
248 
249  // Diagonal direction 2
250  if ((y - yc) > -(x - xc)) Sum[3][0] += static_cast<double>(bit.GetPixel(i));
251  else if ((y - yc) < -(x - xc)) Sum[3][1] += static_cast<double>(bit.GetPixel(i));
252 
253  } // end of the loop on pixels of the filter
254 
255  // Loop on the 4 directions
256  for (int dir = 0; dir < NB_DIR; ++dir)
257  {
258  // Calculation of the mean of the 2 regions
259  M1 = Sum[dir][0] / static_cast<double>(m_Radius[0] * (2 * m_Radius[0] + 1));
260  M2 = Sum[dir][1] / static_cast<double>(m_Radius[0] * (2 * m_Radius[0] + 1));
261 
262  // Calculation of the intensity of the contour
263  if ((M1 != 0) && (M2 != 0)) R_theta[dir] = static_cast<double>(1 - std::min((M1 / M2), (M2 / M1)));
264  else R_theta[dir] = 0.;
265 
266  // Determination of the maximum intensity of the contour
267  R_contour = static_cast<double>(std::max(R_contour, R_theta[dir]));
268 
269  // Determination of the sign of contour
270  if (M2 > M1) sign = +1;
271  else sign = -1;
272 
273  Dir_contour += sign * Theta[dir] * R_theta[dir];
274  Sum_R_theta += R_theta[dir];
275 
276  } // end of the loop on the directions
277 
278  // Assignment of this value to the output pixel
279  it.Set(static_cast<OutputPixelType>(R_contour));
280 
281  // Determination of the direction of the contour
282  if (Sum_R_theta != 0.) Dir_contour = Dir_contour / Sum_R_theta;
283 
284  // Assignment of this value to the "outputdir" pixel
285  it_dir.Set(static_cast<OutputPixelDirectionType>(Dir_contour));
286 
287  ++bit;
288  ++it;
289  ++it_dir;
290  progress.CompletedPixel();
291 
292  }
293 
294  }
295 }
296 
300 template <class TInputImage, class TOutputImage, class TOutputImageDirection>
301 void
303 ::PrintSelf(std::ostream& os, itk::Indent indent) const
304 {
305  Superclass::PrintSelf(os, indent);
306  os << indent << "Radius: " << m_Radius << std::endl;
307 }
308 
309 } // end namespace otb
310 
311 #endif

Generated at Sun Feb 3 2013 00:52:10 for Orfeo Toolbox with doxygen 1.8.1.1