Medical Imaging Interaction Toolkit  2018.4.99-064ad45c
Medical Imaging Interaction Toolkit
mitkGIFCooccurenceMatrix.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
22 #include <itkMinimumMaximumImageCalculator.h>
23 
24 // STL
25 #include <sstream>
26 
27 template<typename TPixel, unsigned int VImageDimension>
28 void
30 {
31  typedef itk::Image<TPixel, VImageDimension> ImageType;
32  typedef itk::Image<TPixel, VImageDimension> MaskType;
34  typedef itk::MinimumMaximumImageCalculator<ImageType> MinMaxComputerType;
35  typedef typename FilterType::TextureFeaturesFilterType TextureFilterType;
36 
37  typename MaskType::Pointer maskImage = MaskType::New();
38  mitk::CastToItkImage(mask, maskImage);
39 
40  typename FilterType::Pointer filter = FilterType::New();
41 
42  typename FilterType::OffsetVector::Pointer newOffset = FilterType::OffsetVector::New();
43  auto oldOffsets = filter->GetOffsets();
44  auto oldOffsetsIterator = oldOffsets->Begin();
45  while(oldOffsetsIterator != oldOffsets->End())
46  {
47  bool continueOuterLoop = false;
48  typename FilterType::OffsetType offset = oldOffsetsIterator->Value();
49  for (unsigned int i = 0; i < VImageDimension; ++i)
50  {
51  offset[i] *= config.range;
52  if (config.direction == i + 2 && offset[i] != 0)
53  {
54  continueOuterLoop = true;
55  }
56  }
57  if (config.direction == 1)
58  {
59  offset[0] = 0;
60  offset[1] = 0;
61  offset[2] = 1;
62  newOffset->push_back(offset);
63  break;
64  }
65 
66 
67  oldOffsetsIterator++;
68  if (continueOuterLoop)
69  continue;
70  newOffset->push_back(offset);
71 
72  }
73  filter->SetOffsets(newOffset);
74 
75  // All features are required
76  typename FilterType::FeatureNameVectorPointer requestedFeatures = FilterType::FeatureNameVector::New();
77  requestedFeatures->push_back(TextureFilterType::Energy);
78  requestedFeatures->push_back(TextureFilterType::Entropy);
79  requestedFeatures->push_back(TextureFilterType::Correlation);
80  requestedFeatures->push_back(TextureFilterType::InverseDifferenceMoment);
81  requestedFeatures->push_back(TextureFilterType::Inertia);
82  requestedFeatures->push_back(TextureFilterType::ClusterShade);
83  requestedFeatures->push_back(TextureFilterType::ClusterProminence);
84  requestedFeatures->push_back(TextureFilterType::HaralickCorrelation);
85  requestedFeatures->push_back(TextureFilterType::Autocorrelation);
86  requestedFeatures->push_back(TextureFilterType::Contrast);
87  requestedFeatures->push_back(TextureFilterType::Dissimilarity);
88  requestedFeatures->push_back(TextureFilterType::MaximumProbability);
89  requestedFeatures->push_back(TextureFilterType::InverseVariance);
90  requestedFeatures->push_back(TextureFilterType::Homogeneity1);
91  requestedFeatures->push_back(TextureFilterType::ClusterTendency);
92  requestedFeatures->push_back(TextureFilterType::Variance);
93  requestedFeatures->push_back(TextureFilterType::SumAverage);
94  requestedFeatures->push_back(TextureFilterType::SumEntropy);
95  requestedFeatures->push_back(TextureFilterType::SumVariance);
96  requestedFeatures->push_back(TextureFilterType::DifferenceAverage);
97  requestedFeatures->push_back(TextureFilterType::DifferenceEntropy);
98  requestedFeatures->push_back(TextureFilterType::DifferenceVariance);
99  requestedFeatures->push_back(TextureFilterType::InverseDifferenceMomentNormalized);
100  requestedFeatures->push_back(TextureFilterType::InverseDifferenceNormalized);
101  requestedFeatures->push_back(TextureFilterType::InverseDifference);
102  requestedFeatures->push_back(TextureFilterType::JointAverage);
103  requestedFeatures->push_back(TextureFilterType::FirstMeasureOfInformationCorrelation);
104  requestedFeatures->push_back(TextureFilterType::SecondMeasureOfInformationCorrelation);
105 
106  typename MinMaxComputerType::Pointer minMaxComputer = MinMaxComputerType::New();
107  minMaxComputer->SetImage(itkImage);
108  minMaxComputer->Compute();
109 
110  filter->SetInput(itkImage);
111  filter->SetMaskImage(maskImage);
112  filter->SetRequestedFeatures(requestedFeatures);
113 
114  double min = minMaxComputer->GetMinimum() - 0.5;
115  double max = minMaxComputer->GetMaximum() + 0.5;
116  if (config.UseMinimumIntensity)
117  min = config.MinimumIntensity;
118  if (config.UseMaximumIntensity)
119  max = config.MaximumIntensity;
120 
121  filter->SetPixelValueMinMax(min,max);
122  //filter->SetPixelValueMinMax(-1024,3096);
123  //filter->SetNumberOfBinsPerAxis(5);
124  filter->Update();
125 
126  auto featureMeans = filter->GetFeatureMeans ();
127  auto featureStd = filter->GetFeatureStandardDeviations();
128 
129  std::ostringstream ss;
130  ss << config.range;
131  std::string strRange = ss.str();
132  for (std::size_t i = 0; i < featureMeans->size(); ++i)
133  {
134  switch (i)
135  {
136  case TextureFilterType::Energy :
137  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Energy Means",featureMeans->ElementAt(i)));
138  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Energy Std.",featureStd->ElementAt(i)));
139  break;
140  case TextureFilterType::Entropy :
141  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Entropy Means",featureMeans->ElementAt(i)));
142  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Entropy Std.",featureStd->ElementAt(i)));
143  break;
144  case TextureFilterType::Correlation :
145  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Correlation Means",featureMeans->ElementAt(i)));
146  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Correlation Std.",featureStd->ElementAt(i)));
147  break;
148  case TextureFilterType::InverseDifferenceMoment :
149  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseDifferenceMoment Means",featureMeans->ElementAt(i)));
150  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseDifferenceMoment Std.",featureStd->ElementAt(i)));
151  break;
152  case TextureFilterType::Inertia :
153  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Inertia Means",featureMeans->ElementAt(i)));
154  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Inertia Std.",featureStd->ElementAt(i)));
155  break;
156  case TextureFilterType::ClusterShade :
157  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") ClusterShade Means",featureMeans->ElementAt(i)));
158  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") ClusterShade Std.",featureStd->ElementAt(i)));
159  break;
160  case TextureFilterType::ClusterProminence :
161  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") ClusterProminence Means",featureMeans->ElementAt(i)));
162  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") ClusterProminence Std.",featureStd->ElementAt(i)));
163  break;
164  case TextureFilterType::HaralickCorrelation :
165  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") HaralickCorrelation Means",featureMeans->ElementAt(i)));
166  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") HaralickCorrelation Std.",featureStd->ElementAt(i)));
167  break;
168  case TextureFilterType::Autocorrelation :
169  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Autocorrelation Means",featureMeans->ElementAt(i)));
170  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Autocorrelation Std.",featureStd->ElementAt(i)));
171  break;
172  case TextureFilterType::Contrast :
173  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Contrast Means",featureMeans->ElementAt(i)));
174  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Contrast Std.",featureStd->ElementAt(i)));
175  break;
176  case TextureFilterType::Dissimilarity :
177  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Dissimilarity Means",featureMeans->ElementAt(i)));
178  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Dissimilarity Std.",featureStd->ElementAt(i)));
179  break;
180  case TextureFilterType::MaximumProbability :
181  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") MaximumProbability Means",featureMeans->ElementAt(i)));
182  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") MaximumProbability Std.",featureStd->ElementAt(i)));
183  break;
184  case TextureFilterType::InverseVariance :
185  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseVariance Means",featureMeans->ElementAt(i)));
186  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseVariance Std.",featureStd->ElementAt(i)));
187  break;
188  case TextureFilterType::Homogeneity1 :
189  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Homogeneity1 Means",featureMeans->ElementAt(i)));
190  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Homogeneity1 Std.",featureStd->ElementAt(i)));
191  break;
192  case TextureFilterType::ClusterTendency :
193  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") ClusterTendency Means",featureMeans->ElementAt(i)));
194  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") ClusterTendency Std.",featureStd->ElementAt(i)));
195  break;
196  case TextureFilterType::Variance :
197  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Variance Means",featureMeans->ElementAt(i)));
198  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") Variance Std.",featureStd->ElementAt(i)));
199  break;
200  case TextureFilterType::SumAverage :
201  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") SumAverage Means",featureMeans->ElementAt(i)));
202  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") SumAverage Std.",featureStd->ElementAt(i)));
203  break;
204  case TextureFilterType::SumEntropy :
205  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") SumEntropy Means",featureMeans->ElementAt(i)));
206  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") SumEntropy Std.",featureStd->ElementAt(i)));
207  break;
208  case TextureFilterType::SumVariance :
209  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") SumVariance Means",featureMeans->ElementAt(i)));
210  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") SumVariance Std.",featureStd->ElementAt(i)));
211  break;
212  case TextureFilterType::DifferenceAverage :
213  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") DifferenceAverage Means",featureMeans->ElementAt(i)));
214  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") DifferenceAverage Std.",featureStd->ElementAt(i)));
215  break;
216  case TextureFilterType::DifferenceEntropy :
217  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") DifferenceEntropy Means",featureMeans->ElementAt(i)));
218  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") DifferenceEntropy Std.",featureStd->ElementAt(i)));
219  break;
220  case TextureFilterType::DifferenceVariance :
221  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") DifferenceVariance Means",featureMeans->ElementAt(i)));
222  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") DifferenceVariance Std.",featureStd->ElementAt(i)));
223  break;
224  case TextureFilterType::InverseDifferenceMomentNormalized :
225  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseDifferenceMomentNormalized Means",featureMeans->ElementAt(i)));
226  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseDifferenceMomentNormalized Std.",featureStd->ElementAt(i)));
227  break;
228  case TextureFilterType::InverseDifferenceNormalized :
229  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseDifferenceNormalized Means",featureMeans->ElementAt(i)));
230  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseDifferenceNormalized Std.",featureStd->ElementAt(i)));
231  break;
232  case TextureFilterType::InverseDifference :
233  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseDifference Means",featureMeans->ElementAt(i)));
234  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") InverseDifference Std.",featureStd->ElementAt(i)));
235  break;
236  case TextureFilterType::JointAverage :
237  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") JointAverage Means",featureMeans->ElementAt(i)));
238  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") JointAverage Std.",featureStd->ElementAt(i)));
239  break;
240  case TextureFilterType::FirstMeasureOfInformationCorrelation :
241  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") FirstMeasureOfInformationCorrelation Means",featureMeans->ElementAt(i)));
242  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") FirstMeasureOfInformationCorrelation Std.",featureStd->ElementAt(i)));
243  break;
244  case TextureFilterType::SecondMeasureOfInformationCorrelation :
245  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") SecondMeasureOfInformationCorrelation Means",featureMeans->ElementAt(i)));
246  featureList.push_back(std::make_pair("co-occ. ("+ strRange+") SecondMeasureOfInformationCorrelation Std.",featureStd->ElementAt(i)));
247  break;
248  default:
249  break;
250  }
251  }
252 }
253 
255 m_Range(1.0)
256 {
257  SetShortName("deprecated-cooc");
258  SetLongName("deprecated-cooccurence");
259  SetFeatureClassName("Deprecated Co-occurence Features");
260 }
261 
263 {
264  FeatureListType featureList;
265 
267  config.direction = GetDirection();
268  config.range = m_Range;
269 
274  config.Bins = GetBins();
275 
276  AccessByItk_3(image, CalculateCoocurenceFeatures, mask, featureList,config);
277 
278  return featureList;
279 }
280 
282 {
283  FeatureNameListType featureList;
284  featureList.push_back("co-occ. Energy Means");
285  featureList.push_back("co-occ. Energy Std.");
286  return featureList;
287 }
288 
289 
290 
292 {
293  std::string name = GetOptionPrefix();
294 
295  parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Co-occurence matrix", "calculates Co-occurence based features", us::Any());
296  parser.addArgument(name + "::range", name + "::range", mitkCommandLineParser::String, "Cooc 2 Range", "Define the range that is used (Semicolon-separated)", us::Any());
297 }
298 
299 void
301 {
302  auto parsedArgs = GetParameter();
303  std::string name = GetOptionPrefix();
304 
305  if (parsedArgs.count(GetLongName()))
306  {
307  std::vector<double> ranges;
308  if (parsedArgs.count(name + "::range"))
309  {
310  ranges = SplitDouble(parsedArgs[name + "::range"].ToString(), ';');
311  }
312  else
313  {
314  ranges.push_back(1);
315  }
316 
317  for (std::size_t i = 0; i < ranges.size(); ++i)
318  {
319  MITK_INFO << "Start calculating coocurence with range " << ranges[i] << "....";
321  coocCalculator->SetRange(ranges[i]);
322  auto localResults = coocCalculator->CalculateFeatures(feature, maskNoNAN);
323  featureList.insert(featureList.end(), localResults.begin(), localResults.end());
324  MITK_INFO << "Finished calculating coocurence with range " << ranges[i] << "....";
325  }
326  }
327 }
328 
#define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3)
void CalculateCoocurenceFeatures(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer mask, mitk::GIFCooccurenceMatrix::FeatureListType &featureList, mitk::GIFCooccurenceMatrix::GIFCooccurenceMatrixConfiguration config)
#define MITK_INFO
Definition: mitkLogMacros.h:18
itk::Image< unsigned char, 3 > ImageType
void AddArguments(mitkCommandLineParser &parser) override
virtual void SetLongName(std::string _arg)
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 bool GetUseMaximumIntensity() const
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...
virtual void SetShortName(std::string _arg)
virtual double GetMinimumIntensity() const
std::vector< std::pair< std::string, double > > FeatureListType
static Vector3D offset
virtual std::string GetLongName() const
Definition: usAny.h:163
FeatureListType CalculateFeatures(const Image::Pointer &image, const Image::Pointer &feature) override
Calculates the Cooccurence-Matrix based features for this class.
virtual int GetDirection() const
static T max(T x, T y)
Definition: svm.cpp:56
mitk::Image::Pointer image
static T min(T x, T y)
Definition: svm.cpp:53
std::vector< double > SplitDouble(std::string str, char delimiter)
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.
virtual bool GetUseMinimumIntensity() const
mitk::Image::Pointer mask
FeatureNameListType GetFeatureNames() override
Returns a list of the names of all features that are calculated from this class.
virtual double GetMaximumIntensity() const
virtual ParameterTypes GetParameter() const