17 #ifndef __itkMinMaxCurvatureFlowFunction_txx
18 #define __itkMinMaxCurvatureFlowFunction_txx
21 #include "vnl/vnl_math.h"
29 template<
class TImage>
34 this->SetStencilRadius( 2 );
42 template<
class TImage>
47 if ( m_StencilRadius == value ) {
return; }
49 m_StencilRadius = (value > 1) ? value: 1;
53 for ( j = 0; j < ImageDimension; j++ )
55 radius[j] = m_StencilRadius;
58 this->SetRadius( radius );
59 this->InitializeStencilOperator();
67 template<
class TImage>
74 m_StencilOperator.SetRadius( m_StencilRadius );
80 for ( j = 0; j < ImageDimension; j++ )
87 Iterator opEnd = m_StencilOperator.End();
89 unsigned long numPixelsInSphere = 0;
91 for ( opIter = m_StencilOperator.Begin(); opIter < opEnd; ++opIter )
97 for ( j = 0; j < ImageDimension; j++ )
100 vnl_math_sqr( static_cast<signed long>(counter[j]) -
101 static_cast<signed long>(m_StencilRadius) ) );
103 if ( length <= sqrRadius )
109 bool carryOver =
true;
110 for ( j = 0; carryOver && j < ImageDimension; j++ )
114 if ( counter[j] == span )
124 for ( opIter = m_StencilOperator.Begin(); opIter < opEnd; ++opIter )
126 *opIter =
static_cast<PixelType>( (double) *opIter /
127 (
double) numPixelsInSphere );
136 template<
class TImage>
147 unsigned long stride;
148 unsigned long center;
151 center = it.
Size()/2;
154 for ( j = 0; j < ImageDimension; j++ )
156 stride = it.
GetStride( (
unsigned long) j );
157 gradient[j] = 0.5 * ( it.
GetPixel( center + stride ) -
159 gradient[j] *= this->m_ScaleCoefficients[j];
161 gradMagnitude += vnl_math_sqr( (
double)gradient[j] );
164 if ( gradMagnitude == 0.0 ) {
return threshold; }
166 gradMagnitude = vcl_sqrt( (
double)gradMagnitude );
173 for ( j = 0; j < ImageDimension; j++ )
180 Iterator neighEnd = it.
End();
183 unsigned long numPixels = 0;
185 for ( neighIter = it.
Begin(); neighIter < neighEnd; ++neighIter, ++i )
191 for ( j = 0; j < ImageDimension; j++ )
193 signed long diff =
static_cast<signed long>( counter[j] ) -
194 static_cast<signed long>( m_StencilRadius );
196 dotProduct +=
static_cast<PixelType>( diff ) * gradient[j];
197 vectorMagnitude +=
static_cast<PixelType>( vnl_math_sqr( diff ) );
201 vectorMagnitude = vcl_sqrt( (
double)vectorMagnitude );
203 if ( vectorMagnitude != 0.0 )
205 dotProduct /= gradMagnitude * vectorMagnitude;
208 if ( vectorMagnitude >= m_StencilRadius && vnl_math_abs(dotProduct) < 0.262 )
214 bool carryOver =
true;
215 for ( j = 0; carryOver && j < ImageDimension; j++ )
219 if ( counter[j] == span )
230 threshold /=
static_cast<PixelType>( numPixels );
242 template<
class TImage>
247 const signed int imageDimension = 2;
256 unsigned long stride;
257 unsigned long center;
258 unsigned long position[imageDimension];
261 center = it.
Size()/2;
263 gradient[0] = 0.5 * ( it.
GetPixel( center + 1 ) -
266 gradient[k] *= this->m_ScaleCoefficients[k];
267 gradMagnitude = vnl_math_sqr( (
double)gradient[k] );
271 gradient[k] = 0.5 * ( it.
GetPixel( center + stride ) -
273 gradient[k] *= this->m_ScaleCoefficients[k];
274 gradMagnitude += vnl_math_sqr( (
double)gradient[k] );
276 if ( gradMagnitude == 0.0 ) {
return threshold; }
278 gradMagnitude = vcl_sqrt( (
double)gradMagnitude ) /
279 static_cast<PixelType>( m_StencilRadius );
281 for ( j = 0; j < imageDimension; j++ )
283 gradient[j] /= gradMagnitude;
288 position[0] = Math::Round<unsigned long>( (double)(m_StencilRadius - gradient[1]) );
289 position[1] = Math::Round<unsigned long>( (double)(m_StencilRadius + gradient[0]) );
292 threshold = it.
GetPixel( position[0] + stride * position[1] );
295 position[0] = Math::Round<unsigned long>( (double)(m_StencilRadius + gradient[1]) );
296 position[1] = Math::Round<unsigned long>( (double)(m_StencilRadius - gradient[0]) );
299 threshold += it.
GetPixel( position[0] + stride * position[1] );
311 template<
class TImage>
317 const signed int imageDimension = 3;
326 unsigned long strideY, strideZ;
327 unsigned long center;
328 unsigned long position[imageDimension];
331 center = it.
Size()/2;
335 gradient[0] = 0.5 * ( it.
GetPixel( center + 1 ) -
338 gradient[k] *= this->m_ScaleCoefficients[k];
339 gradMagnitude = vnl_math_sqr( (
double)gradient[k] );
342 gradient[k] = 0.5 * ( it.
GetPixel( center + strideY ) -
344 gradient[k] *= this->m_ScaleCoefficients[k];
345 gradMagnitude += vnl_math_sqr( (
double)gradient[k] );
348 gradient[k] = 0.5 * ( it.
GetPixel( center + strideZ ) -
350 gradient[k] *= this->m_ScaleCoefficients[k];
351 gradMagnitude += vnl_math_sqr( (
double)gradient[k] );
353 if ( gradMagnitude == 0.0 ) {
return threshold; }
355 gradMagnitude = vcl_sqrt( (
double)gradMagnitude ) /
356 static_cast<PixelType>( m_StencilRadius );
358 for ( j = 0; j < imageDimension; j++ )
360 gradient[j] /= gradMagnitude;
364 if (gradient[2] > 1.0)
368 if (gradient[2] < -1.0)
372 theta = vcl_acos((
double)gradient[2] );
374 if ( gradient[0] == 0 )
376 phi = vnl_math::pi * 0.5;
380 phi = vcl_atan((
double)gradient[1]/ (
double)gradient[0] );
384 double cosTheta = vcl_cos(theta );
385 double sinTheta = vcl_sin(theta );
386 double cosPhi = vcl_cos(phi );
387 double sinPhi = vcl_sin(phi );
389 double rSinTheta = m_StencilRadius * sinTheta;
390 double rCosThetaCosPhi = m_StencilRadius * cosTheta * cosPhi;
391 double rCosThetaSinPhi = m_StencilRadius * cosTheta * sinPhi;
392 double rSinPhi = m_StencilRadius * sinPhi;
393 double rCosPhi = m_StencilRadius * cosPhi;
396 position[0] = Math::Round<unsigned long>( m_StencilRadius + rCosThetaCosPhi );
397 position[1] = Math::Round<unsigned long>( m_StencilRadius + rCosThetaSinPhi );
398 position[2] = Math::Round<unsigned long>( m_StencilRadius - rSinTheta );
400 threshold += it.
GetPixel( position[0] +
401 strideY * position[1] + strideZ * position[2] );
404 position[0] = Math::Round<unsigned long>( m_StencilRadius - rSinPhi );
405 position[1] = Math::Round<unsigned long>( m_StencilRadius + rCosPhi );
406 position[2] = m_StencilRadius;
408 threshold += it.
GetPixel( position[0] +
409 strideY * position[1] + strideZ * position[2] );
412 position[0] = Math::Round<unsigned long>( m_StencilRadius - rCosThetaCosPhi );
413 position[1] = Math::Round<unsigned long>( m_StencilRadius - rCosThetaSinPhi );
414 position[2] = Math::Round<unsigned long>( m_StencilRadius + rSinTheta );
416 threshold += it.
GetPixel( position[0] +
417 strideY * position[1] + strideZ * position[2] );
420 position[0] = Math::Round<unsigned long>( m_StencilRadius + rSinPhi );
421 position[1] = Math::Round<unsigned long>( m_StencilRadius - rCosPhi );
422 position[2] = m_StencilRadius;
424 threshold += it.
GetPixel( position[0] +
425 strideY * position[1] + strideZ * position[2] );
436 template<
class TImage>
442 PixelType update = this->Superclass::ComputeUpdate(
443 it, globalData, offset );
454 PixelType avgValue = innerProduct( it, m_StencilOperator );
456 if ( avgValue < threshold )