Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkGIFFirstOrderHistogramStatistics.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 
15 // MITK
16 #include <mitkITKImageImport.h>
17 #include <mitkImageCast.h>
18 #include <mitkImageAccessByItk.h>
19 
20 // ITK
21 #include <itkLabelStatisticsImageFilter.h>
22 #include <itkMinimumMaximumImageCalculator.h>
23 #include <itkImageRegionConstIteratorWithIndex.h>
24 
25 // STL
26 #include <sstream>
27 #include <limits>
28 #include <math.h>
29 
30 #define GET_VARIABLE_INDEX(value) \
31  mv[0] = value; \
32  histogram->GetIndex(mv, resultingIndex);
33 
34 
35 template<typename TPixel, unsigned int VImageDimension>
36 void
38 {
39  typedef itk::Image<TPixel, VImageDimension> ImageType;
40  typedef itk::Image<unsigned short, VImageDimension> MaskType;
41  typedef itk::LabelStatisticsImageFilter<ImageType, MaskType> FilterType;
42  typedef typename FilterType::HistogramType HistogramType;
43  typedef typename HistogramType::IndexType HIndexType;
44 
45  typename MaskType::Pointer maskImage = MaskType::New();
46  mitk::CastToItkImage(mask, maskImage);
47 
48  typename FilterType::Pointer labelStatisticsImageFilter = FilterType::New();
49  labelStatisticsImageFilter->SetInput(itkImage);
50  labelStatisticsImageFilter->SetLabelInput(maskImage);
51  labelStatisticsImageFilter->SetUseHistograms(true);
52  labelStatisticsImageFilter->SetHistogramParameters(params.Bins, params.MinimumIntensity, params.MaximumIntensity);
53 
54  labelStatisticsImageFilter->Update();
55 
56  typename HistogramType::MeasurementVectorType mv(1);
57  mv[0] = 4.1;
58  typename HistogramType::IndexType resultingIndex;
59 
60  auto histogram = labelStatisticsImageFilter->GetHistogram(1);
61  double meanValue = 0; // labelStatisticsImageFilter->GetMean(1);
62  GET_VARIABLE_INDEX(meanValue);
63  double meanIndex = 0; // resultingIndex[0];
64  double medianValue = labelStatisticsImageFilter->GetMedian(1);
65  GET_VARIABLE_INDEX(medianValue);
66  double medianIndex = resultingIndex[0];
67  double minimumValue = labelStatisticsImageFilter->GetMinimum(1);
68  GET_VARIABLE_INDEX(minimumValue);
69  double minimumIndex = resultingIndex[0];
70  double p10Value = histogram->Quantile(0, 0.10);
71  GET_VARIABLE_INDEX(p10Value);
72  double p10Index = resultingIndex[0];
73  double p25Value = histogram->Quantile(0, 0.25);
74  GET_VARIABLE_INDEX(p25Value);
75  double p25Index = resultingIndex[0];
76  double p75Value = histogram->Quantile(0, 0.75);
77  GET_VARIABLE_INDEX(p75Value);
78  double p75Index = resultingIndex[0];
79  double p90Value = histogram->Quantile(0, 0.90);
80  GET_VARIABLE_INDEX(p90Value);
81  double p90Index = resultingIndex[0];
82  double maximumValue = labelStatisticsImageFilter->GetMaximum(1);
83  GET_VARIABLE_INDEX(maximumValue);
84  double maximumIndex = resultingIndex[0];
85 
86  double Log2 = log(2);
87  HIndexType index;
88  HIndexType index2;
89  index.SetSize(1);
90  index2.SetSize(1);
91  double binWidth = histogram->GetBinMax(0, 0) - histogram->GetBinMin(0, 0);
92  double count = labelStatisticsImageFilter->GetCount(1);
93 
94  double robustMeanValue = 0;
95  double robustMeanIndex = 0;
96  double robustCount = 0;
97 
98  for (int i = 0; i < (int)(histogram->GetSize(0)); ++i)
99  {
100  index[0] = i;
101  double frequence = histogram->GetFrequency(index);
102  double probability = frequence / count;
103  double voxelValue = histogram->GetBinMin(0, i) + binWidth * 0.5;
104 
105  meanValue += probability * voxelValue;
106  meanIndex += probability * (i);
107 
108  if ((i >= p10Index) && (i <= p90Index))
109  {
110  robustMeanValue += frequence * voxelValue;
111  robustMeanIndex += frequence * i;
112  robustCount += frequence;
113  }
114  }
115  robustMeanValue /= robustCount;
116  robustMeanIndex /= robustCount;
117 
118  double varianceValue = 0;
119  double varianceIndex = 0;
120  double skewnessValue = 0;
121  double skewnessIndex = 0;
122  double kurtosisValue = 0;
123  double kurtosisIndex = 0;
124  double modeValue = 0;
125  double modeIndex = 0;
126  double modeFrequence = 0;
127  double meanAbsoluteDeviationValue = 0;
128  double meanAbsoluteDeviationIndex = 0;
129  double robustMeanAbsoluteDeviationValue = 0;
130  double robustMeanAbsoluteDeivationIndex = 0;
131  double medianAbsoluteDeviationValue = 0;
132  double medianAbsoluteDeviationIndex = 0;
133  double coefficientOfVariationValue = 0;
134  double coefficientOfVariationIndex = 0;
135  double quantileCoefficientOfDispersionValue = 0;
136  double quantileCoefficientOfDispersionIndex = 0;
137  double entropyValue = 0;
138  double entropyIndex = 0;
139  double uniformityValue = 0;
140  double uniformityIndex = 0;
141 
142  double maximumGradientValue = std::numeric_limits<double>::min();
143  double maximumGradientIndex = 0;
144  double minimumGradientValue = std::numeric_limits<double>::max();
145  double minimumGradientIndex = 0;
146 
147  double gradient = 0;
148 
149  for (int i = 0; i < (int)(histogram->GetSize(0)); ++i)
150  {
151  index[0] = i;
152  double frequence = histogram->GetFrequency(index);
153  double probability = frequence / count;
154  double voxelValue = histogram->GetBinMin(0, i) + binWidth * 0.5;
155 
156  double deltaValue = (voxelValue - meanValue);
157  double deltaIndex = (i - meanIndex);
158 
159  varianceValue += probability * deltaValue * deltaValue;
160  varianceIndex += probability * deltaIndex * deltaIndex;
161  skewnessValue += probability * deltaValue * deltaValue * deltaValue;
162  skewnessIndex += probability * deltaIndex * deltaIndex * deltaIndex;
163  kurtosisValue += probability * deltaValue * deltaValue * deltaValue * deltaValue;
164  kurtosisIndex += probability * deltaIndex * deltaIndex * deltaIndex * deltaIndex;
165 
166  if (modeFrequence < frequence)
167  {
168  modeFrequence = frequence;
169  modeValue = voxelValue;
170  modeIndex = i;
171  }
172  meanAbsoluteDeviationValue += probability * std::abs(deltaValue);
173  meanAbsoluteDeviationIndex += probability * std::abs(deltaIndex);
174  if ((i >= p10Index) && (i <= p90Index))
175  {
176  robustMeanAbsoluteDeviationValue += frequence * std::abs<double>(voxelValue - robustMeanValue);
177  robustMeanAbsoluteDeivationIndex += frequence * std::abs<double>(i*1.0 - robustMeanIndex*1.0);
178  }
179  medianAbsoluteDeviationValue += probability * std::abs(voxelValue - medianValue);
180  medianAbsoluteDeviationIndex += probability * std::abs(i*1.0 - medianIndex);
181  if (probability > 0.0000001)
182  {
183  entropyValue -= probability * std::log(probability) / Log2;
184  entropyIndex = entropyValue;
185  }
186  uniformityValue += probability*probability;
187  uniformityIndex = uniformityValue;
188  if (i == 0)
189  {
190  index[0] = 1; index2[0] = 0;
191  gradient = histogram->GetFrequency(index)*1.0 - histogram->GetFrequency(index2)*1.0;
192  }
193  else if (i == (int)(histogram->GetSize(0)) - 1)
194  {
195  index[0] = i; index2[0] = i - 1;
196  gradient = histogram->GetFrequency(index)*1.0 - histogram->GetFrequency(index2)*1.0;
197  }
198  else
199  {
200  index[0] = i+1; index2[0] = i - 1;
201  gradient = (histogram->GetFrequency(index)*1.0 - histogram->GetFrequency(index2)*1.0) / 2.0;
202  }
203  if (gradient > maximumGradientValue)
204  {
205  maximumGradientValue = gradient;
206  maximumGradientIndex = i + 1;
207  }
208  if (gradient < minimumGradientValue)
209  {
210  minimumGradientValue = gradient;
211  minimumGradientIndex = i + 1;
212  }
213  }
214  skewnessValue = skewnessValue / (varianceValue * std::sqrt(varianceValue));
215  skewnessIndex = skewnessIndex / (varianceIndex * std::sqrt(varianceIndex));
216  kurtosisValue = kurtosisValue / (varianceValue * varianceValue) - 3; // Excess Kurtosis
217  kurtosisIndex = kurtosisIndex / (varianceIndex * varianceIndex) - 3; // Excess Kurtosis
218  coefficientOfVariationValue = std::sqrt(varianceValue) / meanValue;
219  coefficientOfVariationIndex = std::sqrt(varianceIndex) / (meanIndex+1);
220  quantileCoefficientOfDispersionValue = (p75Value - p25Value) / (p75Value + p25Value);
221  quantileCoefficientOfDispersionIndex = (p75Index - p25Index) / (p75Index + 1.0 + p25Index + 1.0);
222  robustMeanAbsoluteDeviationValue /= robustCount;
223  robustMeanAbsoluteDeivationIndex /= robustCount;
224 
225  featureList.push_back(std::make_pair(params.prefix + "Mean Value", meanValue));
226  featureList.push_back(std::make_pair(params.prefix + "Variance Value", varianceValue));
227  featureList.push_back(std::make_pair(params.prefix + "Skewness Value", skewnessValue));
228  featureList.push_back(std::make_pair(params.prefix + "Excess Kurtosis Value", kurtosisValue));
229  featureList.push_back(std::make_pair(params.prefix + "Median Value", medianValue));
230  featureList.push_back(std::make_pair(params.prefix + "Minimum Value", minimumValue));
231  featureList.push_back(std::make_pair(params.prefix + "Percentile 10 Value", p10Value));
232  featureList.push_back(std::make_pair(params.prefix + "Percentile 90 Value", p90Value));
233  featureList.push_back(std::make_pair(params.prefix + "Maximum Value", maximumValue));
234  featureList.push_back(std::make_pair(params.prefix + "Mode Value", modeValue));
235  featureList.push_back(std::make_pair(params.prefix + "Interquantile Range Value", p75Value - p25Value));
236  featureList.push_back(std::make_pair(params.prefix + "Range Value", maximumValue - minimumValue));
237  featureList.push_back(std::make_pair(params.prefix + "Mean Absolute Deviation Value", meanAbsoluteDeviationValue));
238  featureList.push_back(std::make_pair(params.prefix + "Robust Mean Absolute Deviation Value", robustMeanAbsoluteDeviationValue));
239  featureList.push_back(std::make_pair(params.prefix + "Median Absolute Deviation Value", medianAbsoluteDeviationValue));
240  featureList.push_back(std::make_pair(params.prefix + "Coefficient of Variation Value", coefficientOfVariationValue));
241  featureList.push_back(std::make_pair(params.prefix + "Quantile coefficient of Dispersion Value", quantileCoefficientOfDispersionValue));
242  featureList.push_back(std::make_pair(params.prefix + "Entropy Value", entropyValue));
243  featureList.push_back(std::make_pair(params.prefix + "Uniformity Value", uniformityValue));
244  featureList.push_back(std::make_pair(params.prefix + "Robust Mean Value", robustMeanValue));
245 
246  featureList.push_back(std::make_pair(params.prefix + "Mean Index", meanIndex + 1 ));
247  featureList.push_back(std::make_pair(params.prefix + "Variance Index", varianceIndex));
248  featureList.push_back(std::make_pair(params.prefix + "Skewness Index", skewnessIndex));
249  featureList.push_back(std::make_pair(params.prefix + "Excess Kurtosis Index", kurtosisIndex));
250  featureList.push_back(std::make_pair(params.prefix + "Median Index", medianIndex + 1));
251  featureList.push_back(std::make_pair(params.prefix + "Minimum Index", minimumIndex + 1));
252  featureList.push_back(std::make_pair(params.prefix + "Percentile 10 Index", p10Index + 1));
253  featureList.push_back(std::make_pair(params.prefix + "Percentile 90 Index", p90Index + 1));
254  featureList.push_back(std::make_pair(params.prefix + "Maximum Index", maximumIndex + 1));
255  featureList.push_back(std::make_pair(params.prefix + "Mode Index", modeIndex + 1));
256  featureList.push_back(std::make_pair(params.prefix + "Interquantile Range Index", p75Index - p25Index));
257  featureList.push_back(std::make_pair(params.prefix + "Range Index", maximumIndex - minimumIndex));
258  featureList.push_back(std::make_pair(params.prefix + "Mean Absolute Deviation Index", meanAbsoluteDeviationIndex));
259  featureList.push_back(std::make_pair(params.prefix + "Robust Mean Absolute Deviation Index", robustMeanAbsoluteDeivationIndex));
260  featureList.push_back(std::make_pair(params.prefix + "Median Absolute Deviation Index", medianAbsoluteDeviationIndex));
261  featureList.push_back(std::make_pair(params.prefix + "Coefficient of Variation Index", coefficientOfVariationIndex));
262  featureList.push_back(std::make_pair(params.prefix + "Quantile coefficient of Dispersion Index", quantileCoefficientOfDispersionIndex));
263  featureList.push_back(std::make_pair(params.prefix + "Entropy Index", entropyIndex));
264  featureList.push_back(std::make_pair(params.prefix + "Uniformity Index", uniformityIndex));
265  featureList.push_back(std::make_pair(params.prefix + "Maximum Gradient", maximumGradientValue));
266  featureList.push_back(std::make_pair(params.prefix + "Maximum Gradient Index", maximumGradientIndex));
267  featureList.push_back(std::make_pair(params.prefix + "Minimum Gradient", minimumGradientValue));
268  featureList.push_back(std::make_pair(params.prefix + "Minimum Gradient Index", minimumGradientIndex));
269  featureList.push_back(std::make_pair(params.prefix + "Robust Mean Index", robustMeanIndex));
270 
271  featureList.push_back(std::make_pair(params.prefix + "Number of Bins", histogram->GetSize(0)));
272  featureList.push_back(std::make_pair(params.prefix + "Bin Size", binWidth));
273 }
274 
276 {
277  SetShortName("foh");
278  SetLongName("first-order-histogram");
279  SetFeatureClassName("First Order Histogram");
280 }
281 
283 {
284  InitializeQuantifier(image, mask);
285  FeatureListType featureList;
286 
287  ParameterStruct params;
288  params.MinimumIntensity = GetQuantifier()->GetMinimum();
289  params.MaximumIntensity = GetQuantifier()->GetMaximum();
290  params.Bins = GetQuantifier()->GetBins();
291  params.prefix = FeatureDescriptionPrefix();
292 
293  AccessByItk_3(image, CalculateFirstOrderHistogramStatistics, mask, featureList, params);
294 
295  return featureList;
296 }
297 
299 {
300  FeatureNameListType featureList;
301  return featureList;
302 }
303 
304 
306 {
307  AddQuantifierArguments(parser);
308  std::string name = GetOptionPrefix();
309 
310  parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Histogram based First order features", "calculates first order features based on a histogram", us::Any());
311 }
312 
313 void
315 {
316  std::string name = GetOptionPrefix();
317  auto parsedArgs = GetParameter();
318  if (parsedArgs.count(GetLongName()))
319  {
320  InitializeQuantifierFromParameters(feature, mask);
321 
322  MITK_INFO << "Start calculating first order histogram features ....";
323  auto localResults = this->CalculateFeatures(feature, maskNoNAN);
324  featureList.insert(featureList.end(), localResults.begin(), localResults.end());
325  MITK_INFO << "Finished calculating first order histogram features....";
326  }
327 }
329 {
330  return QuantifierParameterString();
331 }
332 
FeatureListType CalculateFeatures(const Image::Pointer &image, const Image::Pointer &feature) override
Calculates the Cooccurence-Matrix based features for this class.
#define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3)
#define MITK_INFO
Definition: mitkLogMacros.h:18
itk::Image< unsigned char, 3 > ImageType
virtual void SetLongName(std::string _arg)
void CalculateFeaturesUsingParameters(const Image::Pointer &feature, const Image::Pointer &mask, const Image::Pointer &maskNoNAN, FeatureListType &featureList) override
Calculates the feature of this abstact interface. Does not necessarily considers the parameter settin...
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false, mitkCommandLineParser::Channel channel=mitkCommandLineParser::Channel::None)
virtual void SetShortName(std::string _arg)
std::vector< std::pair< std::string, double > > FeatureListType
std::string FeatureDescriptionPrefix()
Returns a string that encodes the feature class name.
void AddArguments(mitkCommandLineParser &parser) override
virtual std::string GetLongName() const
#define GET_VARIABLE_INDEX(value)
Definition: usAny.h:163
FeatureNameListType GetFeatureNames() override
Returns a list of the names of all features that are calculated from this class.
static T max(T x, T y)
Definition: svm.cpp:56
mitk::Image::Pointer image
void AddQuantifierArguments(mitkCommandLineParser &parser)
static T min(T x, T y)
Definition: svm.cpp:53
virtual void SetFeatureClassName(std::string _arg)
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
mitk::Image::Pointer mask
virtual IntensityQuantifier::Pointer GetQuantifier()
void InitializeQuantifierFromParameters(const Image::Pointer &feature, const Image::Pointer &mask, unsigned int defaultBins=256)
void CalculateFirstOrderHistogramStatistics(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer mask, mitk::GIFFirstOrderHistogramStatistics::FeatureListType &featureList, mitk::GIFFirstOrderHistogramStatistics::ParameterStruct params)
std::string GetCurrentFeatureEncoding() override
Adds an additional Separator to the name of the feature, which encodes the used parameters.
void InitializeQuantifier(const Image::Pointer &feature, const Image::Pointer &mask, unsigned int defaultBins=256)
virtual ParameterTypes GetParameter() const