Orfeo Toolbox  3.16
itkVectorConfidenceConnectedImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkVectorConfidenceConnectedImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2008-10-17 16:30:53 $
7  Version: $Revision: 1.11 $
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 #ifndef __itkVectorConfidenceConnectedImageFilter_txx
18 #define __itkVectorConfidenceConnectedImageFilter_txx
19 
21 #include "itkExceptionObject.h"
22 #include "itkImageRegionIterator.h"
28 #include "itkNumericTraits.h"
30 #include "itkProgressReporter.h"
31 
32 namespace itk
33 {
34 
38 template <class TInputImage, class TOutputImage>
41 {
42  m_Multiplier = 2.5;
43  m_NumberOfIterations = 4;
44  m_Seeds.clear();
45  m_InitialNeighborhoodRadius = 1;
46  m_ReplaceValue = NumericTraits<OutputImagePixelType>::One;
47  m_ThresholdFunction = DistanceThresholdFunctionType::New();
48 }
49 
53 template <class TInputImage, class TOutputImage>
54 void
56 ::PrintSelf(std::ostream& os, Indent indent) const
57 {
58  this->Superclass::PrintSelf(os, indent);
59  os << indent << "Number of iterations: " << m_NumberOfIterations
60  << std::endl;
61  os << indent << "Multiplier for confidence interval: " << m_Multiplier
62  << std::endl;
63  os << indent << "ReplaceValue: "
64  << static_cast<typename NumericTraits<OutputImagePixelType>::PrintType>(m_ReplaceValue)
65  << std::endl;
66  os << indent << "InitialNeighborhoodRadius: " << m_InitialNeighborhoodRadius
67  << std::endl;
68 
69 }
70 
71 template <class TInputImage, class TOutputImage>
72 void
75 {
76  Superclass::GenerateInputRequestedRegion();
77  if ( this->GetInput() )
78  {
79  InputImagePointer input =
80  const_cast< TInputImage * >( this->GetInput() );
81  input->SetRequestedRegionToLargestPossibleRegion();
82  }
83 }
84 
85 template <class TInputImage, class TOutputImage>
86 void
89 {
90  Superclass::EnlargeOutputRequestedRegion(output);
92 }
93 
94 template <class TInputImage, class TOutputImage>
95 void
98 {
99  typedef typename InputImageType::PixelType InputPixelType;
100 
101  typedef BinaryThresholdImageFunction<OutputImageType> SecondFunctionType;
104 
105  unsigned int loop;
106 
107  typename Superclass::InputImageConstPointer inputImage = this->GetInput();
108  typename Superclass::OutputImagePointer outputImage = this->GetOutput();
109 
110  // Zero the output
111  OutputImageRegionType region = outputImage->GetRequestedRegion();
112  outputImage->SetBufferedRegion( region );
113  outputImage->Allocate();
114  outputImage->FillBuffer ( NumericTraits<OutputImagePixelType>::Zero );
115 
116  // Compute the statistics of the seed point
117  typedef VectorMeanImageFunction<InputImageType> VectorMeanImageFunctionType;
118  typename VectorMeanImageFunctionType::Pointer meanFunction
119  = VectorMeanImageFunctionType::New();
120 
121  meanFunction->SetInputImage( inputImage );
122  meanFunction->SetNeighborhoodRadius( m_InitialNeighborhoodRadius );
123  typedef CovarianceImageFunction<InputImageType> CovarianceImageFunctionType;
124  typename CovarianceImageFunctionType::Pointer varianceFunction
125  = CovarianceImageFunctionType::New();
126  varianceFunction->SetInputImage( inputImage );
127  varianceFunction->SetNeighborhoodRadius( m_InitialNeighborhoodRadius );
128 
129  // Set up the image function used for connectivity
130  m_ThresholdFunction->SetInputImage ( inputImage );
131 
132  CovarianceMatrixType covariance;
133  MeanVectorType mean;
134 
135  typedef typename InputPixelType::ValueType ComponentPixelType;
136  typedef typename NumericTraits< ComponentPixelType >::RealType ComponentRealType;
137 
138  const unsigned int dimension = InputPixelType::Dimension;
139 
140  covariance = CovarianceMatrixType( dimension, dimension );
141  mean = MeanVectorType( dimension );
142 
143  covariance.fill( NumericTraits<ComponentRealType>::Zero );
144  mean.fill( NumericTraits<ComponentRealType>::Zero );
145 
146  typedef typename VectorMeanImageFunctionType::OutputType MeanFunctionVectorType;
147  typedef typename CovarianceImageFunctionType::OutputType CovarianceFunctionMatrixType;
148 
149  typename SeedsContainerType::const_iterator si = m_Seeds.begin();
150  typename SeedsContainerType::const_iterator li = m_Seeds.end();
151  while( si != li )
152  {
153  const MeanFunctionVectorType meanContribution = meanFunction->EvaluateAtIndex( *si );
154  const CovarianceFunctionMatrixType covarianceContribution = varianceFunction->EvaluateAtIndex( *si );
155  for(unsigned int ii=0; ii < dimension; ii++)
156  {
157  mean[ ii ] += meanContribution[ ii ];
158  for(unsigned int jj=0; jj < dimension; jj++)
159  {
160  covariance[ ii ][ jj ] += covarianceContribution[ ii ][ jj ];
161  }
162  }
163  si++;
164  }
165  for(unsigned int ik=0; ik < dimension; ik++)
166  {
167  mean[ ik ] /= m_Seeds.size();
168  for(unsigned int jk=0; jk < dimension; jk++)
169  {
170  covariance[ ik ][ jk ] /= m_Seeds.size();
171  }
172  }
173 
174  m_ThresholdFunction->SetMean( mean );
175  m_ThresholdFunction->SetCovariance( covariance );
176 
177  m_ThresholdFunction->SetThreshold( m_Multiplier );
178 
179  itkDebugMacro(<< "\nMultiplier originally = " << m_Multiplier );
180 
181 
182  // Make sure that the multiplier is large enough to include the seed points themselves.
183  // This is a pragmatic fix, but a questionable practice because it means that the actual
184  // region may be grown using a multiplier different from the one specified by the user.
185  si = m_Seeds.begin();
186  li = m_Seeds.end();
187  while( si != li )
188  {
189  const double distance =
190  m_ThresholdFunction->EvaluateDistanceAtIndex( *si );
191  if( distance > m_Multiplier )
192  {
193  m_Multiplier = distance;
194  }
195  si++;
196  }
197 
198  // Finally setup the eventually modified multiplier. That is actually the threshold itself.
199  m_ThresholdFunction->SetThreshold( m_Multiplier );
200 
201  itkDebugMacro(<< "\nMultiplier after verifying seeds inclusion = " << m_Multiplier );
202 
203  // Segment the image, the iterator walks the output image (so Set()
204  // writes into the output image), starting at the seed point. As
205  // the iterator walks, if the corresponding pixel in the input image
206  // (accessed via the "m_ThresholdFunction" assigned to the iterator) is within
207  // the [lower, upper] bounds prescribed, the pixel is added to the
208  // output segmentation and its neighbors become candidates for the
209  // iterator to walk.
210  IteratorType it = IteratorType ( outputImage, m_ThresholdFunction, m_Seeds );
211  it.GoToBegin();
212  while( !it.IsAtEnd())
213  {
214  it.Set(m_ReplaceValue);
215  ++it;
216  }
217 
218  ProgressReporter progress(this, 0, region.GetNumberOfPixels() * m_NumberOfIterations );
219 
220  for (loop = 0; loop < m_NumberOfIterations; ++loop)
221  {
222  // Now that we have an initial segmentation, let's recalculate the
223  // statistics. Since we have already labelled the output, we visit
224  // pixels in the input image that have been set in the output image.
225  // Essentially, we flip the iterator around, so we walk the input
226  // image (so Get() will get pixel values from the input) and constrain
227  // iterator such it only visits pixels that were set in the output.
228  typename SecondFunctionType::Pointer secondFunction = SecondFunctionType::New();
229  secondFunction->SetInputImage ( outputImage );
230  secondFunction->ThresholdBetween( m_ReplaceValue, m_ReplaceValue );
231 
232  covariance = CovarianceMatrixType( dimension, dimension );
233  mean = MeanVectorType( dimension );
234 
235  covariance.fill( NumericTraits<ComponentRealType>::Zero );
236  mean.fill( NumericTraits<ComponentRealType>::Zero );
237 
238  unsigned long num = 0;
239 
240  SecondIteratorType sit
241  = SecondIteratorType ( inputImage, secondFunction, m_Seeds );
242  sit.GoToBegin();
243  while( !sit.IsAtEnd())
244  {
245  const InputPixelType pixelValue = sit.Get();
246  for(unsigned int i=0; i<dimension; i++)
247  {
248  const ComponentRealType pixelValueI = static_cast<ComponentRealType>( pixelValue[i] );
249  covariance[i][i] += pixelValueI * pixelValueI;
250  mean[i] += pixelValueI;
251  for(unsigned int j=i+1; j<dimension; j++)
252  {
253  const ComponentRealType pixelValueJ = static_cast<ComponentRealType>( pixelValue[j] );
254  const ComponentRealType product = pixelValueI * pixelValueJ;
255  covariance[i][j] += product;
256  covariance[j][i] += product;
257  }
258  }
259  ++num;
260  ++sit;
261  }
262  for(unsigned int ii=0; ii<dimension; ii++)
263  {
264  mean[ii] /= static_cast<double>(num);
265  for(unsigned int jj=0; jj<dimension; jj++)
266  {
267  covariance[ii][jj] /= static_cast<double>(num);
268  }
269  }
270 
271  for(unsigned int ik=0; ik<dimension; ik++)
272  {
273  for(unsigned int jk=0; jk<dimension; jk++)
274  {
275  covariance[ik][jk] -= mean[ik] * mean[jk];
276  }
277  }
278 
279  m_ThresholdFunction->SetMean( mean );
280  m_ThresholdFunction->SetCovariance( covariance );
281 
282 
283  // Rerun the segmentation, the iterator walks the output image,
284  // starting at the seed point. As the iterator walks, if the
285  // corresponding pixel in the input image (accessed via the
286  // "m_ThresholdFunction" assigned to the iterator) is within the [lower,
287  // upper] bounds prescribed, the pixel is added to the output
288  // segmentation and its neighbors become candidates for the
289  // iterator to walk.
290  outputImage->FillBuffer ( NumericTraits<OutputImagePixelType>::Zero );
291  IteratorType thirdIt = IteratorType ( outputImage, m_ThresholdFunction, m_Seeds );
292  thirdIt.GoToBegin();
293  try
294  {
295  while( !thirdIt.IsAtEnd())
296  {
297  thirdIt.Set(m_ReplaceValue);
298  ++thirdIt;
299  progress.CompletedPixel(); // potential exception thrown here
300  }
301 
302  }
303  catch( ProcessAborted & )
304  {
305  break; // interrupt the iterations loop
306  }
307 
308  } // end iteration loop
309 
310  if( this->GetAbortGenerateData() )
311  {
312  ProcessAborted e(__FILE__,__LINE__);
313  e.SetDescription("Process aborted.");
314  e.SetLocation(ITK_LOCATION);
315  throw e;
316  }
317 }
318 
319 
320 template <class TInputImage, class TOutputImage>
321 const typename
325 {
326  return m_ThresholdFunction->GetCovariance();
327 }
328 
329 template <class TInputImage, class TOutputImage>
330 const typename
333 ::GetMean() const
334 {
335  return m_ThresholdFunction->GetMean();
336 }
337 
338 
339 } // end namespace itk
340 
341 #endif

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