20 #ifndef __itkBSplineInterpolateImageFunction_txx
21 #define __itkBSplineInterpolateImageFunction_txx
26 #include "itkConfigure.h"
29 #ifdef ITK_USE_OPTIMIZED_REGISTRATION_METHODS
48 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
53 unsigned int SplineOrder = 3;
54 m_CoefficientFilter = CoefficientFilter::New();
56 m_Coefficients = CoefficientImageType::New();
57 this->SetSplineOrder(SplineOrder);
58 #if defined(ITK_IMAGE_BEHAVES_AS_ORIENTED_IMAGE)
59 this->m_UseImageDirection =
true;
61 this->m_UseImageDirection =
false;
68 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
75 Superclass::PrintSelf( os, indent );
76 os << indent <<
"Spline Order: " << m_SplineOrder << std::endl;
77 os << indent <<
"UseImageDirection = "
78 << (this->m_UseImageDirection ?
"On" :
"Off") << std::endl;
83 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
90 m_CoefficientFilter->SetInput(inputData);
97 m_CoefficientFilter->Update();
98 m_Coefficients = m_CoefficientFilter->GetOutput();
102 Superclass::SetInputImage(inputData);
104 m_DataLength = inputData->GetBufferedRegion().GetSize();
108 m_CoefficientFilter->GetOutput()->DisconnectPipeline();
109 m_Coefficients =
NULL;
114 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
119 if (SplineOrder == m_SplineOrder)
123 m_SplineOrder = SplineOrder;
124 m_CoefficientFilter->SetSplineOrder( SplineOrder );
127 m_MaxNumberInterpolationPoints = 1;
128 for (
unsigned int n=0; n < ImageDimension; n++)
130 m_MaxNumberInterpolationPoints *= ( m_SplineOrder + 1);
132 this->GeneratePointsToIndex( );
136 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
146 this->DetermineRegionOfSupport(EvaluateIndex, x, m_SplineOrder);
150 SetInterpolationWeights( x, EvaluateIndex, weights, m_SplineOrder );
153 this->ApplyMirrorBoundaryConditions(EvaluateIndex, m_SplineOrder);
156 double interpolated = 0.0;
159 for (
unsigned int p = 0; p < m_MaxNumberInterpolationPoints; p++)
165 for (
unsigned int n = 0; n < ImageDimension; n++ )
167 w *= weights[n][ m_PointsToIndex[p][n] ];
168 coefficientIndex[n] = EvaluateIndex[n][m_PointsToIndex[p][n]];
172 interpolated += w * (m_Coefficients->GetPixel(coefficientIndex));
175 return(interpolated);
180 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
183 :: CovariantVectorType
191 this->DetermineRegionOfSupport(EvaluateIndex, x, m_SplineOrder);
195 SetInterpolationWeights( x, EvaluateIndex, weights, m_SplineOrder );
198 SetDerivativeWeights( x, EvaluateIndex, weightsDerivative, ( m_SplineOrder ) );
201 this->ApplyMirrorBoundaryConditions(EvaluateIndex, m_SplineOrder);
204 const typename InputImageType::SpacingType & spacing = inputImage->GetSpacing();
210 for (
unsigned int n = 0; n < ImageDimension; n++)
212 derivativeValue[n] = 0.0;
213 for (
unsigned int p = 0; p < m_MaxNumberInterpolationPoints; p++)
216 for (
unsigned int n1 = 0; n1 < ImageDimension; n1++)
219 coefficientIndex[n1] = EvaluateIndex[n1][m_PointsToIndex[p][n1]];
224 tempValue *= weightsDerivative[n1][ m_PointsToIndex[p][n1] ];
228 tempValue *= weights[n1][ m_PointsToIndex[p][n1] ];
231 derivativeValue[n] += m_Coefficients->GetPixel(coefficientIndex) * tempValue;
233 derivativeValue[n] /= spacing[n];
236 #ifdef ITK_USE_ORIENTED_IMAGE_DIRECTION
237 if( this->m_UseImageDirection )
240 inputImage->TransformLocalVectorToPhysicalVector( derivativeValue, orientedDerivative );
241 return orientedDerivative;
245 return(derivativeValue);
249 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
258 double w, w2, w4, t, t0, t1;
263 for (
unsigned int n = 0; n < ImageDimension; n++)
265 w = x[n] - (double) EvaluateIndex[n][1];
266 weights[n][3] = (1.0 / 6.0) * w * w * w;
267 weights[n][0] = (1.0 / 6.0) + 0.5 * w * (w - 1.0) - weights[n][3];
268 weights[n][2] = w + weights[n][0] - 2.0 * weights[n][3];
269 weights[n][1] = 1.0 - weights[n][0] - weights[n][2] - weights[n][3];
273 for (
unsigned int n = 0; n < ImageDimension; n++)
279 for (
unsigned int n = 0; n < ImageDimension; n++)
281 w = x[n] - (double) EvaluateIndex[n][0];
283 weights[n][0] = 1.0 - w;
287 for (
unsigned int n = 0; n < ImageDimension; n++)
290 w = x[n] - (double)EvaluateIndex[n][1];
291 weights[n][1] = 0.75 - w * w;
292 weights[n][2] = 0.5 * (w - weights[n][1] + 1.0);
293 weights[n][0] = 1.0 - weights[n][1] - weights[n][2];
297 for (
unsigned int n = 0; n < ImageDimension; n++)
300 w = x[n] - (double)EvaluateIndex[n][2];
302 t = (1.0 / 6.0) * w2;
303 weights[n][0] = 0.5 - w;
304 weights[n][0] *= weights[n][0];
305 weights[n][0] *= (1.0 / 24.0) * weights[n][0];
306 t0 = w * (t - 11.0 / 24.0);
307 t1 = 19.0 / 96.0 + w2 * (0.25 - t);
308 weights[n][1] = t1 + t0;
309 weights[n][3] = t1 - t0;
310 weights[n][4] = weights[n][0] + t0 + 0.5 * w;
311 weights[n][2] = 1.0 - weights[n][0] - weights[n][1] - weights[n][3] - weights[n][4];
315 for (
unsigned int n = 0; n < ImageDimension; n++)
318 w = x[n] - (double)EvaluateIndex[n][2];
320 weights[n][5] = (1.0 / 120.0) * w * w2 * w2;
325 weights[n][0] = (1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - weights[n][5];
326 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
327 t1 = (-1.0 / 12.0) * w * (t + 4.0);
328 weights[n][2] = t0 + t1;
329 weights[n][3] = t0 - t1;
330 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
331 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
332 weights[n][1] = t0 + t1;
333 weights[n][4] = t0 - t1;
340 err.
SetDescription(
"SplineOrder must be between 0 and 5. Requested spline order has not been implemented yet." );
347 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
358 double w, w1, w2, w3, w4, w5, t, t0, t1, t2;
359 int derivativeSplineOrder = (int) splineOrder -1;
361 switch (derivativeSplineOrder)
367 for (
unsigned int n = 0; n < ImageDimension; n++)
373 for (
unsigned int n = 0; n < ImageDimension; n++)
375 weights[n][0] = -1.0;
380 for (
unsigned int n = 0; n < ImageDimension; n++)
382 w = x[n] + 0.5 - (double)EvaluateIndex[n][1];
386 weights[n][0] = 0.0 - w1;
387 weights[n][1] = w1 - w;
393 for (
unsigned int n = 0; n < ImageDimension; n++)
395 w = x[n] + .5 - (double)EvaluateIndex[n][2];
397 w3 = 0.5 * (w - w2 + 1.0);
400 weights[n][0] = 0.0 - w1;
401 weights[n][1] = w1 - w2;
402 weights[n][2] = w2 - w3;
408 for (
unsigned int n = 0; n < ImageDimension; n++)
410 w = x[n] + 0.5 - (double)EvaluateIndex[n][2];
411 w4 = (1.0 / 6.0) * w * w * w;
412 w1 = (1.0 / 6.0) + 0.5 * w * (w - 1.0) - w4;
413 w3 = w + w1 - 2.0 * w4;
414 w2 = 1.0 - w1 - w3 - w4;
416 weights[n][0] = 0.0 - w1;
417 weights[n][1] = w1 - w2;
418 weights[n][2] = w2 - w3;
419 weights[n][3] = w3 - w4;
424 for (
unsigned int n = 0; n < ImageDimension; n++)
426 w = x[n] + .5 - (double)EvaluateIndex[n][3];
428 t = (1.0 / 6.0) * t2;
431 w1 *= (1.0 / 24.0) * w1;
432 t0 = w * (t - 11.0 / 24.0);
433 t1 = 19.0 / 96.0 + t2 * (0.25 - t);
436 w5 = w1 + t0 + 0.5 * w;
437 w3 = 1.0 - w1 - w2 - w4 - w5;
439 weights[n][0] = 0.0 - w1;
440 weights[n][1] = w1 - w2;
441 weights[n][2] = w2 - w3;
442 weights[n][3] = w3 - w4;
443 weights[n][4] = w4 - w5;
452 err.
SetDescription(
"SplineOrder (for derivatives) must be between 1 and 5. Requested spline order has not been implemented yet." );
461 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
468 m_PointsToIndex.resize(m_MaxNumberInterpolationPoints);
469 for (
unsigned int p = 0; p < m_MaxNumberInterpolationPoints; p++)
472 unsigned long indexFactor[ImageDimension];
474 for (
int j=1; j< static_cast<int>(ImageDimension); j++)
476 indexFactor[j] = indexFactor[j-1] * ( m_SplineOrder + 1 );
478 for (
int j = (static_cast<int>(ImageDimension) - 1); j >= 0; j--)
480 m_PointsToIndex[p][j] = pp / indexFactor[j];
481 pp = pp % indexFactor[j];
486 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
491 unsigned int splineOrder )
const
496 for (
unsigned int n = 0; n< ImageDimension; n++)
500 indx = (long)vcl_floor((
float)x[n]) - splineOrder / 2;
501 for (
unsigned int k = 0; k <= splineOrder; k++)
503 evaluateIndex[n][k] = indx++;
508 indx = (long)vcl_floor((
float)(x[n] + 0.5)) - splineOrder / 2;
509 for (
unsigned int k = 0; k <= splineOrder; k++)
511 evaluateIndex[n][k] = indx++;
517 template <
class TImageType,
class TCoordRep,
class TCoefficientType>
521 unsigned int splineOrder)
const
523 for (
unsigned int n = 0; n < ImageDimension; n++)
525 long dataLength2 = 2 * m_DataLength[n] - 2;
529 if (m_DataLength[n] == 1)
531 for (
unsigned int k = 0; k <= splineOrder; k++)
533 evaluateIndex[n][k] = 0;
538 for (
unsigned int k = 0; k <= splineOrder; k++)
541 evaluateIndex[n][k] = (evaluateIndex[n][k] < 0L) ? (-evaluateIndex[n][k] - dataLength2 * ((-evaluateIndex[n][k]) / dataLength2))
542 : (evaluateIndex[n][k] - dataLength2 * (evaluateIndex[n][k] / dataLength2));
543 if ((
long) m_DataLength[n] <= evaluateIndex[n][k])
545 evaluateIndex[n][k] = dataLength2 - evaluateIndex[n][k];