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 __clitkMultipleBSplineDeformableTransform_txx
19 #define __clitkMultipleBSplineDeformableTransform_txx
22 #include "clitkMultipleBSplineDeformableTransformInitializer.h"
25 #include <itkRelabelComponentImageFilter.h>
29 // Constructor with default arguments
30 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
31 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
32 ::MultipleBSplineDeformableTransform() : Superclass(OutputDimension, 0)
36 m_labelInterpolator = 0;
38 m_trans[0] = TransformType::New();
39 m_parameters.resize(1);
41 this->m_FixedParameters.SetSize(NInputDimensions * (NInputDimensions + 5) + 4);
42 this->m_FixedParameters.Fill(0.0);
44 m_InternalParametersBuffer = ParametersType(0);
45 // Make sure the parameters pointer is not NULL after construction.
46 m_InputParametersPointer = &m_InternalParametersBuffer;
51 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
52 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
53 ::~MultipleBSplineDeformableTransform()
57 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
59 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
60 ::SetLabels(ImageLabelPointer labels)
62 GetFixedParameters(); // Update m_FixedParameters
65 typedef itk::RelabelComponentImageFilter<ImageLabelType, ImageLabelType> RelabelImageFilterType;
66 typename RelabelImageFilterType::Pointer relabelImageFilter = RelabelImageFilterType::New();
67 relabelImageFilter->SetInput(labels);
68 relabelImageFilter->Update();
69 m_labels = relabelImageFilter->GetOutput();
70 m_nLabels = relabelImageFilter->GetNumberOfObjects();
71 m_trans.resize(m_nLabels);
72 m_parameters.resize(m_nLabels);
73 for (unsigned i = 0; i < m_nLabels; ++i)
74 m_trans[i] = TransformType::New();
75 m_labelInterpolator = ImageLabelInterpolator::New();
76 m_labelInterpolator->SetInputImage(m_labels);
82 m_parameters.resize(1);
83 m_trans[0] = TransformType::New();
85 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 2] = (double)((size_t) m_labels);
86 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 3] = m_nLabels;
87 SetFixedParameters(this->m_FixedParameters);
90 #define LOOP_ON_LABELS(FUNC, ARGS) \
91 for (unsigned i = 0; i < m_nLabels; ++i) \
92 m_trans[i]->FUNC(ARGS);
94 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
96 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
97 ::SetSplineOrder(const unsigned int & splineOrder)
99 LOOP_ON_LABELS(SetSplineOrder, splineOrder);
103 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
105 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
106 ::SetSplineOrders(const SizeType & splineOrders)
108 LOOP_ON_LABELS(SetSplineOrders, splineOrders);
112 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
114 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
115 ::SetLUTSamplingFactor( const int & samplingFactor)
117 LOOP_ON_LABELS(SetLUTSamplingFactor, samplingFactor);
121 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
123 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
124 ::SetLUTSamplingFactors( const SizeType & samplingFactors)
126 LOOP_ON_LABELS(SetLUTSamplingFactors, samplingFactors);
130 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
132 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
133 ::SetGridRegion( const RegionType & region )
135 LOOP_ON_LABELS(SetGridRegion, region);
139 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
141 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
142 ::SetGridSpacing( const SpacingType & spacing )
144 LOOP_ON_LABELS(SetGridSpacing, spacing);
148 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
150 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
151 ::SetGridDirection( const DirectionType & direction )
153 LOOP_ON_LABELS(SetGridDirection, direction);
157 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
159 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
160 ::SetGridOrigin( const OriginType& origin )
162 LOOP_ON_LABELS(SetGridOrigin, origin);
166 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
168 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
171 LOOP_ON_LABELS(SetIdentity, );
172 if ( m_InputParametersPointer )
174 ParametersType * parameters =
175 const_cast<ParametersType *>( m_InputParametersPointer );
176 parameters->Fill( 0.0 );
181 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
182 inline const std::vector<typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::CoefficientImagePointer>&
183 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
184 ::GetCoefficientImages() const
186 m_CoefficientImages.resize(m_nLabels);
187 for (unsigned i = 0; i < m_nLabels; ++i)
188 m_CoefficientImages[i] = m_trans[i]->GetCoefficientImage();
189 return m_CoefficientImages;
192 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
194 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
195 ::SetCoefficientImages(std::vector<CoefficientImagePointer>& images)
197 if (images.size() != m_nLabels)
199 itkExceptionMacro( << "Mismatched between the number of labels "
201 << " and the number of coefficient images "
204 for (unsigned i = 0; i < m_nLabels; ++i)
205 m_trans[i]->SetCoefficientImage(images[i]);
208 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
210 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
211 ::SetParameters( const ParametersType & parameters )
213 if ( parameters.Size() != this->GetNumberOfParameters() )
215 itkExceptionMacro(<<"Mismatched between parameters size "
217 << " and region size "
218 << this->GetNumberOfParameters() );
221 // Clean up buffered parameters
222 m_InternalParametersBuffer = ParametersType( 0 );
224 // Keep a reference to the input parameters
225 m_InputParametersPointer = ¶meters;
227 double * dataPointer = const_cast<double *>(m_InputParametersPointer->data_block());
229 for (unsigned i = 0; i < m_nLabels; ++i)
231 unsigned int numberOfParameters = m_trans[i]->GetNumberOfParameters();
232 m_parameters[i].SetData(dataPointer + tot, numberOfParameters);
233 m_trans[i]->SetParameters(m_parameters[i]);
234 tot += numberOfParameters;
241 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
243 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
244 ::SetFixedParameters( const ParametersType & parameters )
246 // BSplineSeformableTransform parameters + m_labels pointer
247 if ( parameters.Size() != NInputDimensions * (5 + NInputDimensions) + 4)
249 itkExceptionMacro(<< "Mismatched between parameters size "
251 << " and number of fixed parameters "
252 << NInputDimensions * (5 + NInputDimensions) + 4);
254 ImageLabelPointer tmp2 = ((ImageLabelPointer)( (size_t)parameters[(5+NInputDimensions)*NInputDimensions+2]));
255 if (tmp2 != m_labels)
260 m_nLabels = parameters[(5+NInputDimensions) * NInputDimensions + 3 ];
261 m_trans.resize(m_nLabels);
262 m_parameters.resize(m_nLabels);
263 for (unsigned i = 0; i < m_nLabels; ++i)
264 m_trans[i] = TransformType::New();
265 m_labelInterpolator = ImageLabelInterpolator::New();
266 m_labelInterpolator->SetInputImage(m_labels);
273 m_parameters.resize(1);
274 m_trans[0] = TransformType::New();
277 unsigned int numberOfParameters = NInputDimensions * (5 + NInputDimensions) + 2;
278 ParametersType tmp(numberOfParameters);
279 for (unsigned j = 0; j < numberOfParameters; ++j)
280 tmp.SetElement(j, parameters.GetElement(j));
281 LOOP_ON_LABELS(SetFixedParameters, tmp);
282 this->m_FixedParameters = parameters;
286 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
288 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
289 ::SetParametersByValue( const ParametersType & parameters )
291 if ( parameters.Size() != this->GetNumberOfParameters() )
293 itkExceptionMacro(<<"Mismatched between parameters size "
295 << " and region size "
296 << this->GetNumberOfParameters() );
300 m_InternalParametersBuffer = parameters;
301 m_InputParametersPointer = &m_InternalParametersBuffer;
303 for (unsigned i = 0, tot = 0; i < m_nLabels; ++i)
305 unsigned int numberOfParameters = m_trans[i]->GetNumberOfParameters();
306 ParametersType tmp(numberOfParameters);
307 for (unsigned j = 0; j < numberOfParameters; ++j, ++tot)
308 tmp.SetElement(j, parameters.GetElement(tot));
309 m_trans[i]->SetParametersByValue(tmp);
316 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
318 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
319 ::SetBulkTransform(BulkTransformPointer b)
322 LOOP_ON_LABELS(SetBulkTransform, b);
325 #undef LOOP_ON_LABELS
327 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
329 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
330 ::GetNumberOfParameters(void) const
332 unsigned int sum = 0;
333 for (unsigned i = 0; i < m_nLabels; ++i)
334 sum += m_trans[i]->GetNumberOfParameters();
338 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
340 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
341 ::GetNumberOfParametersPerDimension(void) const
343 unsigned int sum = 0;
344 for (unsigned i = 0; i < m_nLabels; ++i)
345 sum += m_trans[i]->GetNumberOfParametersPerDimension();
349 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
350 inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::ParametersType &
351 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
352 ::GetParameters() const
354 if (NULL == m_InputParametersPointer)
356 itkExceptionMacro( <<"Cannot GetParameters() because m_InputParametersPointer is NULL. Perhaps SetCoefficientImage() has been called causing the NULL pointer." );
359 return (*m_InputParametersPointer);
362 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
363 inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::ParametersType &
364 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
365 ::GetFixedParameters() const
367 const ParametersType& trans0Para = m_trans[0]->GetFixedParameters();
368 for (unsigned i = 0; i < trans0Para.Size() ; ++i)
369 this->m_FixedParameters.SetElement(i, trans0Para.GetElement(i));
370 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 2] = (double)((size_t) m_labels);
371 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 3] = m_nLabels;
372 return this->m_FixedParameters;
375 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
377 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
378 ::PrintSelf(std::ostream &os, itk::Indent indent) const
380 this->Superclass::PrintSelf(os, indent);
381 os << indent << "nLabels" << m_nLabels << std::endl;
382 itk::Indent ind = indent.GetNextIndent();
384 for (unsigned i = 0; i < m_nLabels; ++i)
386 os << indent << "Label " << i << std::endl;
387 m_trans[i]->Print(os, ind);
391 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
393 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
394 ::InsideValidRegion( const ContinuousIndexType& index ) const
397 for (unsigned i = 0; i < m_nLabels; ++i)
398 res |= m_trans[i]->InsideValidRegion(index);
402 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
403 inline typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::OutputPointType
404 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
405 ::TransformPoint(const InputPointType &inputPoint) const
409 lidx = m_labelInterpolator->Evaluate(inputPoint) - 1;
412 return m_trans[lidx]->TransformPoint(inputPoint);
415 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
416 inline typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::OutputPointType
417 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
418 ::DeformablyTransformPoint(const InputPointType &inputPoint) const
422 lidx = m_labelInterpolator->Evaluate(inputPoint) - 1;
425 return m_trans[lidx]->DeformablyTransformPoint(inputPoint);
428 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
429 inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::JacobianType &
430 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
431 ::GetJacobian( const InputPointType & point ) const
434 for (unsigned i = 0; i < m_nLabels; ++i)
435 m_trans[i]->ResetJacobian();
437 if (m_LastJacobian != -1)
438 m_trans[m_LastJacobian]->ResetJacobian();
442 lidx = m_labelInterpolator->Evaluate(point) - 1;
445 m_LastJacobian = lidx;
446 return this->m_Jacobian;
449 m_trans[lidx]->GetJacobian(point);
450 m_LastJacobian = lidx;
452 return this->m_Jacobian;
455 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
457 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions,NOutputDimensions>
458 ::TransformPointToContinuousIndex( const InputPointType & point, ContinuousIndexType & index ) const
460 m_trans[0]->TransformPointToContinuousIndex(point, index);
463 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
465 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions,NOutputDimensions>::InitJacobian()
467 unsigned numberOfParameters = this->GetNumberOfParameters();
468 this->m_Jacobian.set_size(OutputDimension, numberOfParameters);
469 JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_Jacobian.data_block());
470 memset(jacobianDataPointer, 0, numberOfParameters * sizeof (JacobianPixelType));
473 for (unsigned int j = 0; j < OutputDimension; j++)
475 for (unsigned i = 0; i < m_nLabels; ++i)
477 unsigned numberOfPixels = m_trans[i]->SetJacobianImageData(jacobianDataPointer, j);
478 jacobianDataPointer += numberOfPixels;
479 tot += numberOfPixels;
482 assert(tot == numberOfParameters);
487 #endif // __clitkMultipleBSplineDeformableTransform_txx