/*=================================================================== 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://www.centreleonberard.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 __clitkMultipleBSplineDeformableTransformInitializer_txx #define __clitkMultipleBSplineDeformableTransformInitializer_txx #include "clitkMultipleBSplineDeformableTransformInitializer.h" namespace clitk { template < class TTransform, class TImage > MultipleBSplineDeformableTransformInitializer ::MultipleBSplineDeformableTransformInitializer() { this->m_NumberOfControlPointsInsideTheImage.Fill( 5 ); this->m_ControlPointSpacing.Fill(64.); this->m_ChosenSpacing.Fill(64.); m_NumberOfControlPointsIsGiven=false; m_ControlPointSpacingIsGiven=false; m_TransformRegionIsGiven=false; m_SamplingFactorIsGiven=false; m_SplineOrders.Fill(3); m_Parameters=NULL; } template < class TTransform, class TImage > void MultipleBSplineDeformableTransformInitializer ::InitializeTransform() { // Sanity check: // The image is required for the region and spacing if( ! this->m_Image ) { itkExceptionMacro( "Reference Image has not been set" ); return; } // A pointer to the transform is required if( ! this->m_Transform ) { itkExceptionMacro( "Transform has not been set" ); return; } // If the image come from a filter, then update that filter. if( this->m_Image->GetSource() ) { this->m_Image->GetSource()->Update(); } //-------------------------------------- // Spacing & Size on image //-------------------------------------- SpacingType fixedImageSpacing = m_Image->GetSpacing(); SizeType fixedImageSize=m_Image->GetLargestPossibleRegion().GetSize(); typename RegionType::SizeType gridBorderSize; typename RegionType::SizeType totalGridSize; // Only spacing given: adjust if necessary if (m_ControlPointSpacingIsGiven && !m_NumberOfControlPointsIsGiven) { for(unsigned int r=0; r(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ; m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ); if ( ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) ) == ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) ) { m_NumberOfControlPointsInsideTheImage[r] +=1; DD("Adding control point"); } } } // Only number of CP given: adjust if necessary // JV -1 ? else if (!m_ControlPointSpacingIsGiven && m_NumberOfControlPointsIsGiven) { for(unsigned int r=0; rTransformIndexToPhysicalPoint(m_Image->GetLargestPossibleRegion().GetIndex(),fixedImageOrigin); typename ImageType::DirectionType gridDirection = m_Image->GetDirection(); SizeType orderShift; // Shift depends on order for(unsigned int r=0; rm_Transform->SetSplineOrders(m_SplineOrders); this->m_Transform->SetGridRegion( gridRegion ); this->m_Transform->SetGridOrigin( gridOrigin ); this->m_Transform->SetGridSpacing( m_ControlPointSpacing ); this->m_Transform->SetGridDirection( gridDirection ); this->m_Transform->SetLUTSamplingFactors(m_SamplingFactors); } template < class TTransform, class TImage > void MultipleBSplineDeformableTransformInitializer ::SetInitialParameters( const std::string& s, ParametersType& params) { //--------------------------------------- // Read Initial parameters //--------------------------------------- typedef itk::ImageFileReader CoefficientReaderType; typename CoefficientReaderType::Pointer coeffReader = CoefficientReaderType::New(); std::vector coefficientImages; unsigned nLabels = m_Transform->GetnLabels(); coefficientImages.resize(nLabels); int dotpos = s.length() - 1; while (dotpos >= 0 && s[dotpos] != '.') dotpos--; for (unsigned i = 0; i < nLabels; ++i) { std::ostringstream osfname; osfname << s.substr(0, dotpos) << '_' << i << s.substr(dotpos); coeffReader->SetFileName(osfname.str()); if (m_Verbose) std::cout << "Reading initial coefficients from file: " << osfname.str() << "..." << std::endl; coeffReader->Update(); coefficientImages[i] = coeffReader->GetOutput(); } this->SetInitialParameters(coefficientImages, params); } template < class TTransform, class TImage > void MultipleBSplineDeformableTransformInitializer ::SetInitialParameters(std::vector coefficientImages, ParametersType& params) { // Keep a reference m_Parameters=¶ms; // Resample typedef ResampleBSplineDeformableTransformImageFilter ResamplerType; typename ResamplerType::Pointer resampler; unsigned int i = 0; for (unsigned l = 0; l < coefficientImages.size(); ++l) { typename ResamplerType::Pointer resampler = ResamplerType::New(); resampler->SetInput(coefficientImages[l]); resampler->SetOutputParametersFromImage(m_Transform->GetCoefficientImages()[l]); if (m_Verbose) std::cout << "Resampling initial coefficients..." << std::endl; resampler->Update(); // Copy parameters into the existing array, I know its crappy typedef itk::ImageRegionConstIterator Iterator; Iterator it(resampler->GetOutput(), resampler->GetOutput()->GetLargestPossibleRegion()); it.GoToBegin(); while (!it.IsAtEnd()) { for (unsigned int j = 0; j < InputDimension; ++j) params[i + j] = it.Get()[j]; ++it; i += InputDimension; } } // JV pass the reference to the array !! this->m_Transform->SetParameters(params); } } // namespace itk #endif