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>::MultipleBSplineDeformableTransform() : Superclass(0)
35 m_labelInterpolator = 0;
37 m_trans[0] = TransformType::New();
38 m_parameters.resize(1);
40 this->m_FixedParameters.SetSize(NInputDimensions * (NInputDimensions + 5) + 4);
41 this->m_FixedParameters.Fill(0.0);
43 m_InternalParametersBuffer = ParametersType(0);
44 // Make sure the parameters pointer is not NULL after construction.
45 m_InputParametersPointer = &m_InternalParametersBuffer;
50 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
51 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
52 ::~MultipleBSplineDeformableTransform()
56 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
58 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
59 ::SetLabels(ImageLabelPointer labels)
61 GetFixedParameters(); // Update m_FixedParameters
64 typedef itk::RelabelComponentImageFilter<ImageLabelType, ImageLabelType> RelabelImageFilterType;
65 typename RelabelImageFilterType::Pointer relabelImageFilter = RelabelImageFilterType::New();
66 relabelImageFilter->SetInput(labels);
67 relabelImageFilter->Update();
68 m_labels = relabelImageFilter->GetOutput();
69 m_nLabels = relabelImageFilter->GetNumberOfObjects();
70 m_trans.resize(m_nLabels);
71 m_parameters.resize(m_nLabels);
72 for (unsigned i = 0; i < m_nLabels; ++i)
73 m_trans[i] = TransformType::New();
74 m_labelInterpolator = ImageLabelInterpolator::New();
75 m_labelInterpolator->SetInputImage(m_labels);
81 m_parameters.resize(1);
82 m_trans[0] = TransformType::New();
84 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 2] = (double)((size_t) m_labels);
85 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 3] = m_nLabels;
86 SetFixedParameters(this->m_FixedParameters);
89 #define LOOP_ON_LABELS(FUNC, ARGS) \
90 for (unsigned i = 0; i < m_nLabels; ++i) \
91 m_trans[i]->FUNC(ARGS);
93 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
95 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
96 ::SetSplineOrder(const unsigned int & splineOrder)
98 LOOP_ON_LABELS(SetSplineOrder, splineOrder);
102 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
104 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
105 ::SetSplineOrders(const SizeType & splineOrders)
107 LOOP_ON_LABELS(SetSplineOrders, splineOrders);
111 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
113 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
114 ::SetLUTSamplingFactor( const int & samplingFactor)
116 LOOP_ON_LABELS(SetLUTSamplingFactor, samplingFactor);
120 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
122 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
123 ::SetLUTSamplingFactors( const SizeType & samplingFactors)
125 LOOP_ON_LABELS(SetLUTSamplingFactors, samplingFactors);
129 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
131 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
132 ::SetGridRegion( const RegionType & region )
134 LOOP_ON_LABELS(SetGridRegion, region);
138 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
140 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
141 ::SetGridSpacing( const SpacingType & spacing )
143 LOOP_ON_LABELS(SetGridSpacing, spacing);
147 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
149 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
150 ::SetGridDirection( const DirectionType & direction )
152 LOOP_ON_LABELS(SetGridDirection, direction);
156 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
158 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
159 ::SetGridOrigin( const OriginType& origin )
161 LOOP_ON_LABELS(SetGridOrigin, origin);
165 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
167 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
170 LOOP_ON_LABELS(SetIdentity, );
171 if ( m_InputParametersPointer )
173 ParametersType * parameters =
174 const_cast<ParametersType *>( m_InputParametersPointer );
175 parameters->Fill( 0.0 );
180 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
181 inline const std::vector<typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::CoefficientImagePointer>&
182 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
183 ::GetCoefficientImages() const
185 m_CoefficientImages.resize(m_nLabels);
186 for (unsigned i = 0; i < m_nLabels; ++i)
187 m_CoefficientImages[i] = m_trans[i]->GetCoefficientImage();
188 return m_CoefficientImages;
191 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
193 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
194 ::SetCoefficientImages(std::vector<CoefficientImagePointer>& images)
196 if (images.size() != m_nLabels)
198 itkExceptionMacro( << "Mismatched between the number of labels "
200 << " and the number of coefficient images "
203 for (unsigned i = 0; i < m_nLabels; ++i)
204 m_trans[i]->SetCoefficientImage(images[i]);
207 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
209 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
210 ::SetParameters( const ParametersType & parameters )
212 if ( parameters.Size() != this->GetNumberOfParameters() )
214 itkExceptionMacro(<<"Mismatched between parameters size "
216 << " and region size "
217 << this->GetNumberOfParameters() );
220 // Clean up buffered parameters
221 m_InternalParametersBuffer = ParametersType( 0 );
223 // Keep a reference to the input parameters
224 m_InputParametersPointer = ¶meters;
226 double * dataPointer = const_cast<double *>(m_InputParametersPointer->data_block());
228 for (unsigned i = 0; i < m_nLabels; ++i)
230 unsigned int numberOfParameters = m_trans[i]->GetNumberOfParameters();
231 m_parameters[i].SetData(dataPointer + tot, numberOfParameters);
232 m_trans[i]->SetParameters(m_parameters[i]);
233 tot += numberOfParameters;
240 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
242 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
243 ::SetFixedParameters( const ParametersType & parameters )
245 // BSplineSeformableTransform parameters + m_labels pointer
246 if ( parameters.Size() != NInputDimensions * (5 + NInputDimensions) + 4)
248 itkExceptionMacro(<< "Mismatched between parameters size "
250 << " and number of fixed parameters "
251 << NInputDimensions * (5 + NInputDimensions) + 4);
253 ImageLabelPointer tmp2 = ((ImageLabelPointer)( (size_t)parameters[(5+NInputDimensions)*NInputDimensions+2]));
254 if (tmp2 != m_labels)
259 m_nLabels = parameters[(5+NInputDimensions) * NInputDimensions + 3 ];
260 m_trans.resize(m_nLabels);
261 m_parameters.resize(m_nLabels);
262 for (unsigned i = 0; i < m_nLabels; ++i)
263 m_trans[i] = TransformType::New();
264 m_labelInterpolator = ImageLabelInterpolator::New();
265 m_labelInterpolator->SetInputImage(m_labels);
272 m_parameters.resize(1);
273 m_trans[0] = TransformType::New();
276 unsigned int numberOfParameters = NInputDimensions * (5 + NInputDimensions) + 2;
277 ParametersType tmp(numberOfParameters);
278 for (unsigned j = 0; j < numberOfParameters; ++j)
279 tmp.SetElement(j, parameters.GetElement(j));
280 LOOP_ON_LABELS(SetFixedParameters, tmp);
281 this->m_FixedParameters = parameters;
285 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
287 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
288 ::SetParametersByValue( const ParametersType & parameters )
290 if ( parameters.Size() != this->GetNumberOfParameters() )
292 itkExceptionMacro(<<"Mismatched between parameters size "
294 << " and region size "
295 << this->GetNumberOfParameters() );
299 m_InternalParametersBuffer = parameters;
300 m_InputParametersPointer = &m_InternalParametersBuffer;
302 for (unsigned i = 0, tot = 0; i < m_nLabels; ++i)
304 unsigned int numberOfParameters = m_trans[i]->GetNumberOfParameters();
305 ParametersType tmp(numberOfParameters);
306 for (unsigned j = 0; j < numberOfParameters; ++j, ++tot)
307 tmp.SetElement(j, parameters.GetElement(tot));
308 m_trans[i]->SetParametersByValue(tmp);
315 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
317 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
318 ::SetBulkTransform(BulkTransformPointer b)
321 LOOP_ON_LABELS(SetBulkTransform, b);
324 #undef LOOP_ON_LABELS
326 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
327 inline typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::NumberOfParametersType
328 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
329 ::GetNumberOfParameters(void) const
331 unsigned int sum = 0;
332 for (unsigned i = 0; i < m_nLabels; ++i)
333 sum += m_trans[i]->GetNumberOfParameters();
337 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
339 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
340 ::GetNumberOfParametersPerDimension(void) const
342 unsigned int sum = 0;
343 for (unsigned i = 0; i < m_nLabels; ++i)
344 sum += m_trans[i]->GetNumberOfParametersPerDimension();
348 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
349 inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::ParametersType &
350 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
351 ::GetParameters() const
353 if (NULL == m_InputParametersPointer)
355 itkExceptionMacro( <<"Cannot GetParameters() because m_InputParametersPointer is NULL. Perhaps SetCoefficientImage() has been called causing the NULL pointer." );
358 return (*m_InputParametersPointer);
361 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
362 inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::ParametersType &
363 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
364 ::GetFixedParameters() const
366 const ParametersType& trans0Para = m_trans[0]->GetFixedParameters();
367 for (unsigned i = 0; i < trans0Para.Size() ; ++i)
368 this->m_FixedParameters.SetElement(i, trans0Para.GetElement(i));
369 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 2] = (double)((size_t) m_labels);
370 this->m_FixedParameters[(5+NInputDimensions)*NInputDimensions + 3] = m_nLabels;
371 return this->m_FixedParameters;
374 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
376 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
377 ::PrintSelf(std::ostream &os, itk::Indent indent) const
379 this->Superclass::PrintSelf(os, indent);
380 os << indent << "nLabels" << m_nLabels << std::endl;
381 itk::Indent ind = indent.GetNextIndent();
383 for (unsigned i = 0; i < m_nLabels; ++i)
385 os << indent << "Label " << i << std::endl;
386 m_trans[i]->Print(os, ind);
390 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
392 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
393 ::InsideValidRegion( const ContinuousIndexType& index ) const
396 for (unsigned i = 0; i < m_nLabels; ++i)
397 res |= m_trans[i]->InsideValidRegion(index);
401 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
402 inline typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::OutputPointType
403 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
404 ::TransformPoint(const InputPointType &inputPoint) const
408 lidx = m_labelInterpolator->Evaluate(inputPoint) - 1;
411 return m_trans[lidx]->TransformPoint(inputPoint);
414 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
415 inline typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::OutputPointType
416 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
417 ::DeformablyTransformPoint(const InputPointType &inputPoint) const
421 lidx = m_labelInterpolator->Evaluate(inputPoint) - 1;
424 return m_trans[lidx]->DeformablyTransformPoint(inputPoint);
427 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
429 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
430 ::ComputeJacobianWithRespectToParameters (const InputPointType &point, JacobianType &jacobian) const
432 if (m_LastJacobian != -1)
433 m_trans[m_LastJacobian]->ResetJacobian();
437 lidx = m_labelInterpolator->Evaluate(point) - 1;
440 m_LastJacobian = lidx;
441 jacobian = this->m_SharedDataBSplineJacobian;
446 m_trans[lidx]->ComputeJacobianWithRespectToParameters(point, unused);
447 m_LastJacobian = lidx;
449 jacobian = this->m_SharedDataBSplineJacobian;
453 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
455 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions,NOutputDimensions>
456 ::TransformPointToContinuousIndex( const InputPointType & point, ContinuousIndexType & index ) const
458 m_trans[0]->TransformPointToContinuousIndex(point, index);
461 template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
463 MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions,NOutputDimensions>::InitJacobian()
465 unsigned numberOfParameters = this->GetNumberOfParameters();
466 this->m_SharedDataBSplineJacobian.set_size(OutputDimension, numberOfParameters);
467 JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_SharedDataBSplineJacobian.data_block());
468 memset(jacobianDataPointer, 0, numberOfParameters * sizeof (JacobianPixelType));
471 for (unsigned int j = 0; j < OutputDimension; j++)
473 for (unsigned i = 0; i < m_nLabels; ++i)
475 unsigned numberOfPixels = m_trans[i]->SetJacobianImageData(jacobianDataPointer, j);
476 jacobianDataPointer += numberOfPixels;
477 tot += numberOfPixels;
480 assert(tot == numberOfParameters);
485 #endif // __clitkMultipleBSplineDeformableTransform_txx