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>>
167 static constexpr
unsigned int ImageDimension = TOutputImage::ImageDimension;
194 GenerateInputRequestedRegion()
override;
203 this->SetUseImageSpacing(
true);
212 this->SetUseImageSpacing(
false);
218 SetUseImageSpacing(
bool);
220 itkGetConstMacro(UseImageSpacing,
bool);
227 itkGetConstReferenceMacro(DerivativeWeights,
WeightsType);
233 itkGetConstReferenceMacro(ComponentWeights,
WeightsType);
241 itkSetMacro(UsePrincipleComponents,
bool);
242 itkGetConstMacro(UsePrincipleComponents,
bool);
246 this->SetUsePrincipleComponents(
true);
253 this->SetUsePrincipleComponents(
false);
259 CubicSolver(
double *,
double *);
261 #ifdef ITK_USE_CONCEPT_CHECKING
276 BeforeThreadedGenerateData()
override;
290 DynamicThreadedGenerateData(
const OutputImageRegionType & outputRegionForThread)
override;
294 PrintSelf(std::ostream & os,
Indent indent)
const override;
305 TRealType dx, sum, accum;
308 for (i = 0; i < ImageDimension; ++i)
311 for (j = 0; j < VectorDimension; ++j)
313 dx = m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.
GetNext(i)[j] - it.
GetPrevious(i)[j]);
318 return std::sqrt(accum);
330 vnl_matrix<TRealType> g(ImageDimension, ImageDimension);
331 vnl_vector_fixed<TRealType, VectorDimension> d_phi_du[TInputImage::ImageDimension];
335 for (i = 0; i < ImageDimension; i++)
337 for (j = 0; j < VectorDimension; j++)
340 m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.
GetNext(i)[j] - it.
GetPrevious(i)[j]);
345 for (i = 0; i < ImageDimension; i++)
347 for (j = i; j < ImageDimension; j++)
349 g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
356 CharEqn[2] = -(g[0][0] + g[1][1] + g[2][2]);
358 CharEqn[1] = (g[0][0] * g[1][1] + g[0][0] * g[2][2] + g[1][1] * g[2][2]) -
359 (g[0][1] * g[1][0] + g[0][2] * g[2][0] + g[1][2] * g[2][1]);
361 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]) +
362 g[2][0] * (g[1][1] * g[0][2] - g[0][1] * g[1][2]);
365 int numberOfDistinctRoots = this->CubicSolver(CharEqn, Lambda);
369 if (numberOfDistinctRoots == 3)
371 if (Lambda[0] > Lambda[1])
373 if (Lambda[1] > Lambda[2])
375 ans = Lambda[0] - Lambda[1];
379 if (Lambda[0] > Lambda[2])
381 ans = Lambda[0] - Lambda[2];
385 ans = Lambda[2] - Lambda[0];
391 if (Lambda[0] > Lambda[2])
393 ans = Lambda[1] - Lambda[0];
397 if (Lambda[1] > Lambda[2])
399 ans = Lambda[1] - Lambda[2];
403 ans = Lambda[2] - Lambda[1];
408 else if (numberOfDistinctRoots == 2)
410 if (Lambda[0] > Lambda[1])
412 ans = Lambda[0] - Lambda[1];
416 ans = Lambda[1] - Lambda[0];
419 else if (numberOfDistinctRoots == 1)
425 itkExceptionMacro(<<
"Undefined condition. Cubic root solver returned " << numberOfDistinctRoots
426 <<
" distinct roots.");
440 vnl_matrix<TRealType> g(ImageDimension, ImageDimension);
441 vnl_vector_fixed<TRealType, VectorDimension> d_phi_du[TInputImage::ImageDimension];
445 for (i = 0; i < ImageDimension; i++)
447 for (j = 0; j < VectorDimension; j++)
450 m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.
GetNext(i)[j] - it.
GetPrevious(i)[j]);
455 for (i = 0; i < ImageDimension; i++)
457 for (j = i; j < ImageDimension; j++)
459 g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
464 vnl_symmetric_eigensystem<TRealType> E(g);
468 return (E.get_eigenvalue(ImageDimension - 1) - E.get_eigenvalue(ImageDimension - 2));
490 #ifndef ITK_MANUAL_INSTANTIATION
491 # include "itkVectorGradientMagnitudeImageFilter.hxx"