Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _itkLocalVariationImageFilter_txx
00017 #define _itkLocalVariationImageFilter_txx
00018 #include "itkLocalVariationImageFilter.h"
00019
00020 #include "itkConstShapedNeighborhoodIterator.h"
00021 #include "itkNeighborhoodInnerProduct.h"
00022 #include "itkImageRegionIterator.h"
00023 #include "itkNeighborhoodAlgorithm.h"
00024 #include "itkZeroFluxNeumannBoundaryCondition.h"
00025 #include "itkOffset.h"
00026 #include "itkProgressReporter.h"
00027 #include "itkVectorImage.h"
00028
00029 #include <vector>
00030 #include <algorithm>
00031
00032 namespace itk
00033 {
00034
00035 template <class TInputImage, class TOutputImage>
00036 LocalVariationImageFilter<TInputImage, TOutputImage>
00037 ::LocalVariationImageFilter()
00038 {}
00039
00040 template <class TInputImage, class TOutputImage>
00041 void
00042 LocalVariationImageFilter<TInputImage, TOutputImage>
00043 ::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError)
00044 {
00045
00046 Superclass::GenerateInputRequestedRegion();
00047
00048
00049 typename Superclass::InputImagePointer inputPtr =
00050 const_cast< TInputImage * >( this->GetInput() );
00051 typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
00052
00053 if ( !inputPtr || !outputPtr )
00054 {
00055 return;
00056 }
00057
00058
00059
00060 typename TInputImage::RegionType inputRequestedRegion;
00061 inputRequestedRegion = inputPtr->GetRequestedRegion();
00062
00063
00064 inputRequestedRegion.PadByRadius( 1 );
00065
00066
00067 if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
00068 {
00069 inputPtr->SetRequestedRegion( inputRequestedRegion );
00070 return;
00071 }
00072 else
00073 {
00074
00075
00076
00077
00078 inputPtr->SetRequestedRegion( inputRequestedRegion );
00079
00080
00081 InvalidRequestedRegionError e(__FILE__, __LINE__);
00082 e.SetLocation(ITK_LOCATION);
00083 e.SetDescription("Requested region outside possible region.");
00084 e.SetDataObject(inputPtr);
00085 throw e;
00086 }
00087 }
00088
00089 template<> double SquaredEuclideanMetric<itk::VariableLengthVector<float> >::
00090 Calc(itk::VariableLengthVector<float> p)
00091 {
00092 return p.GetSquaredNorm();
00093 }
00094
00095 template<> double SquaredEuclideanMetric<itk::VariableLengthVector<double> >::
00096 Calc(itk::VariableLengthVector<double> p)
00097 {
00098 return p.GetSquaredNorm();
00099 }
00100
00101 template<class TPixelType> double
00102 SquaredEuclideanMetric<TPixelType>::Calc(TPixelType p)
00103 {
00104 return p*p;
00105 }
00106
00107 template< class TInputImage, class TOutputImage>
00108 void
00109 LocalVariationImageFilter< TInputImage, TOutputImage>
00110 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
00111 int threadId)
00112 {
00113
00114
00115 typename OutputImageType::Pointer output = this->GetOutput();
00116 typename InputImageType::ConstPointer input = this->GetInput();
00117
00118 itk::Size<InputImageDimension> size;
00119 for( int i=0; i<InputImageDimension; i++)
00120 size[i] = 1;
00121
00122
00123 NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType> bC;
00124 typename NeighborhoodAlgorithm::
00125 ImageBoundaryFacesCalculator<InputImageType>::FaceListType
00126 faceList = bC(input, outputRegionForThread, size);
00127
00128
00129 ProgressReporter progress(
00130 this, threadId, outputRegionForThread.GetNumberOfPixels());
00131
00132 ZeroFluxNeumannBoundaryCondition<InputImageType> nbc;
00133 std::vector<InputPixelType> pixels;
00134
00135
00136
00137 for ( typename NeighborhoodAlgorithm::
00138 ImageBoundaryFacesCalculator<InputImageType>::FaceListType::iterator
00139 fit=faceList.begin(); fit != faceList.end(); ++fit)
00140 {
00141
00142
00143 ImageRegionIterator<OutputImageType>
00144 output_image_it(output, *fit);
00145 ImageRegionConstIterator<InputImageType>
00146 input_image_it(input.GetPointer(), *fit);
00147
00148
00149 ConstShapedNeighborhoodIterator<InputImageType>
00150 input_image_neighbors_it(size, input, *fit);
00151 typename ConstShapedNeighborhoodIterator<InputImageType>::
00152 OffsetType offset;
00153 input_image_neighbors_it.OverrideBoundaryCondition(&nbc);
00154 input_image_neighbors_it.ClearActiveList();
00155 for(int i=0; i<InputImageDimension; i++)
00156 {
00157 offset.Fill(0);
00158 offset[i] = -1;
00159 input_image_neighbors_it.ActivateOffset(offset);
00160 offset[i] = 1;
00161 input_image_neighbors_it.ActivateOffset(offset);
00162 }
00163 input_image_neighbors_it.GoToBegin();
00164
00165
00166 while ( ! input_image_neighbors_it.IsAtEnd() )
00167 {
00168
00169
00170 typename OutputImageType::PixelType locVariation = 0;
00171 typename ConstShapedNeighborhoodIterator<InputImageType>::
00172 ConstIterator input_neighbors_it;
00173 for (input_neighbors_it = input_image_neighbors_it.Begin();
00174 ! input_neighbors_it.IsAtEnd();
00175 input_neighbors_it++)
00176 {
00177 typename TInputImage::PixelType diffVec =
00178 input_neighbors_it.Get()-input_image_it.Get();
00179 locVariation += SquaredEuclideanMetric
00180 <typename TInputImage::PixelType>::Calc(diffVec);
00181 }
00182 locVariation = sqrt(locVariation + 0.0001);
00183 output_image_it.Set(locVariation);
00184
00185
00186 ++input_image_neighbors_it;
00187 ++output_image_it;
00188 ++input_image_it;
00189
00190
00191 progress.CompletedPixel();
00192 }
00193 }
00194 }
00195
00199 template <class TInputImage, class TOutput>
00200 void
00201 LocalVariationImageFilter<TInputImage, TOutput>
00202 ::PrintSelf(
00203 std::ostream& os,
00204 Indent indent) const
00205 {
00206 Superclass::PrintSelf( os, indent );
00207 }
00208
00209 }
00210
00211 #endif //_itkLocalVariationImageFilter_txx