Orfeo Toolbox  3.16
itkLaplacianSharpeningImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkLaplacianSharpeningImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2008-10-16 17:40:09 $
7  Version: $Revision: 1.5 $
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 __itkLaplacianSharpeningImageFilter_txx
18 #define __itkLaplacianSharpeningImageFilter_txx
20 
22 #include "itkLaplacianOperator.h"
24 #include "itkProgressAccumulator.h"
26 #include "itkImageRegionIterator.h"
27 
28 namespace itk
29 {
30 
31 template< class TInputImage, class TOutputImage >
32 void
34 ::PrintSelf(std::ostream& os, Indent indent) const
35 {
36  Superclass::PrintSelf(os,indent);
37  os << indent << "UseImageSpacing = " << m_UseImageSpacing << std::endl;
38 }
39 
40 
41 template <class TInputImage, class TOutputImage>
42 void
45 {
46  // call the superclass' implementation of this method. this should
47  // copy the output requested region to the input requested region
48  Superclass::GenerateInputRequestedRegion();
49 
50  // get pointers to the input and output
51  InputImagePointer inputPtr =
52  const_cast< TInputImage * > ( this->GetInput() );
53 
54  if ( !inputPtr )
55  {
56  return;
57  }
58 
59  // Build an operator so that we can determine the kernel size
61  oper.CreateOperator();
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( oper.GetRadius() );
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  InvalidRequestedRegionError e(__FILE__, __LINE__);
87  e.SetLocation(ITK_LOCATION);
88  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
89  e.SetDataObject(inputPtr);
90  throw e;
91  }
92 }
93 
94 template< class TInputImage, class TOutputImage >
95 void
98 {
99  // Create the Laplacian operator
101  double s[ImageDimension];
102  for (unsigned i = 0; i < ImageDimension; i++)
103  {
104  if (this->GetInput()->GetSpacing()[i] == 0.0 )
105  {
106  itkExceptionMacro( << "Image spacing cannot be zero" );
107  }
108  else
109  {
110  s[i] = 1.0 / this->GetInput()->GetSpacing()[i];
111  }
112  }
113  oper.SetDerivativeScalings( s );
114  oper.CreateOperator();
115 
116  // do calculations in floating point
117  typedef Image<RealType, ImageDimension> RealImageType;
120 
121  typename NOIF::Pointer filter = NOIF::New();
122  filter->OverrideBoundaryCondition(static_cast<typename NOIF::ImageBoundaryConditionPointerType>(&nbc));
123 
124  // Create a process accumulator for tracking the progress of this minipipeline
126  progress->SetMiniPipelineFilter(this);
127 
128  // Register the filter with the with progress accumulator using
129  // equal weight proportion
130  progress->RegisterInternalFilter(filter,0.8f);
131 
132  //
133  // set up the mini-pipline
134  //
135  filter->SetOperator(oper);
136  filter->SetInput(this->GetInput());
137  filter->GetOutput()
138  ->SetRequestedRegion( this->GetOutput()->GetRequestedRegion() );
139 
140  // execute the mini-pipeline
141  filter->Update();
142 
143  // determine how the data will need to scaled to be properly combined
148 
149  inputCalculator->SetImage(this->GetInput());
150  inputCalculator->SetRegion(this->GetOutput()->GetRequestedRegion());
151  inputCalculator->Compute();
152 
153  filteredCalculator->SetImage(filter->GetOutput());
154  filteredCalculator->SetRegion(this->GetOutput()->GetRequestedRegion());
155  filteredCalculator->Compute();
156 
157  RealType inputShift, inputScale, filteredShift, filteredScale;
158  inputShift = static_cast<RealType>(inputCalculator->GetMinimum());
159  inputScale = static_cast<RealType>(inputCalculator->GetMaximum())
160  - static_cast<RealType>(inputCalculator->GetMinimum());
161 
162  filteredShift = filteredCalculator->GetMinimum(); // no need to cast
163  filteredScale = filteredCalculator->GetMaximum()
164  - filteredCalculator->GetMinimum();
165 
167  it(filter->GetOutput(), filter->GetOutput()->GetRequestedRegion());
169  inIt(this->GetInput(), this->GetOutput()->GetRequestedRegion());
170 
171  // combine the input and laplacian images
172  RealType value, invalue;
173  RealType inputSum = 0.0;
174  RealType enhancedSum = 0.0;
175  while ( !it.IsAtEnd() )
176  {
177  value = it.Get(); // laplacian value
178 
179  // rescale to [0,1]
180  value = (value - filteredShift) / filteredScale;
181 
182  // rescale to the input dynamic range
183  value = value * inputScale + inputShift;
184 
185  // combine the input and laplacian image (note that we subtract
186  // the laplacian due to the signs in our laplacian kernel).
187  invalue = static_cast<RealType>(inIt.Get());
188  value = invalue - value;
189  it.Set( value );
190 
191  inputSum += invalue;
192  enhancedSum += value;
193  ++it;
194  ++inIt;
195  }
196  RealType inputMean = inputSum
197  / static_cast<RealType>(this->GetOutput()->GetRequestedRegion()
198  .GetNumberOfPixels());
199  RealType enhancedMean = enhancedSum
200  / static_cast<RealType>(this->GetOutput()->GetRequestedRegion()
201  .GetNumberOfPixels());
202 
203  // update progress
204  this->UpdateProgress( 0.9 );
205 
206  // copy and cast the output
207  typename TOutputImage::Pointer output = this->GetOutput();
208  output->SetBufferedRegion(output->GetRequestedRegion());
209  output->Allocate();
210 
211  RealType inputMinimum = inputCalculator->GetMinimum();
212  RealType inputMaximum = inputCalculator->GetMaximum();
213  OutputPixelType castInputMinimum
214  = static_cast<OutputPixelType>(inputMinimum);
215  OutputPixelType castInputMaximum
216  = static_cast<OutputPixelType>(inputMaximum);
217 
220  output->GetRequestedRegion());
221  outIt.GoToBegin();
222  it.GoToBegin();
223  while (!outIt.IsAtEnd())
224  {
225  value = it.Get();
226 
227  // adjust value to make the mean intensities before and after match
228  value = value - enhancedMean + inputMean;
229 
230  if (value < inputMinimum)
231  {
232  outIt.Set( castInputMinimum );
233  }
234  else if (value > inputMaximum)
235  {
236  outIt.Set( castInputMaximum );
237  }
238  else
239  {
240  outIt.Set( static_cast<OutputPixelType>(value) );
241  }
242 
243  ++outIt;
244  ++it;
245  }
246 
247  // update progress
248  this->UpdateProgress( 1.0 );
249 }
250 
251 } // end namespace itk
252 
253 #endif

Generated at Sat Feb 2 2013 23:50:58 for Orfeo Toolbox with doxygen 1.8.1.1