Orfeo Toolbox  3.16
itkVanHerkGilWermanErodeDilateImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkVanHerkGilWermanErodeDilateImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2009-06-03 12:48:05 $
7  Version: $Revision: 1.6 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 
18 #ifndef __itkVanHerkGilWermanErodeDilateImageFilter_txx
19 #define __itkVanHerkGilWermanErodeDilateImageFilter_txx
20 
22 #include "itkImageRegionIterator.h"
23 //#include "itkNeighborhoodAlgorithm.h"
24 
26 
27 namespace itk {
28 
29 template <class TImage, class TKernel, class TFunction1>
32 {
33  m_KernelSet = false;
34 }
35 
36 template <class TImage, class TKernel, class TFunction1>
37 void
40 {
41  m_Boundary = value;
42 }
43 
44 template <class TImage, class TKernel, class TFunction1>
45 void
47 ::ThreadedGenerateData (const InputImageRegionType& outputRegionForThread,
48  int threadId)
49 {
50 
51  // check that we are using a decomposable kernel
52  if (!m_Kernel.GetDecomposable())
53  {
54  itkExceptionMacro("VanHerkGilWerman morphology only works with decomposable structuring elements");
55  return;
56  }
57  if (!m_KernelSet)
58  {
59  itkExceptionMacro("No kernel set");
60  return;
61  }
62  // TFunction1 will be < for erosions
63 
64  // the initial version will adopt the methodology of loading a line
65  // at a time into a buffer vector, carrying out the opening or
66  // closing, and then copy the result to the output. Hopefully this
67  // will improve cache performance when working along non raster
68  // directions.
69 
70  ProgressReporter progress(this, threadId, m_Kernel.GetLines().size() + 1);
71 
72  InputImageConstPointer input = this->GetInput();
73 
74  InputImageRegionType IReg = outputRegionForThread;
75  IReg.PadByRadius( m_Kernel.GetRadius() );
76  // IReg.PadByRadius( m_Kernel.GetRadius() );
77  IReg.Crop( this->GetInput()->GetRequestedRegion() );
78 
79  // allocate an internal buffer
80  typename InputImageType::Pointer internalbuffer = InputImageType::New();
81  internalbuffer->SetRegions(IReg);
82  internalbuffer->Allocate();
83  InputImagePointer output = internalbuffer;
84 
85  // get the region size
86  InputImageRegionType OReg = outputRegionForThread;
87  // maximum buffer length is sum of dimensions
88  unsigned int bufflength = 0;
89  for (unsigned i = 0; i<TImage::ImageDimension; i++)
90  {
91  bufflength += IReg.GetSize()[i];
92  }
93 
94  // compat
95  bufflength += 2;
96 
97  InputImagePixelType * buffer = new InputImagePixelType[bufflength];
98  InputImagePixelType * forward = new InputImagePixelType[bufflength];
99  InputImagePixelType * reverse = new InputImagePixelType[bufflength];
100  // iterate over all the structuring elements
101  typename KernelType::DecompType decomposition = m_Kernel.GetLines();
102  BresType BresLine;
103 
104  typedef typename KernelType::LType KernelLType;
105 
106  for (unsigned i = 0; i < decomposition.size(); i++)
107  {
108  typename KernelType::LType ThisLine = decomposition[i];
109  typename BresType::OffsetArray TheseOffsets = BresLine.BuildLine(ThisLine, bufflength);
110  unsigned int SELength = GetLinePixels<KernelLType>(ThisLine);
111  // want lines to be odd
112  if (!(SELength%2))
113  ++SELength;
114 
115  InputImageRegionType BigFace = MakeEnlargedFace<InputImageType, KernelLType>(input, IReg, ThisLine);
116 
117  DoFace<TImage, BresType, TFunction1, KernelLType>(input, output, m_Boundary, ThisLine,
118  TheseOffsets, SELength,
119  buffer, forward,
120  reverse, IReg, BigFace);
121 
122  // after the first pass the input will be taken from the output
123  input = internalbuffer;
124  progress.CompletedPixel();
125  }
126 
127  // copy internal buffer to output
128  typedef ImageRegionIterator<InputImageType> IterType;
129  IterType oit(this->GetOutput(), OReg);
130  IterType iit(internalbuffer, OReg);
131  for (oit.GoToBegin(), iit.GoToBegin(); !oit.IsAtEnd(); ++oit, ++iit)
132  {
133  oit.Set(iit.Get());
134  }
135  progress.CompletedPixel();
136 
137  delete [] buffer;
138  delete [] forward;
139  delete [] reverse;
140 }
141 
142 
143 template<class TImage, class TKernel, class TFunction1>
144 void
146 ::PrintSelf(std::ostream &os, Indent indent) const
147 {
148  Superclass::PrintSelf(os, indent);
149  os << indent << "Boundary: " << m_Boundary << std::endl;
150 }
151 
152 
153 template<class TImage, class TKernel, class TFunction1>
154 void
157 {
158  // call the superclass' implementation of this method
159  Superclass::GenerateInputRequestedRegion();
160 
161  // get pointers to the input and output
162  typename Superclass::InputImagePointer inputPtr =
163  const_cast< TImage * >( this->GetInput() );
164 
165  if ( !inputPtr )
166  {
167  return;
168  }
169 
170  // get a copy of the input requested region (should equal the output
171  // requested region)
172  typename TImage::RegionType inputRequestedRegion;
173  inputRequestedRegion = inputPtr->GetRequestedRegion();
174 
175  // pad the input requested region by the operator radius
176  inputRequestedRegion.PadByRadius( m_Kernel.GetRadius() );
177 
178  // crop the input requested region at the input's largest possible region
179  if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
180  {
181  inputPtr->SetRequestedRegion( inputRequestedRegion );
182  return;
183  }
184  else
185  {
186  // Couldn't crop the region (requested region is outside the largest
187  // possible region). Throw an exception.
188 
189  // store what we tried to request (prior to trying to crop)
190  inputPtr->SetRequestedRegion( inputRequestedRegion );
191 
192  // build an exception
193  InvalidRequestedRegionError e(__FILE__, __LINE__);
194  OStringStream msg;
195  msg << static_cast<const char *>(this->GetNameOfClass())
196  << "::GenerateInputRequestedRegion()";
197  e.SetLocation(msg.str().c_str());
198  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
199  e.SetDataObject(inputPtr);
200  throw e;
201  }
202 }
203 
204 } // end namespace itk
205 
206 #endif

Generated at Sun Feb 3 2013 00:11:20 for Orfeo Toolbox with doxygen 1.8.1.1