Orfeo Toolbox  3.16
itkScalarImageTextureCalculator.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkScalarImageTextureCalculator.txx,v $
5  Language: C++
6  Date: $Date: 2009-03-04 19:29:54 $
7  Version: $Revision: 1.11 $
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 __itkScalarImageTextureCalculator_txx
18 #define __itkScalarImageTextureCalculator_txx
19 
21 #include "itkNeighborhood.h"
22 #include "vnl/vnl_math.h"
23 
24 namespace itk {
25 namespace Statistics {
26 
27 template< class TImage, class THistogramFrequencyContainer >
30 {
31  m_GLCMGenerator = GLCMGeneratorType::New();
32  m_FeatureMeans = FeatureValueVector::New();
33  m_FeatureStandardDeviations = FeatureValueVector::New();
34 
35  // Set the requested features to the default value:
36  // {Energy, Entropy, InverseDifferenceMoment, Inertia, ClusterShade, ClusterProminence}
37  FeatureNameVectorPointer requestedFeatures = FeatureNameVector::New();
38  // can't directly set m_RequestedFeatures since it is const!
39  requestedFeatures->push_back(Energy);
40  requestedFeatures->push_back(Entropy);
41  requestedFeatures->push_back(InverseDifferenceMoment);
42  requestedFeatures->push_back(Inertia);
43  requestedFeatures->push_back(ClusterShade);
44  requestedFeatures->push_back(ClusterProminence);
45  this->SetRequestedFeatures(requestedFeatures);
46 
47  // Set the offset directions to their defaults: half of all the possible
48  // directions 1 pixel away. (The other half is included by symmetry.)
49  // We use a neighborhood iterator to calculate the appropriate offsets.
50  typedef Neighborhood<ITK_TYPENAME ImageType::PixelType, ::itk::GetImageDimension<
51  ImageType >::ImageDimension > NeighborhoodType;
52  NeighborhoodType hood;
53  hood.SetRadius(1);
54 
55  // select all "previous" neighbors that are face+edge+vertex
56  // connected to the current pixel. do not include the center pixel.
57  unsigned int centerIndex = hood.GetCenterNeighborhoodIndex();
58  OffsetType offset;
59  OffsetVectorPointer offsets = OffsetVector::New();
60  for (unsigned int d=0; d < centerIndex; d++)
61  {
62  offset = hood.GetOffset(d);
63  offsets->push_back(offset);
64  }
65  this->SetOffsets(offsets);
66  m_FastCalculations = false;
67 }
68 
69 template< class TImage, class THistogramFrequencyContainer >
70 void
72 Compute(void)
73 {
74  if (m_FastCalculations)
75  {
76  this->FastCompute();
77  }
78  else
79  {
80  this->FullCompute();
81  }
82 }
83 
84 template< class TImage, class THistogramFrequencyContainer >
85 void
88 {
89  int numOffsets = m_Offsets->size();
90  int numFeatures = m_RequestedFeatures->size();
91  double **features;
92 
93  features = new double *[numOffsets];
94  for (int i = 0; i < numOffsets; i++)
95  {
96  features[i] = new double [numFeatures];
97  }
98 
99  // For each offset, calculate each feature
100  typename OffsetVector::ConstIterator offsetIt;
101  int offsetNum, featureNum;
102 
103  for(offsetIt = m_Offsets->Begin(), offsetNum = 0;
104  offsetIt != m_Offsets->End(); offsetIt++, offsetNum++)
105  {
106  m_GLCMGenerator->SetOffset(offsetIt.Value());
107  m_GLCMGenerator->Compute();
108  typename GLCMCalculatorType::Pointer glcmCalc = GLCMCalculatorType::New();
109  glcmCalc->SetHistogram(m_GLCMGenerator->GetOutput());
110  glcmCalc->Compute();
111 
112  typename FeatureNameVector::ConstIterator fnameIt;
113  for(fnameIt = m_RequestedFeatures->Begin(), featureNum = 0;
114  fnameIt != m_RequestedFeatures->End(); fnameIt++, featureNum++)
115  {
116  features[offsetNum][featureNum] = glcmCalc->GetFeature(fnameIt.Value());
117  }
118  }
119 
120  // Now get the mean and deviaton of each feature across the offsets.
121  m_FeatureMeans->clear();
122  m_FeatureStandardDeviations->clear();
123  double *tempFeatureMeans = new double [numFeatures];
124  double *tempFeatureDevs = new double [numFeatures];
125 
126  /*Compute incremental mean and SD, a la Knuth, "The Art of Computer
127  Programming, Volume 2: Seminumerical Algorithms", section 4.2.2.
128  Compute mean and standard deviation using the recurrence relation:
129  M(1) = x(1), M(k) = M(k-1) + (x(k) - M(k-1) ) / k
130  S(1) = 0, S(k) = S(k-1) + (x(k) - M(k-1)) * (x(k) - M(k))
131  for 2 <= k <= n, then
132  sigma = vcl_sqrt(S(n) / n) (or divide by n-1 for sample SD instead of
133  population SD).
134  */
135 
136  // Set up the initial conditions (k = 1)
137  for (featureNum = 0; featureNum < numFeatures; featureNum++)
138  {
139  tempFeatureMeans[featureNum] = features[0][featureNum];
140  tempFeatureDevs[featureNum] = 0;
141  }
142  // Run through the recurrence (k = 2 ... N)
143  for (offsetNum = 1; offsetNum < numOffsets; offsetNum++)
144  {
145  int k = offsetNum + 1;
146  for (featureNum = 0; featureNum < numFeatures; featureNum++)
147  {
148  double M_k_minus_1 = tempFeatureMeans[featureNum];
149  double S_k_minus_1 = tempFeatureDevs[featureNum];
150  double x_k = features[offsetNum][featureNum];
151 
152  double M_k = M_k_minus_1 + (x_k - M_k_minus_1) / k;
153  double S_k = S_k_minus_1 + (x_k - M_k_minus_1) * (x_k - M_k);
154 
155  tempFeatureMeans[featureNum] = M_k;
156  tempFeatureDevs[featureNum] = S_k;
157  }
158  }
159  for (featureNum = 0; featureNum < numFeatures; featureNum++)
160  {
161  tempFeatureDevs[featureNum] = vcl_sqrt(tempFeatureDevs[featureNum] / numOffsets);
162 
163  m_FeatureMeans->push_back(tempFeatureMeans[featureNum]);
164  m_FeatureStandardDeviations->push_back(tempFeatureDevs[featureNum]);
165  }
166  delete [] tempFeatureMeans;
167  delete [] tempFeatureDevs;
168  for(int i=0; i < numOffsets; i++)
169  {
170  delete [] features[i];
171  }
172  delete[] features;
173 }
174 
175 template< class TImage, class THistogramFrequencyContainer >
176 void
179 {
180  // For each offset, calculate each feature
181  typename OffsetVector::ConstIterator offsetIt;
182  for(offsetIt = m_Offsets->Begin(); offsetIt != m_Offsets->End(); offsetIt++)
183  {
184  m_GLCMGenerator->SetOffset(offsetIt.Value());
185  }
186 
187  m_GLCMGenerator->Compute();
188  typename GLCMCalculatorType::Pointer glcmCalc = GLCMCalculatorType::New();
189  glcmCalc->SetHistogram(m_GLCMGenerator->GetOutput());
190  glcmCalc->Compute();
191 
192  m_FeatureMeans->clear();
193  m_FeatureStandardDeviations->clear();
194  typename FeatureNameVector::ConstIterator fnameIt;
195  for(fnameIt = m_RequestedFeatures->Begin();
196  fnameIt != m_RequestedFeatures->End(); fnameIt++)
197  {
198  m_FeatureMeans->push_back(glcmCalc->GetFeature(fnameIt.Value()));
199  m_FeatureStandardDeviations->push_back(0.0);
200  }
201 }
202 
203 
204 template< class TImage, class THistogramFrequencyContainer >
205 void
207 SetInput( const ImageType * inputImage )
208 {
209  itkDebugMacro("setting Input to " << inputImage);
210  m_GLCMGenerator->SetInput(inputImage);
211  this->Modified();
212 }
213 
214 template< class TImage, class THistogramFrequencyContainer >
215 void
217 SetNumberOfBinsPerAxis( unsigned int numberOfBins )
218 {
219  itkDebugMacro("setting NumberOfBinsPerAxis to " << numberOfBins);
220  m_GLCMGenerator->SetNumberOfBinsPerAxis(numberOfBins);
221  this->Modified();
222 }
223 
224 template< class TImage, class THistogramFrequencyContainer >
225 void
228 {
229  itkDebugMacro("setting Min to " << min << "and Max to " << max);
230  m_GLCMGenerator->SetPixelValueMinMax(min, max);
231  this->Modified();
232 }
233 
234 template< class TImage, class THistogramFrequencyContainer >
235 void
237 SetImageMask( const ImageType* imageMask)
238 {
239  itkDebugMacro("setting ImageMask to " << imageMask);
240  m_GLCMGenerator->SetImageMask(imageMask);
241  this->Modified();
242 }
243 
244 template< class TImage, class THistogramFrequencyContainer >
245 void
248 {
249  itkDebugMacro("setting InsidePixelValue to " << insidePixelValue);
250  m_GLCMGenerator->SetInsidePixelValue(insidePixelValue);
251  this->Modified();
252 }
253 
254 template< class TImage, class THistogramFrequencyContainer >
255 void
257 PrintSelf(std::ostream& os, Indent indent) const
258 {
259  Superclass::PrintSelf(os,indent);
260 }
261 
262 } // end of namespace Statistics
263 
264 } // end of namespace itk
265 
266 
267 #endif

Generated at Sun Feb 3 2013 00:04:43 for Orfeo Toolbox with doxygen 1.8.1.1