X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=filters%2FclitkVFResampleGenericFilter.cxx;h=2cd6b7d58de51940ce383925687bbf9535c96345;hb=c8d53d40ac8f5f83843193c51ac1787a8f38ee90;hp=9eb995b836254593acf1457eaa0ea38b1f5d06ce;hpb=931a42358442f4ee4f314613c991c838d4b4e3b7;p=clitk.git diff --git a/filters/clitkVFResampleGenericFilter.cxx b/filters/clitkVFResampleGenericFilter.cxx index 9eb995b..2cd6b7d 100644 --- a/filters/clitkVFResampleGenericFilter.cxx +++ b/filters/clitkVFResampleGenericFilter.cxx @@ -1,20 +1,41 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +======================================================================-====*/ #ifndef CLITKVFRESAMPLEGENERICFILTER_CXX #define CLITKVFRESAMPLEGENERICFILTER_CXX - /** ------------------------------------------------------------------- * @file clitkVFResampleGenericFilter.cxx * @author David Sarrut * @date 23 Feb 2008 08:37:53 - * @brief + * @brief -------------------------------------------------------------------*/ #include "clitkVFResampleGenericFilter.h" //-------------------------------------------------------------------- -clitk::VFResampleGenericFilter::VFResampleGenericFilter() { +clitk::VFResampleGenericFilter::VFResampleGenericFilter(): + clitk::ImageToImageGenericFilter("VFResample") +{ + InitializeImageType<2>(); + InitializeImageType<3>(); + InitializeImageType<4>(); mApplyGaussianFilterBefore = false; mDefaultPixelValue = 0.0; mInterpolatorName = "NN"; @@ -22,48 +43,184 @@ clitk::VFResampleGenericFilter::VFResampleGenericFilter() { } //-------------------------------------------------------------------- + +//-------------------------------------------------------------------- +template +void clitk::VFResampleGenericFilter::InitializeImageType() +{ + ADD_IMAGE_TYPE(Dim, float); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void clitk::VFResampleGenericFilter::UpdateWithInputImageType() +{ + + if (m_NbOfComponents == 1) { + std::cerr << "Error, only one components ? Use clitkImageResample instead." << std::endl; + exit(0); + } + typedef typename ImageType::PixelType PixelType; + if (m_NbOfComponents == 2) Update_WithDimAndPixelTypeAndComponent(); + if (m_NbOfComponents == 3) Update_WithDimAndPixelTypeAndComponent(); + if (m_NbOfComponents == 4) Update_WithDimAndPixelTypeAndComponent(); +} //-------------------------------------------------------------------- -void clitk::VFResampleGenericFilter::Update() { - // Load image header - itk::ImageIOBase::Pointer header = clitk::readImageHeader(mInputFilenames[0]); - - // Determine dim, pixel type, number of components - mDim = header->GetNumberOfDimensions(); - mPixelTypeName = header->GetComponentTypeAsString(header->GetComponentType()); - mNbOfComponents = header->GetNumberOfComponents(); - // Switch by dimension - if (mDim == 2) { Update_WithDim<2>(); return; } - if (mDim == 3) { Update_WithDim<3>(); return; } - if (mDim == 4) { Update_WithDim<4>(); return; } - std::cerr << "Error, dimension of input image is " << mDim << ", but I only work with 2,3,4." << std::endl; - exit(0); +//-------------------------------------------------------------------- +template +void clitk::VFResampleGenericFilter::Update_WithDimAndPixelTypeAndComponent() +{ + // Reading input + typedef itk::Vector DisplacementType; + typedef itk::Image< DisplacementType, Dim > ImageType; + + typename ImageType::Pointer input = clitk::readImage(m_InputFilenames, m_IOVerbose); + + // Main filter + typename ImageType::Pointer outputImage = ComputeImage(input); + + // Write results + SetNextOutput(outputImage); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- -void clitk::VFResampleGenericFilter::SetOutputSize(const std::vector & size) { +template +typename ImageType::Pointer +clitk::VFResampleGenericFilter::ComputeImage(typename ImageType::Pointer inputImage) +{ + + // Check options + static unsigned int dim = ImageType::ImageDimension; + if (mOutputSize.size() != dim) { + std::cerr << "Please set size with " << dim << " dimensions." << std::endl; + return NULL; + } + if (mOutputSpacing.size() != dim) { + std::cerr << "Please set spacing with " << dim << " dimensions." << std::endl; + return NULL; + } + mOutputOrigin.resize(dim); + + if (mApplyGaussianFilterBefore && mSigma.size() != dim) { + std::cerr << "Please set sigma with " << dim << " dimensions." << std::endl; + return NULL; + } + + // Some typedefs + typedef typename ImageType::SizeType SizeType; + typedef typename ImageType::SpacingType SpacingType; + typedef typename ImageType::PointType PointType; + + // Create Image Filter + typedef itk::VectorResampleImageFilter FilterType; + typename FilterType::Pointer filter = FilterType::New(); + + // Instance of the transform object to be passed to the resample + // filter. By default, identity transform is applied + typedef itk::AffineTransform TransformType; + typename TransformType::Pointer transform = TransformType::New(); + filter->SetTransform(transform); + + // Set filter's parameters + SizeType outputSize; + SpacingType outputSpacing; + PointType outputOrigin; + for(unsigned int i=0; iGetOrigin()[i]; + } + + filter->SetSize(outputSize); + filter->SetOutputSpacing(outputSpacing); + filter->SetOutputOrigin(outputOrigin); + filter->SetDefaultPixelValue(static_cast(mDefaultPixelValue)); + + // Select interpolator + if (mInterpolatorName == "nn") { + typedef itk::VectorNearestNeighborInterpolateImageFunction InterpolatorType; + typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); + filter->SetInterpolator(interpolator); + } else { + if (mInterpolatorName == "linear") { + typedef itk::VectorLinearInterpolateImageFunction InterpolatorType; + typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); + filter->SetInterpolator(interpolator); + } else { + std::cerr << "Sorry, I do not know the interpolator (for vector field) '" << mInterpolatorName + << "'. Known interpolators are : nn, linear" << std::endl; + exit(0); + } + } + + // Build initial Gaussian bluring (if needed) + typedef itk::RecursiveGaussianImageFilter GaussianFilterType; + std::vector gaussianFilters; + if (mApplyGaussianFilterBefore) { + for(unsigned int i=0; iSetDirection(i); + gaussianFilters[i]->SetOrder(GaussianFilterType::ZeroOrder); + gaussianFilters[i]->SetNormalizeAcrossScale(false); + gaussianFilters[i]->SetSigma(mSigma[i]); // in millimeter ! + // Set input + if (i==0) gaussianFilters[i]->SetInput(inputImage); + else gaussianFilters[i]->SetInput(gaussianFilters[i-1]->GetOutput()); + } + filter->SetInput(gaussianFilters[ImageType::ImageDimension-1]->GetOutput()); + } else { + filter->SetInput(inputImage); + } + + // Go ! + try { + filter->Update(); + } catch( itk::ExceptionObject & err ) { + std::cerr << "Error while filtering " << m_InputFilenames[0].c_str() + << " " << err << std::endl; + exit(0); + } + + // Return result + return filter->GetOutput(); + +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::VFResampleGenericFilter::SetOutputSize(const std::vector & size) +{ mOutputSize.resize(size.size()); std::copy(size.begin(), size.end(), mOutputSize.begin()); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- -void clitk::VFResampleGenericFilter::SetOutputSpacing(const std::vector & spacing) { +void clitk::VFResampleGenericFilter::SetOutputSpacing(const std::vector & spacing) +{ mOutputSpacing.resize(spacing.size()); std::copy(spacing.begin(), spacing.end(), mOutputSpacing.begin()); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- -void clitk::VFResampleGenericFilter::SetInterpolationName(const std::string & inter) { +void clitk::VFResampleGenericFilter::SetInterpolationName(const std::string & inter) +{ mInterpolatorName = inter; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- -void clitk::VFResampleGenericFilter::SetGaussianSigma(const std::vector & sigma) { +void clitk::VFResampleGenericFilter::SetGaussianSigma(const std::vector & sigma) +{ mApplyGaussianFilterBefore = true; mSigma.resize(sigma.size()); std::copy(sigma.begin(), sigma.end(), mSigma.begin());