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://www.centreleonberard.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"
27 template < class TTransform, class TImage >
28 BSplineDeformableTransformInitializer<TTransform, TImage >
29 ::BSplineDeformableTransformInitializer()
31 this->m_NumberOfControlPointsInsideTheImage.Fill( 5 );
32 this->m_ControlPointSpacing.Fill(64.);
33 this->m_ChosenSpacing.Fill(64.);
34 m_NumberOfControlPointsIsGiven=false;
35 m_ControlPointSpacingIsGiven=false;
36 m_TransformRegionIsGiven=false;
37 m_SamplingFactorIsGiven=false;
38 m_SplineOrders.Fill(3);
42 template < class TTransform, class TImage >
44 BSplineDeformableTransformInitializer<TTransform, TImage >
45 ::InitializeTransform()
48 // The image is required for the region and spacing
51 itkExceptionMacro( "Reference Image has not been set" );
55 // A pointer to the transform is required
56 if( ! this->m_Transform )
58 itkExceptionMacro( "Transform has not been set" );
62 // If the image come from a filter, then update that filter.
63 if( this->m_Image->GetSource() )
65 this->m_Image->GetSource()->Update();
69 //--------------------------------------
70 // Spacing & Size on image
71 //--------------------------------------
72 SpacingType fixedImageSpacing = m_Image->GetSpacing();
73 SizeType fixedImageSize=m_Image->GetLargestPossibleRegion().GetSize();
74 typename RegionType::SizeType gridBorderSize;
75 typename RegionType::SizeType totalGridSize;
77 // Only spacing given: adjust if necessary
78 if (m_ControlPointSpacingIsGiven && !m_NumberOfControlPointsIsGiven)
80 for(unsigned int r=0; r<InputDimension; r++)
83 m_ChosenSpacing[r]= m_ControlPointSpacing[r];
84 m_ControlPointSpacing[r]= ( itk::Math::Round<double>(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
85 m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] );
86 if ( ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
87 == ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
89 m_NumberOfControlPointsInsideTheImage[r] +=1;
90 DD("Adding control point");
95 // Only number of CP given: adjust if necessary
97 else if (!m_ControlPointSpacingIsGiven && m_NumberOfControlPointsIsGiven)
99 for(unsigned int r=0; r<InputDimension; r++)
101 m_ChosenSpacing[r]=fixedImageSpacing[r]*( (double)(fixedImageSize[r]) /
102 (double)(m_NumberOfControlPointsInsideTheImage[r]) );
103 m_ControlPointSpacing[r]= fixedImageSpacing[r]* ceil( (double)(fixedImageSize[r] - 1) /
104 (double)(m_NumberOfControlPointsInsideTheImage[r] - 1) );
108 // Both or none of Spacing and number of CP given: no adjustment adjust, just warnings
111 for(unsigned int r=0; r<InputDimension; r++)
113 m_ChosenSpacing[r]= m_ControlPointSpacing[r];
114 if (m_NumberOfControlPointsInsideTheImage[r]*m_ControlPointSpacing[r]< fixedImageSize[r]*fixedImageSpacing[r])
116 std::cout<<"WARNING: Specified control point region ("<<m_NumberOfControlPointsInsideTheImage[r]*m_ControlPointSpacing[r]
117 <<"mm) does not cover the fixed image region ("<< fixedImageSize[r]*fixedImageSpacing[r]
118 <<"mm) for dimension "<<r<<"!" <<std::endl
119 <<"Specify only --spacing or --control for automatic adjustment..."<<std::endl;
121 if ( fmod(m_ControlPointSpacing[r], fixedImageSpacing[r]) )
123 std::cout<<"WARNING: Specified control point spacing for dimension "<<r
124 <<" does not allow exact representation of BLUT FFD!"<<std::endl
125 <<"Spacing ratio is non-integer: "<<m_ControlPointSpacing[r]/ fixedImageSpacing[r]<<std::endl
126 <<"Specify only --spacing or --control for automatic adjustment..."<<std::endl;
131 if (m_Verbose) std::cout<<"The chosen control point spacing "<<m_ChosenSpacing<<"..."<<std::endl;
132 if (m_Verbose) std::cout<<"The control points spacing was adapted to "<<m_ControlPointSpacing<<"..."<<std::endl;
133 if (m_Verbose) std::cout<<"The number of (internal) control points is "<<m_NumberOfControlPointsInsideTheImage<<"..."<<std::endl;
136 //--------------------------------------
138 //--------------------------------------
139 for(unsigned int r=0; r<InputDimension; r++) gridBorderSize[r]=m_SplineOrders[r]; // Border for spline order = 3 ( 1 lower, 2 upper )
140 totalGridSize = m_NumberOfControlPointsInsideTheImage + gridBorderSize;
141 if (m_Verbose) std::cout<<"The total control point grid size was set to "<<totalGridSize<<"..."<<std::endl;
142 RegionType gridRegion;
143 gridRegion.SetSize(totalGridSize);
146 //--------------------------------------
148 //--------------------------------------
149 typedef typename TransformType::OriginType OriginType;
150 OriginType fixedImageOrigin, gridOrigin;
152 // In case of non-zero index
153 m_Image->TransformIndexToPhysicalPoint(m_Image->GetLargestPossibleRegion().GetIndex(),fixedImageOrigin);
154 typename ImageType::DirectionType gridDirection = m_Image->GetDirection();
157 // Shift depends on order
158 for(unsigned int r=0; r<InputDimension; r++)
160 orderShift[r] = m_SplineOrders[r] / 2;
161 gridOrigin[r] = fixedImageOrigin[r]- (double) orderShift[r]* m_ControlPointSpacing[r];
163 if (m_Verbose) std::cout<<"The control point grid origin was set to "<<gridOrigin<<"..."<<std::endl;
166 //--------------------------------------
167 // LUT sampling factors
168 //--------------------------------------
169 for (unsigned int i=0; i< InputDimension; i++)
171 if (m_Verbose) std::cout<<"For dimension "<<i<<", the ideal sampling factor (if integer) is a multitude of "
172 << m_ControlPointSpacing[i]/ fixedImageSpacing[i]<<"..."<<std::endl;
173 if ( !m_SamplingFactorIsGiven) m_SamplingFactors[i]= (int) ( m_ControlPointSpacing[i]/ fixedImageSpacing[i]);
174 if (m_Verbose) std::cout<<"Setting sampling factor "<<i<<" to "<<m_SamplingFactors[i]<<"..."<<std::endl;
178 //--------------------------------------
180 //--------------------------------------
181 this->m_Transform->SetSplineOrders(m_SplineOrders);
182 this->m_Transform->SetGridRegion( gridRegion );
183 this->m_Transform->SetGridOrigin( gridOrigin );
184 this->m_Transform->SetGridSpacing( m_ControlPointSpacing );
185 this->m_Transform->SetGridDirection( gridDirection );
186 this->m_Transform->SetLUTSamplingFactors(m_SamplingFactors);
190 template < class TTransform, class TImage >
192 BSplineDeformableTransformInitializer<TTransform, TImage >
193 ::SetInitialParameters( const std::string& s, ParametersType& params)
195 //---------------------------------------
196 // Read Initial parameters
197 //---------------------------------------
198 typedef itk::ImageFileReader<CoefficientImageType> CoefficientReaderType;
199 typename CoefficientReaderType::Pointer coeffReader=CoefficientReaderType::New();
200 coeffReader->SetFileName(s);
201 if(m_Verbose) std::cout<<"Reading initial coefficients from file: "<<s<<"..."<<std::endl;
202 coeffReader->Update();
203 typename CoefficientImageType::Pointer coefficientImage=coeffReader->GetOutput();
204 this->SetInitialParameters(coefficientImage, params);
207 template < class TTransform, class TImage >
209 BSplineDeformableTransformInitializer<TTransform, TImage >
210 ::SetInitialParameters(const typename CoefficientImageType::Pointer coefficientImage, ParametersType& params)
213 m_Parameters=¶ms;
216 typedef ResampleBSplineDeformableTransformImageFilter<CoefficientImageType,CoefficientImageType> ResamplerType;
217 typename ResamplerType::Pointer resampler=ResamplerType::New();
218 resampler->SetInput(coefficientImage);
219 resampler->SetOutputParametersFromImage(m_Transform->GetCoefficientImage());
220 if(m_Verbose) std::cout<<"Resampling initial coefficients..."<<std::endl;
223 // Copy parameters into the existing array, I know its crappy
224 typedef itk::ImageRegionConstIterator<CoefficientImageType> Iterator;
225 Iterator it (resampler->GetOutput(), resampler->GetOutput()->GetLargestPossibleRegion() );
228 while(! it.IsAtEnd())
230 for (unsigned int j=0; j<InputDimension;j++)
231 params[i+j]=it.Get()[j];
237 // JV pass the reference to the array !!
238 this->m_Transform->SetParameters(params);