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 clitkWarpImageGenericFilter_txx
19 #define clitkWarpImageGenericFilter_txx
21 /* =================================================
22 * @file clitkWarpImageGenericFilter.txx
28 ===================================================*/
30 #include "itkVectorResampleImageFilter.h"
31 #include "clitkBSplineDeformableTransform.h"
32 #if ITK_VERSION_MAJOR >= 4
33 #include "itkTransformToDisplacementFieldSource.h"
35 #include "itkTransformToDeformationFieldSource.h"
41 //-------------------------------------------------------------------
42 // Update with the number of dimensions
43 //-------------------------------------------------------------------
44 template<unsigned int Dimension>
46 WarpImageGenericFilter::UpdateWithDim(std::string PixelType)
48 if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
50 if(PixelType == "short") {
51 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
52 UpdateWithDimAndPixelType<Dimension, signed short>();
54 // else if(PixelType == "unsigned_short"){
55 // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
56 // UpdateWithDimAndPixelType<Dimension, unsigned short>();
59 else if (PixelType == "unsigned_char") {
60 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
61 UpdateWithDimAndPixelType<Dimension, unsigned char>();
64 // else if (PixelType == "char"){
65 // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
66 // UpdateWithDimAndPixelType<Dimension, signed char>();
69 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
70 UpdateWithDimAndPixelType<Dimension, float>();
74 //-------------------------------------------------------------------
75 // Convert Coefficient image to DVF
76 //-------------------------------------------------------------------
77 template<class DisplacementFieldType>
78 typename DisplacementFieldType::Pointer
79 WarpImageGenericFilter::CoeffsToDVF(std::string fileName, std::string likeFileName)
81 typedef clitk::BSplineDeformableTransform<double, DisplacementFieldType::ImageDimension, DisplacementFieldType::ImageDimension> TransformType;
82 typedef typename TransformType::CoefficientImageType CoefficientImageType;
84 typedef itk::ImageFileReader<CoefficientImageType> CoeffReaderType;
85 typename CoeffReaderType::Pointer reader = CoeffReaderType::New();
86 reader->SetFileName(fileName);
89 typename TransformType::Pointer transform = TransformType::New();
90 transform->SetCoefficientImage(reader->GetOutput());
92 #if ITK_VERSION_MAJOR >= 4
93 typedef itk::TransformToDisplacementFieldSource<DisplacementFieldType, double> ConvertorType;
95 typedef itk::TransformToDeformationFieldSource<DisplacementFieldType, double> ConvertorType;
98 typedef itk::ImageIOBase ImageIOType;
99 typename ImageIOType::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(likeFileName.c_str(), itk::ImageIOFactory::ReadMode);
100 imageIO->SetFileName(likeFileName);
101 imageIO->ReadImageInformation();
103 typename ConvertorType::Pointer convertor= ConvertorType::New();
104 typename ConvertorType::SizeType output_size;
105 typename ConvertorType::SpacingType output_spacing;
106 typename ConvertorType::OriginType output_origin;
107 typename ConvertorType::DirectionType output_direction;
108 for (unsigned int i = 0; i < DisplacementFieldType::ImageDimension; i++) {
109 output_size[i] = imageIO->GetDimensions(i);
110 output_spacing[i] = imageIO->GetSpacing(i);
111 output_origin[i] = imageIO->GetOrigin(i);
112 for (unsigned int j = 0; j < DisplacementFieldType::ImageDimension; j++)
113 output_direction[i][j] = imageIO->GetDirection(i)[j];
117 std::cout << "Interpolating coefficients with grid:" << std::endl;
118 std::cout << output_size << output_spacing << std::endl;
121 convertor->SetNumberOfThreads(1);
122 convertor->SetTransform(transform);
123 convertor->SetOutputOrigin(output_origin);
124 convertor->SetOutputSpacing(output_spacing);
125 convertor->SetOutputSize(output_size);
126 convertor->SetOutputDirection(output_direction);
129 return convertor->GetOutput();
132 //-------------------------------------------------------------------
133 // Update with the number of dimensions and the pixeltype
134 //-------------------------------------------------------------------
135 template <unsigned int Dimension, class PixelType>
137 WarpImageGenericFilter::UpdateWithDimAndPixelType()
141 typedef itk::Image<PixelType, Dimension> InputImageType;
142 typedef itk::Image<PixelType, Dimension> OutputImageType;
143 typedef itk::Vector<float, Dimension> DisplacementType;
144 typedef itk::Image<DisplacementType, Dimension> DeformationFieldType;
147 typedef itk::ImageFileReader<InputImageType> InputReaderType;
148 typename InputReaderType::Pointer reader = InputReaderType::New();
149 reader->SetFileName( m_InputFileName);
151 typename InputImageType::Pointer input= reader->GetOutput();
153 typename DeformationFieldType::Pointer deformationField;
154 if (m_ArgsInfo.coeff_given) {
155 deformationField = CoeffsToDVF<DeformationFieldType>(m_ArgsInfo.coeff_arg, m_InputFileName);
158 //Read the deformation field
159 typedef itk::ImageFileReader<DeformationFieldType> DeformationFieldReaderType;
160 typename DeformationFieldReaderType::Pointer deformationFieldReader= DeformationFieldReaderType::New();
161 deformationFieldReader->SetFileName(m_ArgsInfo.vf_arg);
162 deformationFieldReader->Update();
163 deformationField =deformationFieldReader->GetOutput();
166 // Intensity interpolator
167 typedef clitk::GenericVectorInterpolator<args_info_clitkWarpImage, DeformationFieldType, double> GenericInterpolatorType;
168 typename GenericInterpolatorType::Pointer genericInterpolator=GenericInterpolatorType::New();
169 genericInterpolator->SetArgsInfo(m_ArgsInfo);
172 // -------------------------------------------
174 // -------------------------------------------
175 if (m_ArgsInfo.spacing_arg == 0) {
176 // Calculate the region
177 typename DeformationFieldType::SizeType newSize;
178 for (unsigned int i=0 ; i <Dimension; i++)
179 newSize[i]=(unsigned int) (input->GetLargestPossibleRegion().GetSize()[i]*input->GetSpacing()[i]/deformationField->GetSpacing()[i]);
181 // Get the interpolator
182 typedef clitk::GenericVectorInterpolator<args_info_clitkWarpImage, DeformationFieldType, double> GenericInterpolatorType;
183 typename GenericInterpolatorType::Pointer genericInterpolator=GenericInterpolatorType::New();
184 genericInterpolator->SetArgsInfo(m_ArgsInfo);
186 // Resample to match the extent of the input
187 typename itk::VectorResampleImageFilter<DeformationFieldType, DeformationFieldType >::Pointer
188 resampler =itk::VectorResampleImageFilter<DeformationFieldType, DeformationFieldType >::New();
189 resampler->SetInput(deformationField);
190 resampler->SetOutputSpacing(deformationField->GetSpacing());
191 resampler->SetSize(newSize);
192 resampler->SetOutputOrigin(input->GetOrigin());
193 resampler->SetInterpolator(genericInterpolator->GetInterpolatorPointer());
196 if (m_Verbose) std::cout<< "Resampling the VF..." <<std::endl;
199 } catch( itk::ExceptionObject & excp ) {
200 std::cerr << "Problem resampling the input vector field file" << std::endl;
201 std::cerr << excp << std::endl;
204 deformationField= resampler->GetOutput();
208 // -------------------------------------------
209 // Spacing like input
210 // -------------------------------------------
211 else if (!m_ArgsInfo.coeff_given) {
213 typename DeformationFieldType::SizeType newSize;
214 for (unsigned int i=0 ; i <Dimension; i++)
215 newSize[i]=input->GetLargestPossibleRegion().GetSize()[i];
217 // Resample to match the extent of the input
218 typename itk::VectorResampleImageFilter<DeformationFieldType, DeformationFieldType >::Pointer
219 resampler =itk::VectorResampleImageFilter<DeformationFieldType, DeformationFieldType >::New();
220 resampler->SetInput(deformationField);
221 resampler->SetOutputSpacing(input->GetSpacing());
222 resampler->SetSize(newSize);
223 resampler->SetOutputOrigin(input->GetOrigin());
224 resampler->SetInterpolator(genericInterpolator->GetInterpolatorPointer());
227 if (m_Verbose) std::cout<< "Resampling the VF..." <<std::endl;
230 } catch( itk::ExceptionObject & excp ) {
231 std::cerr << "Problem resampling the input vector field file" << std::endl;
232 std::cerr << excp << std::endl;
235 deformationField= resampler->GetOutput();
239 // -------------------------------------------
241 // -------------------------------------------
242 typename itk::ImageToImageFilter<InputImageType, InputImageType>::Pointer warpFilter;
243 if (m_ArgsInfo.forward_flag) {
244 //Forward warping: always linear
245 typedef clitk::ForwardWarpImageFilter<InputImageType, InputImageType, DeformationFieldType> ForwardWarpFilterType;
246 typename ForwardWarpFilterType::Pointer forwardWarpFilter= ForwardWarpFilterType::New();
247 forwardWarpFilter->SetDeformationField( deformationField );
248 forwardWarpFilter->SetEdgePaddingValue( static_cast<PixelType>(m_ArgsInfo.pad_arg) );
249 warpFilter=forwardWarpFilter;
252 // -------------------------------------------
254 // -------------------------------------------
256 // Get the interpolator
257 typedef clitk::GenericInterpolator<args_info_clitkWarpImage, InputImageType, double> GenericInterpolatorType;
258 typename GenericInterpolatorType::Pointer genericInterpolator=GenericInterpolatorType::New();
259 genericInterpolator->SetArgsInfo(m_ArgsInfo);
262 typedef itk::WarpImageFilter<InputImageType, InputImageType, DeformationFieldType> BackwardWarpFilterType;
263 typename BackwardWarpFilterType::Pointer backwardWarpFilter= BackwardWarpFilterType::New();
264 #if ITK_VERSION_MAJOR >= 4
265 backwardWarpFilter->SetDisplacementField( deformationField );
267 backwardWarpFilter->SetDeformationField( deformationField );
269 backwardWarpFilter->SetEdgePaddingValue( static_cast<PixelType>(m_ArgsInfo.pad_arg) );
270 backwardWarpFilter->SetOutputSpacing( deformationField->GetSpacing() );
271 backwardWarpFilter->SetOutputOrigin( input->GetOrigin() );
272 backwardWarpFilter->SetOutputSize( deformationField->GetLargestPossibleRegion().GetSize() );
273 typename itk::VectorResampleImageFilter<DeformationFieldType, DeformationFieldType >::Pointer
274 resampler =itk::VectorResampleImageFilter<DeformationFieldType, DeformationFieldType >::New();
275 backwardWarpFilter->SetInterpolator(genericInterpolator->GetInterpolatorPointer());
276 warpFilter=backwardWarpFilter;
280 // -------------------------------------------
282 // -------------------------------------------
283 warpFilter->SetInput(input);
284 if (m_Verbose) std::cout<< "Warping the input..." <<std::endl;
286 warpFilter->Update();
287 } catch( itk::ExceptionObject & excp ) {
288 std::cerr << "Problem warping the input image" << std::endl;
289 std::cerr << excp << std::endl;
295 typedef itk::ImageFileWriter<OutputImageType> WriterType;
296 typename WriterType::Pointer writer = WriterType::New();
297 writer->SetFileName(m_ArgsInfo.output_arg);
298 writer->SetInput(warpFilter->GetOutput());
306 #endif //#define clitkWarpImageGenericFilter_txx