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"
133 template<
typename TInputImage,
134 typename TRealType = float,
135 typename TOutputImage = Image< TRealType,
136 TInputImage::ImageDimension >
168 static constexpr
unsigned int ImageDimension = TOutputImage::ImageDimension;
196 void GenerateInputRequestedRegion()
override;
203 { this->SetUseImageSpacing(
true); }
209 { this->SetUseImageSpacing(
false); }
213 void SetUseImageSpacing(
bool);
215 itkGetConstMacro(UseImageSpacing,
bool);
222 itkGetConstReferenceMacro(DerivativeWeights,
WeightsType);
228 itkGetConstReferenceMacro(ComponentWeights,
WeightsType);
236 itkSetMacro(UsePrincipleComponents,
bool);
237 itkGetConstMacro(UsePrincipleComponents,
bool);
240 this->SetUsePrincipleComponents(
true);
246 this->SetUsePrincipleComponents(
false);
251 static int CubicSolver(
double *,
double *);
253 #ifdef ITK_USE_CONCEPT_CHECKING
269 void BeforeThreadedGenerateData()
override;
282 void DynamicThreadedGenerateData(
const OutputImageRegionType & outputRegionForThread)
override;
285 void PrintSelf(std::ostream & os,
Indent indent)
const override;
295 TRealType dx, sum, accum;
298 for ( i = 0; i < ImageDimension; ++i )
301 for ( j = 0; j < VectorDimension; ++j )
303 dx = m_DerivativeWeights[i] * m_SqrtComponentWeights[j]
309 return std::sqrt(accum);
320 vnl_matrix< TRealType > g(ImageDimension, ImageDimension);
321 vnl_vector_fixed< TRealType, VectorDimension >
322 d_phi_du[TInputImage::ImageDimension];
326 for ( i = 0; i < ImageDimension; i++ )
328 for ( j = 0; j < VectorDimension; j++ )
330 d_phi_du[i][j] = m_DerivativeWeights[i] * m_SqrtComponentWeights[j]
336 for ( i = 0; i < ImageDimension; i++ )
338 for ( j = i; j < ImageDimension; j++ )
340 g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
347 CharEqn[2] = -( g[0][0] + g[1][1] + g[2][2] );
349 CharEqn[1] = ( g[0][0] * g[1][1] + g[0][0] * g[2][2] + g[1][1] * g[2][2] )
350 - ( g[0][1] * g[1][0] + g[0][2] * g[2][0] + g[1][2] * g[2][1] );
352 CharEqn[0] = g[0][0] * ( g[1][2] * g[2][1] - g[1][1] * g[2][2] )
353 + g[1][0] * ( g[2][2] * g[0][1] - g[0][2] * g[2][1] )
354 + g[2][0] * ( g[1][1] * g[0][2] - g[0][1] * g[1][2] );
357 int numberOfDistinctRoots = this->CubicSolver(CharEqn, Lambda);
361 if ( numberOfDistinctRoots == 3 )
363 if ( Lambda[0] > Lambda[1] )
365 if ( Lambda[1] > Lambda[2] )
367 ans = Lambda[0] - Lambda[1];
371 if ( Lambda[0] > Lambda[2] )
373 ans = Lambda[0] - Lambda[2];
377 ans = Lambda[2] - Lambda[0];
383 if ( Lambda[0] > Lambda[2] )
385 ans = Lambda[1] - Lambda[0];
389 if ( Lambda[1] > Lambda[2] )
391 ans = Lambda[1] - Lambda[2];
395 ans = Lambda[2] - Lambda[1];
400 else if ( numberOfDistinctRoots == 2 )
402 if ( Lambda[0] > Lambda[1] )
404 ans = Lambda[0] - Lambda[1];
408 ans = Lambda[1] - Lambda[0];
411 else if ( numberOfDistinctRoots == 1 )
417 itkExceptionMacro(<<
"Undefined condition. Cubic root solver returned "
418 << numberOfDistinctRoots <<
" distinct roots.");
431 vnl_matrix< TRealType > g(ImageDimension, ImageDimension);
432 vnl_vector_fixed< TRealType, VectorDimension >
433 d_phi_du[TInputImage::ImageDimension];
437 for ( i = 0; i < ImageDimension; i++ )
439 for ( j = 0; j < VectorDimension; j++ )
441 d_phi_du[i][j] = m_DerivativeWeights[i] * m_SqrtComponentWeights[j]
447 for ( i = 0; i < ImageDimension; i++ )
449 for ( j = i; j < ImageDimension; j++ )
451 g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
456 vnl_symmetric_eigensystem< TRealType > E(g);
460 return ( E.get_eigenvalue(ImageDimension - 1) - E.get_eigenvalue(ImageDimension - 2) );
483 #ifndef ITK_MANUAL_INSTANTIATION
484 #include "itkVectorGradientMagnitudeImageFilter.hxx"
WeightsType m_SqrtComponentWeights
typename OutputImageType::Pointer OutputImagePointer
WeightsType m_ComponentWeights
bool m_UsePrincipleComponents
void SetUsePrincipleComponentsOn()
Define numeric traits for std::vector.
WeightsType m_DerivativeWeights
ImageBaseType::ConstPointer m_RealValuedInputImage
TRealType EvaluateAtNeighborhood3D(const ConstNeighborhoodIteratorType &it) const
typename TOutputImage::PixelType OutputPixelType
The base class for all process objects (source, filters, mappers) in the Insight data processing pipe...
Base class for all process objects that output image data.
Const version of NeighborhoodIterator, defining iteration of a local N-dimensional neighborhood of pi...
typename ConstNeighborhoodIteratorType::RadiusType RadiusType
constexpr unsigned int Dimension
Computes a scalar, gradient magnitude image from a multiple channel (pixels are vectors) input...
TInputImage InputImageType
ITK_ITERATOR_VIRTUAL PixelType GetPrevious(const unsigned axis, NeighborIndexType i) const ITK_ITERATOR_FINAL
typename InputImageType::Pointer InputImagePointer
A templated class holding a n-Dimensional vector.
typename TInputImage::PixelType InputPixelType
typename OutputImageType::RegionType OutputImageRegionType
TOutputImage OutputImageType
TRealType NonPCEvaluateAtNeighborhood(const ConstNeighborhoodIteratorType &it) const
unsigned int ThreadIdType
typename InputImageType::Superclass ImageBaseType
void SetUseImageSpacingOff()
void SetUsePrincipleComponentsOff()
Base class for filters that take an image as input and produce an image as output.
ITK_ITERATOR_VIRTUAL PixelType GetNext(const unsigned axis, NeighborIndexType i) const ITK_ITERATOR_FINAL
Control indentation during Print() invocation.
typename Superclass::RadiusType RadiusType
#define itkConceptMacro(name, concept)
ThreadIdType m_RequestedNumberOfThreads
Templated n-dimensional image class.
TRealType EvaluateAtNeighborhood(const ConstNeighborhoodIteratorType &it) const
void SetUseImageSpacingOn()