1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
18 #ifndef __clitkBSplineDeformableTransformInitializer_txx
19 #define __clitkBSplineDeformableTransformInitializer_txx
20 #include "clitkBSplineDeformableTransformInitializer.h"
26 template < class TTransform, class TImage >
27 BSplineDeformableTransformInitializer<TTransform, TImage >
28 ::BSplineDeformableTransformInitializer()
30 this->m_NumberOfControlPointsInsideTheImage.Fill( 5 );
31 this->m_ControlPointSpacing.Fill(64.);
32 this->m_ChosenSpacing.Fill(64.);
33 m_NumberOfControlPointsIsGiven=false;
34 m_ControlPointSpacingIsGiven=false;
35 m_TransformRegionIsGiven=false;
36 m_SamplingFactorIsGiven=false;
37 m_SplineOrders.Fill(3);
41 template < class TTransform, class TImage >
43 BSplineDeformableTransformInitializer<TTransform, TImage >
44 ::InitializeTransform()
47 // The image is required for the region and spacing
50 itkExceptionMacro( "Reference Image has not been set" );
54 // A pointer to the transform is required
55 if( ! this->m_Transform )
57 itkExceptionMacro( "Transform has not been set" );
61 // If the image come from a filter, then update that filter.
62 if( this->m_Image->GetSource() )
64 this->m_Image->GetSource()->Update();
68 //--------------------------------------
69 // Spacing & Size on image
70 //--------------------------------------
71 SpacingType fixedImageSpacing = m_Image->GetSpacing();
72 SizeType fixedImageSize=m_Image->GetLargestPossibleRegion().GetSize();
73 typename RegionType::SizeType gridBorderSize;
74 typename RegionType::SizeType totalGridSize;
76 // Only spacing given: adjust if necessary
77 if (m_ControlPointSpacingIsGiven && !m_NumberOfControlPointsIsGiven)
79 for(unsigned int r=0; r<InputDimension; r++)
82 m_ChosenSpacing[r]= m_ControlPointSpacing[r];
83 m_ControlPointSpacing[r]= ( round(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
84 m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] );
85 if ( ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
86 == ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
88 m_NumberOfControlPointsInsideTheImage[r] +=1;
89 DD("Adding control point");
94 // Only number of CP given: adjust if necessary
96 else if (!m_ControlPointSpacingIsGiven && m_NumberOfControlPointsIsGiven)
98 for(unsigned int r=0; r<InputDimension; r++)
100 m_ChosenSpacing[r]=fixedImageSpacing[r]*( (double)(fixedImageSize[r]) /
101 (double)(m_NumberOfControlPointsInsideTheImage[r]) );
102 m_ControlPointSpacing[r]= fixedImageSpacing[r]* ceil( (double)(fixedImageSize[r] - 1) /
103 (double)(m_NumberOfControlPointsInsideTheImage[r] - 1) );
107 // Both or none of Spacing and number of CP given: no adjustment adjust, just warnings
110 for(unsigned int r=0; r<InputDimension; r++)
112 m_ChosenSpacing[r]= m_ControlPointSpacing[r];
113 if (m_NumberOfControlPointsInsideTheImage[r]*m_ControlPointSpacing[r]< fixedImageSize[r]*fixedImageSpacing[r])
115 std::cout<<"WARNING: Specified control point region ("<<m_NumberOfControlPointsInsideTheImage[r]*m_ControlPointSpacing[r]
116 <<"mm) does not cover the fixed image region ("<< fixedImageSize[r]*fixedImageSpacing[r]
117 <<"mm) for dimension "<<r<<"!" <<std::endl
118 <<"Specify only --spacing or --control for automatic adjustment..."<<std::endl;
120 if ( fmod(m_ControlPointSpacing[r], fixedImageSpacing[r]) )
122 std::cout<<"WARNING: Specified control point spacing for dimension "<<r
123 <<" does not allow exact representation of BLUT FFD!"<<std::endl
124 <<"Spacing ratio is non-integer: "<<m_ControlPointSpacing[r]/ fixedImageSpacing[r]<<std::endl
125 <<"Specify only --spacing or --control for automatic adjustment..."<<std::endl;
130 if (m_Verbose) std::cout<<"The chosen control point spacing "<<m_ChosenSpacing<<"..."<<std::endl;
131 if (m_Verbose) std::cout<<"The control points spacing was adapted to "<<m_ControlPointSpacing<<"..."<<std::endl;
132 if (m_Verbose) std::cout<<"The number of (internal) control points is "<<m_NumberOfControlPointsInsideTheImage<<"..."<<std::endl;
135 //--------------------------------------
137 //--------------------------------------
138 for(unsigned int r=0; r<InputDimension; r++) gridBorderSize[r]=m_SplineOrders[r]; // Border for spline order = 3 ( 1 lower, 2 upper )
139 totalGridSize = m_NumberOfControlPointsInsideTheImage + gridBorderSize;
140 if (m_Verbose) std::cout<<"The total control point grid size was set to "<<totalGridSize<<"..."<<std::endl;
141 RegionType gridRegion;
142 gridRegion.SetSize(totalGridSize);
145 //--------------------------------------
147 //--------------------------------------
148 typedef typename TransformType::OriginType OriginType;
149 OriginType fixedImageOrigin, gridOrigin;
151 // In case of non-zero index
152 m_Image->TransformIndexToPhysicalPoint(m_Image->GetLargestPossibleRegion().GetIndex(),fixedImageOrigin);
153 typename ImageType::DirectionType gridDirection = m_Image->GetDirection();
156 // Shift depends on order
157 for(unsigned int r=0; r<InputDimension; r++)
159 orderShift[r] = m_SplineOrders[r] / 2;
160 gridOrigin[r] = fixedImageOrigin[r]- (double) orderShift[r]* m_ControlPointSpacing[r];
162 if (m_Verbose) std::cout<<"The control point grid origin was set to "<<gridOrigin<<"..."<<std::endl;
165 //--------------------------------------
166 // LUT sampling factors
167 //--------------------------------------
168 for (unsigned int i=0; i< InputDimension; i++)
170 if (m_Verbose) std::cout<<"For dimension "<<i<<", the ideal sampling factor (if integer) is a multitude of "
171 << m_ControlPointSpacing[i]/ fixedImageSpacing[i]<<"..."<<std::endl;
172 if ( !m_SamplingFactorIsGiven) m_SamplingFactors[i]= (int) ( m_ControlPointSpacing[i]/ fixedImageSpacing[i]);
173 if (m_Verbose) std::cout<<"Setting sampling factor "<<i<<" to "<<m_SamplingFactors[i]<<"..."<<std::endl;
177 //--------------------------------------
179 //--------------------------------------
180 this->m_Transform->SetSplineOrders(m_SplineOrders);
181 this->m_Transform->SetGridRegion( gridRegion );
182 this->m_Transform->SetGridOrigin( gridOrigin );
183 this->m_Transform->SetGridSpacing( m_ControlPointSpacing );
184 this->m_Transform->SetGridDirection( gridDirection );
185 this->m_Transform->SetLUTSamplingFactors(m_SamplingFactors);
189 template < class TTransform, class TImage >
191 BSplineDeformableTransformInitializer<TTransform, TImage >
192 ::SetInitialParameters( const std::string& s, ParametersType& params)
194 //---------------------------------------
195 // Read Initial parameters
196 //---------------------------------------
197 typedef itk::ImageFileReader<CoefficientImageType> CoefficientReaderType;
198 typename CoefficientReaderType::Pointer coeffReader=CoefficientReaderType::New();
199 coeffReader->SetFileName(s);
200 if(m_Verbose) std::cout<<"Reading initial coefficients from file: "<<s<<"..."<<std::endl;
201 coeffReader->Update();
202 typename CoefficientImageType::Pointer coefficientImage=coeffReader->GetOutput();
203 this->SetInitialParameters(coefficientImage, params);
206 template < class TTransform, class TImage >
208 BSplineDeformableTransformInitializer<TTransform, TImage >
209 ::SetInitialParameters(const typename CoefficientImageType::Pointer coefficientImage, ParametersType& params)
212 m_Parameters=¶ms;
215 typedef ResampleBSplineDeformableTransformImageFilter<CoefficientImageType,CoefficientImageType> ResamplerType;
216 typename ResamplerType::Pointer resampler=ResamplerType::New();
217 resampler->SetInput(coefficientImage);
218 resampler->SetOutputParametersFromImage(m_Transform->GetCoefficientImage());
219 if(m_Verbose) std::cout<<"Resampling initial coefficients..."<<std::endl;
222 // Copy parameters into the existing array, I know its crappy
223 typedef itk::ImageRegionConstIterator<CoefficientImageType> Iterator;
224 Iterator it (resampler->GetOutput(), resampler->GetOutput()->GetLargestPossibleRegion() );
227 while(! it.IsAtEnd())
229 for (unsigned int j=0; j<InputDimension;j++)
230 params[i+j]=it.Get()[j];
236 // JV pass the reference to the array !!
237 this->m_Transform->SetParameters(params);