Orfeo Toolbox  3.16
itkHessianToObjectnessMeasureImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkHessianToObjectnessMeasureImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2010-06-24 12:35:05 $
7  Version: $Revision: 1.6 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkHessianToObjectnessMeasureImageFilter_txx
18 #define __itkHessianToObjectnessMeasureImageFilter_txx
19 
21 #include "itkImageRegionIterator.h"
24 #include "itkProgressReporter.h"
25 
26 #include "vnl/vnl_math.h"
27 
28 namespace itk
29 {
30 
34 template < typename TInputImage, typename TOutputImage >
37 {
38  m_Alpha = 0.5;
39  m_Beta = 0.5;
40  m_Gamma = 5.0;
41 
42 
43  m_ScaleObjectnessMeasure = true;
44 
45  // by default extract bright lines (equivalent to vesselness)
46  m_ObjectDimension = 1;
47  m_BrightObject = true;
48 }
49 
50 
51 template < typename TInputImage, typename TOutputImage >
52 void
55 {
56  if (m_ObjectDimension >= ImageDimension)
57  {
58  itkExceptionMacro( "ObjectDimension must be lower than ImageDimension." );
59  }
60 
61 }
62 
63 template < typename TInputImage, typename TOutputImage >
64 void
66 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
67  int threadId)
68 {
69  typename OutputImageType::Pointer output = this->GetOutput();
70  typename InputImageType::ConstPointer input = this->GetInput();
71 
72  // support progress methods/callbacks
73  ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels(), 1000 / this->GetNumberOfThreads() );
74 
75  // calculator for computation of the eigen values
77  CalculatorType eigenCalculator( ImageDimension );
78 
79 
80  // walk the region of eigen values and get the objectness measure
81  ImageRegionConstIterator<InputImageType> it(input, outputRegionForThread);
82  ImageRegionIterator<OutputImageType> oit(output, outputRegionForThread );
83 
84  oit.GoToBegin();
85  it.GoToBegin();
86 
87  while (!it.IsAtEnd())
88  {
89  // compute eigen values
90  EigenValueArrayType eigenValues;
91  eigenCalculator.ComputeEigenValues( it.Get(), eigenValues );
92 
93  // Sort the eigenvalues by magnitude but retain their sign
94  EigenValueArrayType sortedEigenValues = eigenValues;
95  std::sort( sortedEigenValues.Begin(), sortedEigenValues.End(), AbsCompare() );
96 
97 
98  // check whether eigenvalues have the right sign
99  bool signConstraintsSatisfied = true;
100  for (unsigned int i=m_ObjectDimension; i<ImageDimension; i++)
101  {
102  if ((m_BrightObject && sortedEigenValues[i] > 0.0) ||
103  (!m_BrightObject && sortedEigenValues[i] < 0.0) )
104  {
105  signConstraintsSatisfied = false;
106  break;
107  }
108  }
109 
110  if (!signConstraintsSatisfied)
111  {
112  oit.Set(NumericTraits< OutputPixelType >::Zero);
113  ++it;
114  ++oit;
115  progress.CompletedPixel();
116  continue;
117  }
118 
119  EigenValueArrayType sortedAbsEigenValues;
120  for (unsigned int i=0; i<ImageDimension; i++)
121  {
122  sortedAbsEigenValues[i] = vnl_math_abs(sortedEigenValues[i]);
123  }
124 
125  // initialize the objectness measure
126  double objectnessMeasure = 1.0;
127 
128  // compute objectness from eigenvalue ratios and second-order structureness
129  if (m_ObjectDimension < ImageDimension-1)
130  {
131  double rA = sortedAbsEigenValues[m_ObjectDimension];
132  double rADenominatorBase = 1.0;
133  for (unsigned int j=m_ObjectDimension+1; j<ImageDimension; j++)
134  {
135  rADenominatorBase *= sortedAbsEigenValues[j];
136  }
137  if (vcl_fabs(rADenominatorBase) > 0.0)
138  {
139  if ( vcl_fabs( m_Alpha ) > 0.0 )
140  {
141  rA /= vcl_pow(rADenominatorBase, 1.0 / (ImageDimension-m_ObjectDimension-1));
142  objectnessMeasure *= 1.0 - vcl_exp(- 0.5 * vnl_math_sqr(rA) / vnl_math_sqr(m_Alpha));
143  }
144  }
145  else
146  {
147  objectnessMeasure = 0.0;
148  }
149  }
150 
151  if (m_ObjectDimension > 0)
152  {
153  double rB = sortedAbsEigenValues[m_ObjectDimension-1];
154  double rBDenominatorBase = 1.0;
155  for (unsigned int j=m_ObjectDimension; j<ImageDimension; j++)
156  {
157  rBDenominatorBase *= sortedAbsEigenValues[j];
158  }
159  if (vcl_fabs(rBDenominatorBase) > 0.0 && vcl_fabs( m_Beta ) > 0.0 )
160  {
161  rB /= vcl_pow(rBDenominatorBase, 1.0 / (ImageDimension-m_ObjectDimension));
162 
163  objectnessMeasure *= vcl_exp(- 0.5 * vnl_math_sqr(rB) / vnl_math_sqr(m_Beta));
164 
165  }
166  else
167  {
168  objectnessMeasure = 0.0;
169  }
170  }
171 
172  if ( vcl_fabs( m_Gamma ) > 0.0 )
173  {
174  double frobeniusNormSquared = 0.0;
175  for (unsigned int i=0; i<ImageDimension; i++)
176  {
177  frobeniusNormSquared += vnl_math_sqr(sortedAbsEigenValues[i]);
178  }
179  objectnessMeasure *= 1.0 - vcl_exp(- 0.5 * frobeniusNormSquared / vnl_math_sqr(m_Gamma));
180  }
181 
182  // in case, scale by largest absolute eigenvalue
183  if (m_ScaleObjectnessMeasure)
184  {
185  objectnessMeasure *= sortedAbsEigenValues[ImageDimension-1];
186  }
187 
188 
189  oit.Set( static_cast< OutputPixelType >(objectnessMeasure));
190 
191 
192  ++it;
193  ++oit;
194  progress.CompletedPixel();
195  }
196 }
197 
198 template < typename TInputImage, typename TOutputImage >
199 void
201 ::PrintSelf(std::ostream& os, Indent indent) const
202 {
203  Superclass::PrintSelf(os, indent);
204 
205  os << indent << "Alpha: " << m_Alpha << std::endl;
206  os << indent << "Beta: " << m_Beta << std::endl;
207  os << indent << "Gamma: " << m_Gamma << std::endl;
208  os << indent << "ScaleObjectnessMeasure: " << m_ScaleObjectnessMeasure << std::endl;
209  os << indent << "ObjectDimension: " << m_ObjectDimension << std::endl;
210  os << indent << "BrightObject: " << m_BrightObject << std::endl;
211 }
212 
213 } // end namespace itk
214 
215 #endif

Generated at Sat Feb 2 2013 23:41:24 for Orfeo Toolbox with doxygen 1.8.1.1