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 __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 #if ITK_VERSION_MAJOR >= 4
33 ::MultipleBSplineDeformableTransform() : Superclass(0)
35 ::MultipleBSplineDeformableTransform() : Superclass(OutputDimension, 0)
40 m_labelInterpolator = 0;
42 m_trans[0] = TransformType::New();
43 m_parameters.resize(1);
45 this->m_FixedParameters.SetSize(NInputDimensions * (NInputDimensions + 5) + 4);
46 this->m_FixedParameters.Fill(0.0);
48 m_InternalParametersBuffer = ParametersType(0);
49 // Make sure the parameters pointer is not NULL after construction.
50 m_InputParametersPointer = &m_InternalParametersBuffer;
55 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
56 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
57 ::~MultipleBSplineDeformableTransform()
61 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
63 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
64 ::SetLabels(ImageLabelPointer labels)
66 GetFixedParameters(); // Update m_FixedParameters
69 typedef itk::RelabelComponentImageFilter<ImageLabelType, ImageLabelType> RelabelImageFilterType;
70 typename RelabelImageFilterType::Pointer relabelImageFilter = RelabelImageFilterType::New();
71 relabelImageFilter->SetInput(labels);
72 relabelImageFilter->Update();
73 m_labels = relabelImageFilter->GetOutput();
74 m_nLabels = relabelImageFilter->GetNumberOfObjects();
75 m_trans.resize(m_nLabels);
76 m_parameters.resize(m_nLabels);
77 for (unsigned i = 0; i < m_nLabels; ++i)
78 m_trans[i] = TransformType::New();
79 m_labelInterpolator = ImageLabelInterpolator::New();
80 m_labelInterpolator->SetInputImage(m_labels);
86 m_parameters.resize(1);
87 m_trans[0] = TransformType::New();
89 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 2] = (double)((size_t) m_labels);
90 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 3] = m_nLabels;
91 SetFixedParameters(this->m_FixedParameters);
94 #define LOOP_ON_LABELS(FUNC, ARGS) \
95 for (unsigned i = 0; i < m_nLabels; ++i) \
96 m_trans[i]->FUNC(ARGS);
98 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
100 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
101 ::SetSplineOrder(const unsigned int & splineOrder)
103 LOOP_ON_LABELS(SetSplineOrder, splineOrder);
107 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
109 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
110 ::SetSplineOrders(const SizeType & splineOrders)
112 LOOP_ON_LABELS(SetSplineOrders, splineOrders);
116 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
118 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
119 ::SetLUTSamplingFactor( const int & samplingFactor)
121 LOOP_ON_LABELS(SetLUTSamplingFactor, samplingFactor);
125 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
127 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
128 ::SetLUTSamplingFactors( const SizeType & samplingFactors)
130 LOOP_ON_LABELS(SetLUTSamplingFactors, samplingFactors);
134 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
136 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
137 ::SetGridRegion( const RegionType & region )
139 LOOP_ON_LABELS(SetGridRegion, region);
143 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
145 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
146 ::SetGridSpacing( const SpacingType & spacing )
148 LOOP_ON_LABELS(SetGridSpacing, spacing);
152 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
154 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
155 ::SetGridDirection( const DirectionType & direction )
157 LOOP_ON_LABELS(SetGridDirection, direction);
161 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
163 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
164 ::SetGridOrigin( const OriginType& origin )
166 LOOP_ON_LABELS(SetGridOrigin, origin);
170 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
172 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
175 LOOP_ON_LABELS(SetIdentity, );
176 if ( m_InputParametersPointer )
178 ParametersType * parameters =
179 const_cast<ParametersType *>( m_InputParametersPointer );
180 parameters->Fill( 0.0 );
185 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
186 inline const std::vector<typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::CoefficientImagePointer>&
187 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
188 ::GetCoefficientImages() const
190 m_CoefficientImages.resize(m_nLabels);
191 for (unsigned i = 0; i < m_nLabels; ++i)
192 m_CoefficientImages[i] = m_trans[i]->GetCoefficientImage();
193 return m_CoefficientImages;
196 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
198 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
199 ::SetCoefficientImages(std::vector<CoefficientImagePointer>& images)
201 if (images.size() != m_nLabels)
203 itkExceptionMacro( << "Mismatched between the number of labels "
205 << " and the number of coefficient images "
208 for (unsigned i = 0; i < m_nLabels; ++i)
209 m_trans[i]->SetCoefficientImage(images[i]);
212 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
214 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
215 ::SetParameters( const ParametersType & parameters )
217 if ( parameters.Size() != this->GetNumberOfParameters() )
219 itkExceptionMacro(<<"Mismatched between parameters size "
221 << " and region size "
222 << this->GetNumberOfParameters() );
225 // Clean up buffered parameters
226 m_InternalParametersBuffer = ParametersType( 0 );
228 // Keep a reference to the input parameters
229 m_InputParametersPointer = ¶meters;
231 double * dataPointer = const_cast<double *>(m_InputParametersPointer->data_block());
233 for (unsigned i = 0; i < m_nLabels; ++i)
235 unsigned int numberOfParameters = m_trans[i]->GetNumberOfParameters();
236 m_parameters[i].SetData(dataPointer + tot, numberOfParameters);
237 m_trans[i]->SetParameters(m_parameters[i]);
238 tot += numberOfParameters;
245 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
247 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
248 ::SetFixedParameters( const ParametersType & parameters )
250 // BSplineSeformableTransform parameters + m_labels pointer
251 if ( parameters.Size() != NInputDimensions * (5 + NInputDimensions) + 4)
253 itkExceptionMacro(<< "Mismatched between parameters size "
255 << " and number of fixed parameters "
256 << NInputDimensions * (5 + NInputDimensions) + 4);
258 ImageLabelPointer tmp2 = ((ImageLabelPointer)( (size_t)parameters[(5+NInputDimensions)*NInputDimensions+2]));
259 if (tmp2 != m_labels)
264 m_nLabels = parameters[(5+NInputDimensions) * NInputDimensions + 3 ];
265 m_trans.resize(m_nLabels);
266 m_parameters.resize(m_nLabels);
267 for (unsigned i = 0; i < m_nLabels; ++i)
268 m_trans[i] = TransformType::New();
269 m_labelInterpolator = ImageLabelInterpolator::New();
270 m_labelInterpolator->SetInputImage(m_labels);
277 m_parameters.resize(1);
278 m_trans[0] = TransformType::New();
281 unsigned int numberOfParameters = NInputDimensions * (5 + NInputDimensions) + 2;
282 ParametersType tmp(numberOfParameters);
283 for (unsigned j = 0; j < numberOfParameters; ++j)
284 tmp.SetElement(j, parameters.GetElement(j));
285 LOOP_ON_LABELS(SetFixedParameters, tmp);
286 this->m_FixedParameters = parameters;
290 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
292 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
293 ::SetParametersByValue( const ParametersType & parameters )
295 if ( parameters.Size() != this->GetNumberOfParameters() )
297 itkExceptionMacro(<<"Mismatched between parameters size "
299 << " and region size "
300 << this->GetNumberOfParameters() );
304 m_InternalParametersBuffer = parameters;
305 m_InputParametersPointer = &m_InternalParametersBuffer;
307 for (unsigned i = 0, tot = 0; i < m_nLabels; ++i)
309 unsigned int numberOfParameters = m_trans[i]->GetNumberOfParameters();
310 ParametersType tmp(numberOfParameters);
311 for (unsigned j = 0; j < numberOfParameters; ++j, ++tot)
312 tmp.SetElement(j, parameters.GetElement(tot));
313 m_trans[i]->SetParametersByValue(tmp);
320 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
322 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
323 ::SetBulkTransform(BulkTransformPointer b)
326 LOOP_ON_LABELS(SetBulkTransform, b);
329 #undef LOOP_ON_LABELS
331 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
332 #if ITK_VERSION_MAJOR >= 4
333 inline typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::NumberOfParametersType
337 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
338 ::GetNumberOfParameters(void) const
340 unsigned int sum = 0;
341 for (unsigned i = 0; i < m_nLabels; ++i)
342 sum += m_trans[i]->GetNumberOfParameters();
346 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
348 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
349 ::GetNumberOfParametersPerDimension(void) const
351 unsigned int sum = 0;
352 for (unsigned i = 0; i < m_nLabels; ++i)
353 sum += m_trans[i]->GetNumberOfParametersPerDimension();
357 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
358 inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::ParametersType &
359 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
360 ::GetParameters() const
362 if (NULL == m_InputParametersPointer)
364 itkExceptionMacro( <<"Cannot GetParameters() because m_InputParametersPointer is NULL. Perhaps SetCoefficientImage() has been called causing the NULL pointer." );
367 return (*m_InputParametersPointer);
370 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
371 inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::ParametersType &
372 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
373 ::GetFixedParameters() const
375 const ParametersType& trans0Para = m_trans[0]->GetFixedParameters();
376 for (unsigned i = 0; i < trans0Para.Size() ; ++i)
377 this->m_FixedParameters.SetElement(i, trans0Para.GetElement(i));
378 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 2] = (double)((size_t) m_labels);
379 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 3] = m_nLabels;
380 return this->m_FixedParameters;
383 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
385 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
386 ::PrintSelf(std::ostream &os, itk::Indent indent) const
388 this->Superclass::PrintSelf(os, indent);
389 os << indent << "nLabels" << m_nLabels << std::endl;
390 itk::Indent ind = indent.GetNextIndent();
392 for (unsigned i = 0; i < m_nLabels; ++i)
394 os << indent << "Label " << i << std::endl;
395 m_trans[i]->Print(os, ind);
399 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
401 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
402 ::InsideValidRegion( const ContinuousIndexType& index ) const
405 for (unsigned i = 0; i < m_nLabels; ++i)
406 res |= m_trans[i]->InsideValidRegion(index);
410 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
411 inline typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::OutputPointType
412 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
413 ::TransformPoint(const InputPointType &inputPoint) const
417 lidx = m_labelInterpolator->Evaluate(inputPoint) - 1;
420 return m_trans[lidx]->TransformPoint(inputPoint);
423 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
424 inline typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::OutputPointType
425 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
426 ::DeformablyTransformPoint(const InputPointType &inputPoint) const
430 lidx = m_labelInterpolator->Evaluate(inputPoint) - 1;
433 return m_trans[lidx]->DeformablyTransformPoint(inputPoint);
436 #if ITK_VERSION_MAJOR >= 4
437 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
439 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
440 ::ComputeJacobianWithRespectToParameters (const InputPointType &point, JacobianType &jacobian) const
442 if (m_LastJacobian != -1)
443 m_trans[m_LastJacobian]->ResetJacobian();
447 lidx = m_labelInterpolator->Evaluate(point) - 1;
450 m_LastJacobian = lidx;
451 jacobian = this->m_SharedDataBSplineJacobian;
456 m_trans[lidx]->ComputeJacobianWithRespectToParameters(point, unused);
457 m_LastJacobian = lidx;
459 jacobian = this->m_SharedDataBSplineJacobian;
463 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
464 inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::JacobianType &
465 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
466 ::GetJacobian( const InputPointType & point ) const
468 if (m_LastJacobian != -1)
469 m_trans[m_LastJacobian]->ResetJacobian();
473 lidx = m_labelInterpolator->Evaluate(point) - 1;
476 m_LastJacobian = lidx;
477 return this->m_Jacobian;
480 m_trans[lidx]->GetJacobian(point);
481 m_LastJacobian = lidx;
483 return this->m_Jacobian;
487 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
489 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions,NOutputDimensions>
490 ::TransformPointToContinuousIndex( const InputPointType & point, ContinuousIndexType & index ) const
492 m_trans[0]->TransformPointToContinuousIndex(point, index);
495 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
497 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions,NOutputDimensions>::InitJacobian()
499 unsigned numberOfParameters = this->GetNumberOfParameters();
500 #if ITK_VERSION_MAJOR >= 4
501 this->m_SharedDataBSplineJacobian.set_size(OutputDimension, numberOfParameters);
502 JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_SharedDataBSplineJacobian.data_block());
504 this->m_Jacobian.set_size(OutputDimension, numberOfParameters);
505 JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_Jacobian.data_block());
507 memset(jacobianDataPointer, 0, numberOfParameters * sizeof (JacobianPixelType));
510 for (unsigned int j = 0; j < OutputDimension; j++)
512 for (unsigned i = 0; i < m_nLabels; ++i)
514 unsigned numberOfPixels = m_trans[i]->SetJacobianImageData(jacobianDataPointer, j);
515 jacobianDataPointer += numberOfPixels;
516 tot += numberOfPixels;
519 assert(tot == numberOfParameters);
524 #endif // __clitkMultipleBSplineDeformableTransform_txx