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"
135 template <
typename TInputImage,
136 typename TRealType = float,
137 typename TOutputImage = Image<TRealType, TInputImage::ImageDimension>>
168 static constexpr
unsigned int InputImageDimension = TInputImage::ImageDimension;
169 static constexpr
unsigned int ImageDimension = TOutputImage::ImageDimension;
196 GenerateInputRequestedRegion()
override;
204 SetUseImageSpacing(
bool);
205 itkGetConstMacro(UseImageSpacing,
bool);
206 itkBooleanMacro(UseImageSpacing);
209 #if !defined(ITK_FUTURE_LEGACY_REMOVE)
216 SetUseImageSpacingOn()
218 this->SetUseImageSpacing(
true);
226 SetUseImageSpacingOff()
228 this->SetUseImageSpacing(
false);
234 #if !defined(ITK_LEGACY_REMOVE)
235 using WeightsType ITK_DEPRECATED_MSG(
"Use DerivativeWeightsType or ComponentWeightsType instead.") =
256 itkSetMacro(UsePrincipleComponents,
bool);
257 itkGetConstMacro(UsePrincipleComponents,
bool);
258 itkBooleanMacro(UsePrincipleComponents);
261 #if !defined(ITK_FUTURE_LEGACY_REMOVE)
264 SetUsePrincipleComponentsOn()
266 this->SetUsePrincipleComponents(
true);
271 SetUsePrincipleComponentsOff()
273 this->SetUsePrincipleComponents(
false);
280 CubicSolver(
const double *,
double *);
282 #ifdef ITK_USE_CONCEPT_CHECKING
284 itkConceptMacro(SameDimensionCheck, (Concept::SameDimension<InputImageDimension, ImageDimension>));
285 itkConceptMacro(InputHasNumericTraitsCheck, (Concept::HasNumericTraits<typename InputPixelType::ValueType>));
286 itkConceptMacro(RealTypeHasNumericTraitsCheck, (Concept::HasNumericTraits<RealType>));
291 VectorGradientMagnitudeImageFilter();
292 ~VectorGradientMagnitudeImageFilter()
override =
default;
298 BeforeThreadedGenerateData()
override;
312 DynamicThreadedGenerateData(
const OutputImageRegionType & outputRegionForThread)
override;
316 PrintSelf(std::ostream & os, Indent indent)
const override;
327 TRealType dx, sum, accum;
330 for (i = 0; i < ImageDimension; ++i)
333 for (j = 0; j < VectorDimension; ++j)
335 dx = m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.
GetNext(i)[j] - it.
GetPrevious(i)[j]);
340 return std::sqrt(accum);
352 vnl_matrix<TRealType> g(ImageDimension, ImageDimension);
353 vnl_vector_fixed<TRealType, VectorDimension> d_phi_du[TInputImage::ImageDimension];
357 for (i = 0; i < ImageDimension; i++)
359 for (j = 0; j < VectorDimension; j++)
362 m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.
GetNext(i)[j] - it.
GetPrevious(i)[j]);
367 for (i = 0; i < ImageDimension; i++)
369 for (j = i; j < ImageDimension; j++)
371 g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
378 CharEqn[2] = -(g[0][0] + g[1][1] + g[2][2]);
380 CharEqn[1] = (g[0][0] * g[1][1] + g[0][0] * g[2][2] + g[1][1] * g[2][2]) -
381 (g[0][1] * g[1][0] + g[0][2] * g[2][0] + g[1][2] * g[2][1]);
383 CharEqn[0] = g[0][0] * (g[1][2] * g[2][1] - g[1][1] * g[2][2]) + g[1][0] * (g[2][2] * g[0][1] - g[0][2] * g[2][1]) +
384 g[2][0] * (g[1][1] * g[0][2] - g[0][1] * g[1][2]);
387 int numberOfDistinctRoots = this->CubicSolver(CharEqn, Lambda);
391 if (numberOfDistinctRoots == 3)
393 if (Lambda[0] > Lambda[1])
395 if (Lambda[1] > Lambda[2])
397 ans = Lambda[0] - Lambda[1];
401 if (Lambda[0] > Lambda[2])
403 ans = Lambda[0] - Lambda[2];
407 ans = Lambda[2] - Lambda[0];
413 if (Lambda[0] > Lambda[2])
415 ans = Lambda[1] - Lambda[0];
419 if (Lambda[1] > Lambda[2])
421 ans = Lambda[1] - Lambda[2];
425 ans = Lambda[2] - Lambda[1];
430 else if (numberOfDistinctRoots == 2)
432 if (Lambda[0] > Lambda[1])
434 ans = Lambda[0] - Lambda[1];
438 ans = Lambda[1] - Lambda[0];
441 else if (numberOfDistinctRoots == 1)
447 itkExceptionMacro(<<
"Undefined condition. Cubic root solver returned " << numberOfDistinctRoots
448 <<
" distinct roots.");
462 vnl_matrix<TRealType> g(ImageDimension, ImageDimension);
463 vnl_vector_fixed<TRealType, VectorDimension> d_phi_du[TInputImage::ImageDimension];
467 for (i = 0; i < ImageDimension; i++)
469 for (j = 0; j < VectorDimension; j++)
472 m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.
GetNext(i)[j] - it.
GetPrevious(i)[j]);
477 for (i = 0; i < ImageDimension; i++)
479 for (j = i; j < ImageDimension; j++)
481 g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
486 vnl_symmetric_eigensystem<TRealType> E(g);
490 return (E.get_eigenvalue(ImageDimension - 1) - E.get_eigenvalue(ImageDimension - 2));
513 #ifndef ITK_MANUAL_INSTANTIATION
514 # include "itkVectorGradientMagnitudeImageFilter.hxx"