ITK  4.5.0
Insight Segmentation and Registration 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 "vnl/vnl_math.h"
29 
30 namespace itk
31 {
134 template< typename TInputImage,
135  typename TRealType = float,
136  typename TOutputImage = Image< TRealType,
137  TInputImage::ImageDimension >
138  >
140  public ImageToImageFilter< TInputImage, TOutputImage >
141 {
142 public:
148 
150  itkNewMacro(Self);
151 
154 
157  typedef typename TOutputImage::PixelType OutputPixelType;
158  typedef typename TInputImage::PixelType InputPixelType;
159 
161  typedef TInputImage InputImageType;
162  typedef TOutputImage OutputImageType;
163  typedef typename InputImageType::Pointer InputImagePointer;
164  typedef typename OutputImageType::Pointer OutputImagePointer;
165 
167  itkStaticConstMacro(ImageDimension, unsigned int,
168  TOutputImage::ImageDimension);
169 
171  itkStaticConstMacro(VectorDimension, unsigned int,
172  InputPixelType::Dimension);
173 
175  typedef TRealType RealType;
180 
185 
188 
197  virtual void GenerateInputRequestedRegion()
199 
205  { this->SetUseImageSpacing(true); }
206 
211  { this->SetUseImageSpacing(false); }
212 
215  void SetUseImageSpacing(bool);
216 
217  itkGetConstMacro(UseImageSpacing, bool);
218 
220 
223  itkSetMacro(DerivativeWeights, WeightsType);
224  itkGetConstReferenceMacro(DerivativeWeights, WeightsType);
226 
229  itkSetMacro(ComponentWeights, WeightsType);
230  itkGetConstReferenceMacro(ComponentWeights, WeightsType);
232 
234  itkGetConstReferenceMacro(NeighborhoodRadius, RadiusType);
235  itkSetMacro(NeighborhoodRadius, RadiusType);
237 
243  itkSetMacro(UsePrincipleComponents, bool);
244  itkGetConstMacro(UsePrincipleComponents, bool);
246  {
247  this->SetUsePrincipleComponents(true);
248  }
250 
252  {
253  this->SetUsePrincipleComponents(false);
254  }
255 
258  static int CubicSolver(double *, double *);
259 
260 #ifdef ITK_USE_CONCEPT_CHECKING
261  // Begin concept checking
262  itkConceptMacro( InputHasNumericTraitsCheck,
264  itkConceptMacro( RealTypeHasNumericTraitsCheck,
266  // End concept checking
267 #endif
268 
269 protected:
272 
277 
289  void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,
290  ThreadIdType threadId);
291 
292  void PrintSelf(std::ostream & os, Indent indent) const;
293 
294  typedef typename InputImageType::Superclass ImageBaseType;
295 
297  itkGetConstObjectMacro(RealValuedInputImage, ImageBaseType);
298 
300  {
301  unsigned i, j;
302  TRealType dx, sum, accum;
303 
305  for ( i = 0; i < ImageDimension; ++i )
306  {
308  for ( j = 0; j < VectorDimension; ++j )
309  {
311  * 0.5 * ( it.GetNext(i)[j] - it.GetPrevious(i)[j] );
312  sum += dx * dx;
313  }
314  accum += sum;
315  }
316  return vcl_sqrt(accum);
317  }
318 
320  {
321  // WARNING: ONLY CALL THIS METHOD WHEN PROCESSING A 3D IMAGE
322  unsigned int i, j;
323  double Lambda[3];
324  double CharEqn[3];
325  double ans;
326 
327  vnl_matrix< TRealType > g(ImageDimension, ImageDimension);
328  vnl_vector_fixed< TRealType, VectorDimension >
329  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] = m_DerivativeWeights[i] * m_SqrtComponentWeights[j]
338  * 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] )
360  + g[1][0] * ( g[2][2] * g[0][1] - g[0][2] * g[2][1] )
361  + g[2][0] * ( g[1][1] * g[0][2] - g[0][1] * g[1][2] );
362 
363  // Find the eigenvalues of g
364  int numberOfDistinctRoots = this->CubicSolver(CharEqn, Lambda);
365 
366  // Define gradient magnitude as the difference between two largest
367  // eigenvalues. Other definitions may be appropriate here as well.
368  if ( numberOfDistinctRoots == 3 ) // By far the most common case
369  {
370  if ( Lambda[0] > Lambda[1] )
371  {
372  if ( Lambda[1] > Lambda[2] ) // Most common, guaranteed?
373  {
374  ans = Lambda[0] - Lambda[1];
375  }
376  else
377  {
378  if ( Lambda[0] > Lambda[2] )
379  {
380  ans = Lambda[0] - Lambda[2];
381  }
382  else
383  {
384  ans = Lambda[2] - Lambda[0];
385  }
386  }
387  }
388  else
389  {
390  if ( Lambda[0] > Lambda[2] )
391  {
392  ans = Lambda[1] - Lambda[0];
393  }
394  else
395  {
396  if ( Lambda[1] > Lambda[2] )
397  {
398  ans = Lambda[1] - Lambda[2];
399  }
400  else
401  {
402  ans = Lambda[2] - Lambda[1];
403  }
404  }
405  }
406  }
407  else if ( numberOfDistinctRoots == 2 )
408  {
409  if ( Lambda[0] > Lambda[1] )
410  {
411  ans = Lambda[0] - Lambda[1];
412  }
413  else
414  {
415  ans = Lambda[1] - Lambda[0];
416  }
417  }
418  else if ( numberOfDistinctRoots == 1 )
419  {
420  ans = 0.0;
421  }
422  else
423  {
424  itkExceptionMacro(<< "Undefined condition. Cubic root solver returned "
425  << numberOfDistinctRoots << " distinct roots.");
426  }
427 
428  return ans;
429  }
430 
431  // Function is defined here because the templating confuses gcc 2.96 when
432  // defined
433  // in .hxx file. jc 1/29/03
435  {
436  unsigned int i, j;
437 
438  vnl_matrix< TRealType > g(ImageDimension, ImageDimension);
439  vnl_vector_fixed< TRealType, VectorDimension >
440  d_phi_du[TInputImage::ImageDimension];
441 
442  // Calculate the directional derivatives for each vector component using
443  // central differences.
444  for ( i = 0; i < ImageDimension; i++ )
445  {
446  for ( j = 0; j < VectorDimension; j++ )
447  {
448  d_phi_du[i][j] = m_DerivativeWeights[i] * m_SqrtComponentWeights[j]
449  * 0.5 * ( it.GetNext(i)[j] - it.GetPrevious(i)[j] );
450  }
451  }
452 
453  // Calculate the symmetric metric tensor g
454  for ( i = 0; i < ImageDimension; i++ )
455  {
456  for ( j = i; j < ImageDimension; j++ )
457  {
458  g[j][i] = g[i][j] = dot_product(d_phi_du[i], d_phi_du[j]);
459  }
460  }
461 
462  // Find the eigenvalues of g
463  vnl_symmetric_eigensystem< TRealType > E(g);
464 
465  // Return the difference in length between the first two principle axes.
466  // Note that other edge strength metrics may be appropriate here instead..
467  return ( E.get_eigenvalue(ImageDimension - 1) - E.get_eigenvalue(ImageDimension - 2) );
468  }
469 
472 
478 
479 private:
482 
484 
485  typename ImageBaseType::ConstPointer m_RealValuedInputImage;
486 
487  VectorGradientMagnitudeImageFilter(const Self &); //purposely not implemented
488  void operator=(const Self &); //purposely not implemented
489 
491 };
492 } // end namespace itk
493 
494 #ifndef ITK_MANUAL_INSTANTIATION
495 #include "itkVectorGradientMagnitudeImageFilter.hxx"
496 #endif
497 
498 #endif
ConstNeighborhoodIterator< RealVectorImageType > ConstNeighborhoodIteratorType
FixedArray< TRealType, VectorDimension > WeightsType
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, ThreadIdType threadId)
TRealType EvaluateAtNeighborhood3D(const ConstNeighborhoodIteratorType &it) const
virtual void SetUsePrincipleComponents(bool _arg)
ImageToImageFilter< TInputImage, TOutputImage > Superclass
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
A templated class holding a n-Dimensional vector.
Definition: itkVector.h:62
static int CubicSolver(double *, double *)
Vector< TRealType, InputPixelType::Dimension > RealVectorType
TRealType NonPCEvaluateAtNeighborhood(const ConstNeighborhoodIteratorType &it) const
Base class for filters that take an image as input and produce an image as output.
Control indentation during Print() invocation.
Definition: itkIndent.h:49
Superclass::OutputImageRegionType OutputImageRegionType
Define additional traits for native types such as int or float.
#define itkConceptMacro(name, concept)
Image< RealVectorType, TInputImage::ImageDimension > RealVectorImageType
Templated n-dimensional image class.
Definition: itkImage.h:75
TRealType EvaluateAtNeighborhood(const ConstNeighborhoodIteratorType &it) const
unsigned int ThreadIdType
Definition: itkIntTypes.h:159
void PrintSelf(std::ostream &os, Indent indent) const