ITK  5.1.0
Insight Toolkit
itkVectorGradientMagnitudeImageFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkVectorGradientMagnitudeImageFilter_h
19 #define itkVectorGradientMagnitudeImageFilter_h
20 
22 #include "itkImageToImageFilter.h"
23 #include "itkImage.h"
24 #include "itkVector.h"
25 #include "vnl/vnl_matrix.h"
26 #include "vnl/vnl_vector_fixed.h"
27 #include "vnl/algo/vnl_symmetric_eigensystem.h"
28 #include "itkMath.h"
29 
30 namespace itk
31 {
133 template <typename TInputImage,
134  typename TRealType = float,
135  typename TOutputImage = Image<TRealType, TInputImage::ImageDimension>>
136 class ITK_TEMPLATE_EXPORT VectorGradientMagnitudeImageFilter : public ImageToImageFilter<TInputImage, TOutputImage>
137 {
138 public:
139  ITK_DISALLOW_COPY_AND_ASSIGN(VectorGradientMagnitudeImageFilter);
140 
146 
148  itkNewMacro(Self);
149 
152 
155  using OutputPixelType = typename TOutputImage::PixelType;
156  using InputPixelType = typename TInputImage::PixelType;
157 
159  using InputImageType = TInputImage;
160  using OutputImageType = TOutputImage;
161  using InputImagePointer = typename InputImageType::Pointer;
162  using OutputImagePointer = typename OutputImageType::Pointer;
163 
165  static constexpr unsigned int ImageDimension = TOutputImage::ImageDimension;
166 
168  static constexpr unsigned int VectorDimension = InputPixelType::Dimension;
169 
171  using RealType = TRealType;
174 
179 
181  using OutputImageRegionType = typename Superclass::OutputImageRegionType;
182 
191  void
192  GenerateInputRequestedRegion() override;
193 
198  void
200  {
201  this->SetUseImageSpacing(true);
202  }
203 
207  void
209  {
210  this->SetUseImageSpacing(false);
211  }
212 
215  void
216  SetUseImageSpacing(bool);
217 
218  itkGetConstMacro(UseImageSpacing, bool);
219 
221 
224  itkSetMacro(DerivativeWeights, WeightsType);
225  itkGetConstReferenceMacro(DerivativeWeights, WeightsType);
227 
230  itkSetMacro(ComponentWeights, WeightsType);
231  itkGetConstReferenceMacro(ComponentWeights, WeightsType);
233 
239  itkSetMacro(UsePrincipleComponents, bool);
240  itkGetConstMacro(UsePrincipleComponents, bool);
241  void
243  {
244  this->SetUsePrincipleComponents(true);
245  }
247 
248  void
250  {
251  this->SetUsePrincipleComponents(false);
252  }
253 
256  static int
257  CubicSolver(double *, double *);
258 
259 #ifdef ITK_USE_CONCEPT_CHECKING
260  // Begin concept checking
262  itkConceptMacro(RealTypeHasNumericTraitsCheck, (Concept::HasNumericTraits<RealType>));
263  // End concept checking
264 #endif
265 
266 protected:
268  ~VectorGradientMagnitudeImageFilter() override = default;
269 
273  void
274  BeforeThreadedGenerateData() override;
275 
287  void
288  DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override;
289 
290 
291  void
292  PrintSelf(std::ostream & os, Indent indent) const override;
293 
294  using ImageBaseType = typename InputImageType::Superclass;
295 
297  itkGetConstObjectMacro(RealValuedInputImage, RealVectorImageType);
298 
299  TRealType
301  {
302  unsigned i, j;
303  TRealType dx, sum, accum;
304 
306  for (i = 0; i < ImageDimension; ++i)
307  {
309  for (j = 0; j < VectorDimension; ++j)
310  {
311  dx = m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.GetNext(i)[j] - it.GetPrevious(i)[j]);
312  sum += dx * dx;
313  }
314  accum += sum;
315  }
316  return std::sqrt(accum);
317  }
318 
319  TRealType
321  {
322  // WARNING: ONLY CALL THIS METHOD WHEN PROCESSING A 3D IMAGE
323  unsigned int i, j;
324  double Lambda[3];
325  double CharEqn[3];
326  double ans;
327 
328  vnl_matrix<TRealType> g(ImageDimension, ImageDimension);
329  vnl_vector_fixed<TRealType, VectorDimension> d_phi_du[TInputImage::ImageDimension];
330 
331  // Calculate the directional derivatives for each vector component using
332  // central differences.
333  for (i = 0; i < ImageDimension; i++)
334  {
335  for (j = 0; j < VectorDimension; j++)
336  {
337  d_phi_du[i][j] =
338  m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.GetNext(i)[j] - it.GetPrevious(i)[j]);
339  }
340  }
341 
342  // Calculate the symmetric metric tensor g
343  for (i = 0; i < ImageDimension; i++)
344  {
345  for (j = i; j < ImageDimension; j++)
346  {
347  g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
348  }
349  }
350 
351  // Find the coefficients of the characteristic equation det(g - lambda I)=0
352  // CharEqn[3] = 1.0;
353 
354  CharEqn[2] = -(g[0][0] + g[1][1] + g[2][2]);
355 
356  CharEqn[1] = (g[0][0] * g[1][1] + g[0][0] * g[2][2] + g[1][1] * g[2][2]) -
357  (g[0][1] * g[1][0] + g[0][2] * g[2][0] + g[1][2] * g[2][1]);
358 
359  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]) +
360  g[2][0] * (g[1][1] * g[0][2] - g[0][1] * g[1][2]);
361 
362  // Find the eigenvalues of g
363  int numberOfDistinctRoots = this->CubicSolver(CharEqn, Lambda);
364 
365  // Define gradient magnitude as the difference between two largest
366  // eigenvalues. Other definitions may be appropriate here as well.
367  if (numberOfDistinctRoots == 3) // By far the most common case
368  {
369  if (Lambda[0] > Lambda[1])
370  {
371  if (Lambda[1] > Lambda[2]) // Most common, guaranteed?
372  {
373  ans = Lambda[0] - Lambda[1];
374  }
375  else
376  {
377  if (Lambda[0] > Lambda[2])
378  {
379  ans = Lambda[0] - Lambda[2];
380  }
381  else
382  {
383  ans = Lambda[2] - Lambda[0];
384  }
385  }
386  }
387  else
388  {
389  if (Lambda[0] > Lambda[2])
390  {
391  ans = Lambda[1] - Lambda[0];
392  }
393  else
394  {
395  if (Lambda[1] > Lambda[2])
396  {
397  ans = Lambda[1] - Lambda[2];
398  }
399  else
400  {
401  ans = Lambda[2] - Lambda[1];
402  }
403  }
404  }
405  }
406  else if (numberOfDistinctRoots == 2)
407  {
408  if (Lambda[0] > Lambda[1])
409  {
410  ans = Lambda[0] - Lambda[1];
411  }
412  else
413  {
414  ans = Lambda[1] - Lambda[0];
415  }
416  }
417  else if (numberOfDistinctRoots == 1)
418  {
419  ans = 0.0;
420  }
421  else
422  {
423  itkExceptionMacro(<< "Undefined condition. Cubic root solver returned " << numberOfDistinctRoots
424  << " distinct roots.");
425  }
426 
427  return ans;
428  }
429 
430  // Function is defined here because the templating confuses gcc 2.96 when
431  // defined
432  // in .hxx file. jc 1/29/03
433  TRealType
435  {
436  unsigned int i, j;
437 
438  vnl_matrix<TRealType> g(ImageDimension, ImageDimension);
439  vnl_vector_fixed<TRealType, VectorDimension> d_phi_du[TInputImage::ImageDimension];
440 
441  // Calculate the directional derivatives for each vector component using
442  // central differences.
443  for (i = 0; i < ImageDimension; i++)
444  {
445  for (j = 0; j < VectorDimension; j++)
446  {
447  d_phi_du[i][j] =
448  m_DerivativeWeights[i] * m_SqrtComponentWeights[j] * 0.5 * (it.GetNext(i)[j] - it.GetPrevious(i)[j]);
449  }
450  }
451 
452  // Calculate the symmetric metric tensor g
453  for (i = 0; i < ImageDimension; i++)
454  {
455  for (j = i; j < ImageDimension; j++)
456  {
457  g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
458  }
459  }
460 
461  // Find the eigenvalues of g
462  vnl_symmetric_eigensystem<TRealType> E(g);
463 
464  // Return the difference in length between the first two principle axes.
465  // Note that other edge strength metrics may be appropriate here instead..
466  return (E.get_eigenvalue(ImageDimension - 1) - E.get_eigenvalue(ImageDimension - 2));
467  }
468 
471 
477 
478 private:
481 
483 
485 };
486 } // end namespace itk
487 
488 #ifndef ITK_MANUAL_INSTANTIATION
489 # include "itkVectorGradientMagnitudeImageFilter.hxx"
490 #endif
491 
492 #endif
itk::VectorGradientMagnitudeImageFilter::m_DerivativeWeights
WeightsType m_DerivativeWeights
Definition: itkVectorGradientMagnitudeImageFilter.h:470
itk::VectorGradientMagnitudeImageFilter::RadiusType
typename ConstNeighborhoodIteratorType::RadiusType RadiusType
Definition: itkVectorGradientMagnitudeImageFilter.h:178
itk::VectorGradientMagnitudeImageFilter::m_RequestedNumberOfThreads
ThreadIdType m_RequestedNumberOfThreads
Definition: itkVectorGradientMagnitudeImageFilter.h:482
itk::ConstNeighborhoodIterator::RadiusType
typename Superclass::RadiusType RadiusType
Definition: itkConstNeighborhoodIterator.h:70
itk::Concept::HasNumericTraits
Definition: itkConceptChecking.h:712
itk::ImageSource::OutputImagePointer
typename OutputImageType::Pointer OutputImagePointer
Definition: itkImageSource.h:91
itk::VectorGradientMagnitudeImageFilter
Computes a scalar, gradient magnitude image from a multiple channel (pixels are vectors) input.
Definition: itkVectorGradientMagnitudeImageFilter.h:136
itkNeighborhoodIterator.h
itk::Vector
A templated class holding a n-Dimensional vector.
Definition: itkVector.h:62
itk::VectorGradientMagnitudeImageFilter::InputPixelType
typename TInputImage::PixelType InputPixelType
Definition: itkVectorGradientMagnitudeImageFilter.h:156
itkImage.h
itk::VectorGradientMagnitudeImageFilter::SetUsePrincipleComponentsOff
void SetUsePrincipleComponentsOff()
Definition: itkVectorGradientMagnitudeImageFilter.h:249
itk::SmartPointer< Self >
itk::Indent
Control indentation during Print() invocation.
Definition: itkIndent.h:49
itk::ConstNeighborhoodIterator::GetPrevious
ITK_ITERATOR_VIRTUAL PixelType GetPrevious(const unsigned axis, NeighborIndexType i) const ITK_ITERATOR_FINAL
Definition: itkConstNeighborhoodIterator.h:260
itk::VectorGradientMagnitudeImageFilter::SetUseImageSpacingOn
void SetUseImageSpacingOn()
Definition: itkVectorGradientMagnitudeImageFilter.h:199
itk::VectorGradientMagnitudeImageFilter::m_UsePrincipleComponents
bool m_UsePrincipleComponents
Definition: itkVectorGradientMagnitudeImageFilter.h:480
itk::VectorGradientMagnitudeImageFilter::m_SqrtComponentWeights
WeightsType m_SqrtComponentWeights
Definition: itkVectorGradientMagnitudeImageFilter.h:476
itk::ThreadIdType
unsigned int ThreadIdType
Definition: itkIntTypes.h:99
itk::ImageToImageFilter
Base class for filters that take an image as input and produce an image as output.
Definition: itkImageToImageFilter.h:108
itk::ImageSource
Base class for all process objects that output image data.
Definition: itkImageSource.h:67
itk::VectorGradientMagnitudeImageFilter::EvaluateAtNeighborhood
TRealType EvaluateAtNeighborhood(const ConstNeighborhoodIteratorType &it) const
Definition: itkVectorGradientMagnitudeImageFilter.h:434
itk::ImageToImageFilter::InputImagePointer
typename InputImageType::Pointer InputImagePointer
Definition: itkImageToImageFilter.h:130
itk::VectorGradientMagnitudeImageFilter::SetUsePrincipleComponentsOn
void SetUsePrincipleComponentsOn()
Definition: itkVectorGradientMagnitudeImageFilter.h:242
itk::ImageToImageFilter::InputImageType
TInputImage InputImageType
Definition: itkImageToImageFilter.h:129
itkImageToImageFilter.h
itk::VectorGradientMagnitudeImageFilter::EvaluateAtNeighborhood3D
TRealType EvaluateAtNeighborhood3D(const ConstNeighborhoodIteratorType &it) const
Definition: itkVectorGradientMagnitudeImageFilter.h:320
itk::VectorGradientMagnitudeImageFilter::RealType
TRealType RealType
Definition: itkVectorGradientMagnitudeImageFilter.h:171
itk::FixedArray< TRealType, VectorDimension >
itk::VectorGradientMagnitudeImageFilter::SetUseImageSpacingOff
void SetUseImageSpacingOff()
Definition: itkVectorGradientMagnitudeImageFilter.h:208
itk::VectorGradientMagnitudeImageFilter::ImageBaseType
typename InputImageType::Superclass ImageBaseType
Definition: itkVectorGradientMagnitudeImageFilter.h:294
itk::VectorGradientMagnitudeImageFilter::m_UseImageSpacing
bool m_UseImageSpacing
Definition: itkVectorGradientMagnitudeImageFilter.h:479
itk::ImageSource::OutputImageRegionType
typename OutputImageType::RegionType OutputImageRegionType
Definition: itkImageSource.h:92
itk::NumericTraits::ZeroValue
static T ZeroValue()
Definition: itkNumericTraits.h:148
itkConceptMacro
#define itkConceptMacro(name, concept)
Definition: itkConceptChecking.h:64
itk::VectorGradientMagnitudeImageFilter::OutputPixelType
typename TOutputImage::PixelType OutputPixelType
Definition: itkVectorGradientMagnitudeImageFilter.h:155
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkArray.h:26
itk::ConstNeighborhoodIterator
Const version of NeighborhoodIterator, defining iteration of a local N-dimensional neighborhood of pi...
Definition: itkConstNeighborhoodIterator.h:50
itk::VectorGradientMagnitudeImageFilter::m_RealValuedInputImage
RealVectorImageType::ConstPointer m_RealValuedInputImage
Definition: itkVectorGradientMagnitudeImageFilter.h:484
itk::ProcessObject
The base class for all process objects (source, filters, mappers) in the Insight data processing pipe...
Definition: itkProcessObject.h:135
itkVector.h
itk::VectorGradientMagnitudeImageFilter::m_ComponentWeights
WeightsType m_ComponentWeights
Definition: itkVectorGradientMagnitudeImageFilter.h:475
itk::ConstNeighborhoodIterator::GetNext
ITK_ITERATOR_VIRTUAL PixelType GetNext(const unsigned axis, NeighborIndexType i) const ITK_ITERATOR_FINAL
Definition: itkConstNeighborhoodIterator.h:242
itk::Image
Templated n-dimensional image class.
Definition: itkImage.h:86
itk::VectorGradientMagnitudeImageFilter::NonPCEvaluateAtNeighborhood
TRealType NonPCEvaluateAtNeighborhood(const ConstNeighborhoodIteratorType &it) const
Definition: itkVectorGradientMagnitudeImageFilter.h:300
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44
itkMath.h
itk::ImageSource::OutputImageType
TOutputImage OutputImageType
Definition: itkImageSource.h:90