18 #ifndef itkVectorGradientMagnitudeImageFilter_h
19 #define itkVectorGradientMagnitudeImageFilter_h
25 #include "vnl/vnl_matrix.h"
26 #include "vnl/vnl_vector_fixed.h"
27 #include "vnl/algo/vnl_symmetric_eigensystem.h"
134 template<
typename TInputImage,
135 typename TRealType = float,
136 typename TOutputImage = Image< TRealType,
137 TInputImage::ImageDimension >
167 itkStaticConstMacro(ImageDimension,
unsigned int,
168 TOutputImage::ImageDimension);
171 itkStaticConstMacro(VectorDimension,
unsigned int,
197 virtual void GenerateInputRequestedRegion() ITK_OVERRIDE;
203 void SetUseImageSpacingOn()
204 { this->SetUseImageSpacing(
true); }
210 { this->SetUseImageSpacing(
false); }
214 void SetUseImageSpacing(
bool);
216 itkGetConstMacro(UseImageSpacing,
bool);
223 itkGetConstReferenceMacro(DerivativeWeights,
WeightsType);
229 itkGetConstReferenceMacro(ComponentWeights,
WeightsType);
232 #ifndef ITK_LEGACY_REMOVE
234 virtual const RadiusType GetNeighborhoodRadius()
const
243 virtual void SetNeighborhoodRadius(
const RadiusType) {}
251 itkSetMacro(UsePrincipleComponents,
bool);
252 itkGetConstMacro(UsePrincipleComponents,
bool);
255 this->SetUsePrincipleComponents(
true);
261 this->SetUsePrincipleComponents(
false);
266 static int CubicSolver(
double *,
double *);
268 #ifdef ITK_USE_CONCEPT_CHECKING
284 void BeforeThreadedGenerateData() ITK_OVERRIDE;
297 void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,
300 void PrintSelf(std::ostream & os,
Indent indent) const ITK_OVERRIDE;
305 itkGetConstObjectMacro(RealValuedInputImage, ImageBaseType);
310 TRealType dx, sum, accum;
313 for ( i = 0; i < ImageDimension; ++i )
316 for ( j = 0; j < VectorDimension; ++j )
318 dx = m_DerivativeWeights[i] * m_SqrtComponentWeights[j]
319 * 0.5 * ( it.GetNext(i)[j] - it.GetPrevious(i)[j] );
324 return std::sqrt(accum);
335 vnl_matrix< TRealType > g(ImageDimension, ImageDimension);
336 vnl_vector_fixed< TRealType, VectorDimension >
337 d_phi_du[TInputImage::ImageDimension];
341 for ( i = 0; i < ImageDimension; i++ )
343 for ( j = 0; j < VectorDimension; j++ )
345 d_phi_du[i][j] = m_DerivativeWeights[i] * m_SqrtComponentWeights[j]
351 for ( i = 0; i < ImageDimension; i++ )
353 for ( j = i; j < ImageDimension; j++ )
355 g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
362 CharEqn[2] = -( g[0][0] + g[1][1] + g[2][2] );
364 CharEqn[1] = ( g[0][0] * g[1][1] + g[0][0] * g[2][2] + g[1][1] * g[2][2] )
365 - ( g[0][1] * g[1][0] + g[0][2] * g[2][0] + g[1][2] * g[2][1] );
367 CharEqn[0] = g[0][0] * ( g[1][2] * g[2][1] - g[1][1] * g[2][2] )
368 + g[1][0] * ( g[2][2] * g[0][1] - g[0][2] * g[2][1] )
369 + g[2][0] * ( g[1][1] * g[0][2] - g[0][1] * g[1][2] );
372 int numberOfDistinctRoots = this->CubicSolver(CharEqn, Lambda);
376 if ( numberOfDistinctRoots == 3 )
378 if ( Lambda[0] > Lambda[1] )
380 if ( Lambda[1] > Lambda[2] )
382 ans = Lambda[0] - Lambda[1];
386 if ( Lambda[0] > Lambda[2] )
388 ans = Lambda[0] - Lambda[2];
392 ans = Lambda[2] - Lambda[0];
398 if ( Lambda[0] > Lambda[2] )
400 ans = Lambda[1] - Lambda[0];
404 if ( Lambda[1] > Lambda[2] )
406 ans = Lambda[1] - Lambda[2];
410 ans = Lambda[2] - Lambda[1];
415 else if ( numberOfDistinctRoots == 2 )
417 if ( Lambda[0] > Lambda[1] )
419 ans = Lambda[0] - Lambda[1];
423 ans = Lambda[1] - Lambda[0];
426 else if ( numberOfDistinctRoots == 1 )
432 itkExceptionMacro(<<
"Undefined condition. Cubic root solver returned "
433 << numberOfDistinctRoots <<
" distinct roots.");
446 vnl_matrix< TRealType > g(ImageDimension, ImageDimension);
447 vnl_vector_fixed< TRealType, VectorDimension >
448 d_phi_du[TInputImage::ImageDimension];
452 for ( i = 0; i < ImageDimension; i++ )
454 for ( j = 0; j < VectorDimension; j++ )
456 d_phi_du[i][j] = m_DerivativeWeights[i] * m_SqrtComponentWeights[j]
462 for ( i = 0; i < ImageDimension; i++ )
464 for ( j = i; j < ImageDimension; j++ )
466 g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
471 vnl_symmetric_eigensystem< TRealType > E(g);
475 return ( E.get_eigenvalue(ImageDimension - 1) - E.get_eigenvalue(ImageDimension - 2) );
499 #ifndef ITK_MANUAL_INSTANTIATION
500 #include "itkVectorGradientMagnitudeImageFilter.hxx"
WeightsType m_SqrtComponentWeights
WeightsType m_ComponentWeights
ConstNeighborhoodIterator< RealVectorImageType > ConstNeighborhoodIteratorType
bool m_UsePrincipleComponents
void SetUsePrincipleComponentsOn()
FixedArray< TRealType, VectorDimension > WeightsType
WeightsType m_DerivativeWeights
ImageBaseType::ConstPointer m_RealValuedInputImage
TRealType EvaluateAtNeighborhood3D(const ConstNeighborhoodIteratorType &it) const
SmartPointer< const Self > ConstPointer
TOutputImage OutputImageType
TInputImage InputImageType
SmartPointer< Self > Pointer
The base class for all process objects (source, filters, mappers) in the Insight data processing pipe...
ImageToImageFilter< TInputImage, TOutputImage > Superclass
Superclass::OutputImageRegionType OutputImageRegionType
Superclass::RadiusType RadiusType
Base class for all process objects that output image data.
Const version of NeighborhoodIterator, defining iteration of a local N-dimensional neighborhood of pi...
ConstNeighborhoodIteratorType::RadiusType RadiusType
virtual PixelType GetPrevious(const unsigned axis, NeighborIndexType i) const
Computes a scalar, gradient magnitude image from a multiple channel (pixels are vectors) input...
virtual PixelType GetNext(const unsigned axis, NeighborIndexType i) const
TOutputImage::PixelType OutputPixelType
InputImageType::Pointer InputImagePointer
VectorGradientMagnitudeImageFilter Self
OutputImageType::Pointer OutputImagePointer
A templated class holding a n-Dimensional vector.
TInputImage::PixelType InputPixelType
Vector< TRealType, InputPixelType::Dimension > RealVectorType
TInputImage InputImageType
const unsigned int Dimension
unsigned int ThreadIdType
void SetUseImageSpacingOff()
void SetUsePrincipleComponentsOff()
Base class for filters that take an image as input and produce an image as output.
Control indentation during Print() invocation.
#define itkConceptMacro(name, concept)
InputImageType::Superclass ImageBaseType
ThreadIdType m_RequestedNumberOfThreads
Image< RealVectorType, TInputImage::ImageDimension > RealVectorImageType
Templated n-dimensional image class.
TRealType EvaluateAtNeighborhood(const ConstNeighborhoodIteratorType &it) const
virtual ~VectorGradientMagnitudeImageFilter() override