17 #ifndef __itkLevelSetFunction_txx
18 #define __itkLevelSetFunction_txx
21 #include "vnl/algo/vnl_symmetric_eigensystem.h"
25 template <
class TImageType>
26 typename LevelSetFunction<TImageType>::ScalarValueType
30 if ( m_UseMinimalCurvature ==
false )
32 return this->ComputeMeanCurvature(neighborhood, offset, gd);
36 if (ImageDimension == 3)
38 return this->ComputeMinimalCurvature(neighborhood, offset, gd);
40 else if (ImageDimension == 2)
42 return this->ComputeMeanCurvature(neighborhood, offset, gd);
46 return this->ComputeMinimalCurvature(neighborhood, offset, gd);
52 template<
class TImageType>
65 vnl_matrix_fixed<ScalarValueType, ImageDimension, ImageDimension> Curve;
70 for (i = 0; i < ImageDimension; i++)
72 Pgrad[i][i] = 1.0 - gd->
m_dx[i] * gd->
m_dx[i]/gradMag;
73 for (j = i+1; j < ImageDimension; j++)
75 Pgrad[i][j]= gd->
m_dx[i] * gd->
m_dx[j]/gradMag;
76 Pgrad[j][i] = Pgrad[i][j];
81 for (i = 0; i < ImageDimension; i++)
83 for (j = i; j < ImageDimension; j++)
85 tmp_matrix[i][j]=
ZERO;
86 for (n = 0; n < ImageDimension; n++)
88 tmp_matrix[i][j] += Pgrad[i][n] * gd->
m_dxy[n][j];
90 tmp_matrix[j][i]=tmp_matrix[i][j];
94 for (i = 0; i < ImageDimension; i++)
96 for (j = i; j < ImageDimension; j++)
99 for (n = 0; n < ImageDimension; n++)
101 Curve(i,j) += tmp_matrix[i][n] * Pgrad[n][j];
103 Curve(j,i) = Curve(i,j);
108 vnl_symmetric_eigensystem<ScalarValueType> eig(Curve);
110 mincurve=vnl_math_abs(eig.get_eigenvalue(ImageDimension-1));
111 for (i = 0; i < ImageDimension; i++)
113 if(vnl_math_abs(eig.get_eigenvalue(i)) < mincurve &&
114 vnl_math_abs(eig.get_eigenvalue(i)) > MIN_EIG)
116 mincurve = vnl_math_abs(eig.get_eigenvalue(i));
120 return ( mincurve / gradMag );
124 template<
class TImageType>
130 ScalarValueType mean_curve = this->ComputeMeanCurvature(neighborhood, offset, gd);
132 int i0 = 0, i1 = 1, i2 = 2;
149 if (discriminant < 0.0)
153 discriminant = vcl_sqrt(discriminant);
154 return (mean_curve - discriminant);
158 template <
class TImageType>
169 for (i = 0; i < ImageDimension; i++)
171 for(j = 0; j < ImageDimension; j++)
175 curvature_term -= gd->
m_dx[i] * gd->
m_dx[j] * gd->
m_dxy[i][j];
176 curvature_term += gd->
m_dxy[j][j] * gd->
m_dx[i] * gd->
m_dx[i];
184 template <
class TImageType>
189 for (
unsigned int i = 0; i < ImageDimension; ++i)
191 ans[i] = NumericTraits<ScalarValueType>::Zero;
197 template <
class TImageType>
202 template <
class TImageType>
207 Superclass::PrintSelf(os, indent);
208 os << indent <<
"WaveDT: " << m_WaveDT << std::endl;
209 os << indent <<
"DT: " << m_DT << std::endl;
210 os << indent <<
"UseMinimalCurvature " << m_UseMinimalCurvature << std::endl;
211 os << indent <<
"EpsilonMagnitude: " << m_EpsilonMagnitude << std::endl;
212 os << indent <<
"AdvectionWeight: " << m_AdvectionWeight << std::endl;
213 os << indent <<
"PropagationWeight: " << m_PropagationWeight << std::endl;
214 os << indent <<
"CurvatureWeight: " << m_CurvatureWeight << std::endl;
215 os << indent <<
"LaplacianSmoothingWeight: " << m_LaplacianSmoothingWeight << std::endl;
218 template<
class TImageType >
221 template <
class TImageType >
224 template<
class TImageType >
259 double maxScaleCoefficient = 0.0;
260 for (
unsigned int i=0; i<ImageDimension; i++)
262 maxScaleCoefficient = vnl_math_max(this->m_ScaleCoefficients[i],maxScaleCoefficient);
264 dt /= maxScaleCoefficient;
274 template<
class TImageType >
286 m_Center = it.
Size() / 2;
289 for(
unsigned int i = 0; i < ImageDimension; i++)
293 template<
class TImageType >
306 curvature_term, advection_term, propagation_gradient;
315 for( i = 0; i < ImageDimension; i++)
317 const unsigned int positionA =
318 static_cast<unsigned int>( m_Center + m_xStride[i]);
319 const unsigned int positionB =
320 static_cast<unsigned int>( m_Center - m_xStride[i]);
323 it.
GetPixel( positionB ) ) * neighborhoodScales[i];
325 + it.
GetPixel( positionB ) - 2.0 * center_value ) *
326 vnl_math_sqr(neighborhoodScales[i]);
334 for( j = i+1; j < ImageDimension; j++ )
336 const unsigned int positionAa =
static_cast<unsigned int>(
337 m_Center - m_xStride[i] - m_xStride[j] );
338 const unsigned int positionBa =
static_cast<unsigned int>(
339 m_Center - m_xStride[i] + m_xStride[j] );
340 const unsigned int positionCa =
static_cast<unsigned int>(
341 m_Center + m_xStride[i] - m_xStride[j] );
342 const unsigned int positionDa =
static_cast<unsigned int>(
343 m_Center + m_xStride[i] + m_xStride[j] );
349 * neighborhoodScales[i] * neighborhoodScales[j];
353 if ( m_CurvatureWeight != ZERO )
355 curvature_term = this->ComputeCurvatureTerm(it, offset, gd) * m_CurvatureWeight
356 * this->CurvatureSpeed(it, offset);
359 vnl_math_abs(curvature_term));
363 curvature_term =
ZERO;
372 if (m_AdvectionWeight != ZERO)
375 advection_field = this->AdvectionField(it, offset, gd);
376 advection_term =
ZERO;
378 for(i = 0; i < ImageDimension; i++)
381 x_energy = m_AdvectionWeight * advection_field[i];
389 advection_term += advection_field[i] * gd->
m_dx_forward[i];
395 advection_term *= m_AdvectionWeight;
400 advection_term =
ZERO;
403 if (m_PropagationWeight != ZERO)
406 propagation_term = m_PropagationWeight * this->PropagationSpeed(it, offset, gd);
415 propagation_gradient =
ZERO;
417 if ( propagation_term > ZERO )
419 for(i = 0; i< ImageDimension; i++)
421 propagation_gradient += vnl_math_sqr( vnl_math_max(gd->
m_dx_backward[i], ZERO) )
422 + vnl_math_sqr( vnl_math_min(gd->
m_dx_forward[i], ZERO) );
427 for(i = 0; i< ImageDimension; i++)
429 propagation_gradient += vnl_math_sqr( vnl_math_min(gd->
m_dx_backward[i], ZERO) )
430 + vnl_math_sqr( vnl_math_max(gd->
m_dx_forward[i], ZERO) );
438 vnl_math_abs(propagation_term));
440 propagation_term *= vcl_sqrt( propagation_gradient );
442 else propagation_term =
ZERO;
444 if(m_LaplacianSmoothingWeight != ZERO)
449 for(i = 0;i < ImageDimension; i++)
451 laplacian += gd->
m_dxy[i][i];
456 laplacian * m_LaplacianSmoothingWeight * LaplacianSmoothingSpeed(it,offset, gd);
460 laplacian_term =
ZERO;
463 return (
PixelType ) ( curvature_term - propagation_term
464 - advection_term - laplacian_term );