Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
ImageStatisticsMiniApp.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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkCommandLineParser.h"
18 #include "mitkImage.h"
19 #include "mitkImageStatisticsCalculator.h"
20 #include "mitkIOUtil.h"
21 #include <iostream>
22 #include <usAny.h>
23 #include <fstream>
24 #include <itkImageRegionConstIterator.h>
25 #include "mitkImageAccessByItk.h"
26 #include <boost/accumulators/accumulators.hpp>
27 #include <boost/accumulators/statistics/stats.hpp>
28 #include <boost/accumulators/statistics/mean.hpp>
29 #include <boost/accumulators/statistics/variance.hpp>
30 #include <boost/accumulators/statistics/min.hpp>
31 #include <boost/accumulators/statistics/max.hpp>
32 #include <boost/accumulators/statistics/count.hpp>
33 #include <boost/accumulators/statistics/moment.hpp>
34 #include <mitkImageMaskGenerator.h>
36 
37 struct statistics_res{
38  double mean, variance, min, max, count, moment;
39 };
40 
41 void printstats(statistics_res s)
42 {
43  std::cout << "mean: " << s.mean << std::endl
44  << "variance: " << s.variance << std::endl
45  << "min: " << s.min << std::endl
46  << "max: " << s.max << std::endl
47  << "count: " << s.count << std::endl
48  << "moment: " << s.moment << std::endl;
49 }
50 
51 template < typename TPixel, unsigned int VImageDimension >
52 void get_statistics_boost(itk::Image<TPixel, VImageDimension>* itkImage, statistics_res& res){
53  typedef itk::Image<TPixel, VImageDimension> ImageType;
54 
55  itk::ImageRegionConstIterator<ImageType> it(itkImage, itkImage->GetLargestPossibleRegion());
56 
57  TPixel currentPixel;
58  int ctr=0;
59  double sum=0;
60 
61  boost::accumulators::accumulator_set<double, boost::accumulators::stats<
62  boost::accumulators::tag::mean,
63  boost::accumulators::tag::variance,
66  boost::accumulators::tag::count,
67  boost::accumulators::tag::moment<2>> > acc;
68 
69  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
70  {
71  acc(it.Get());
72 // currentPixel = it.Get();
73 // sum+=currentPixel;
74 // ctr+=1;
75  }
76 
77 // res.mean=(double)sum/(double)ctr;
78  res.mean = boost::accumulators::mean(acc);
79  res.variance = boost::accumulators::variance(acc);
80  res.min = boost::accumulators::min(acc);
81  res.max = boost::accumulators::max(acc);
82  res.count = boost::accumulators::count(acc);
83  res.moment = boost::accumulators::moment<2>(acc);
84 
85  std::cout << "sum: " << sum << " N: " << ctr << " mean: " << res.mean << std::endl;
86 }
87 
88 int main( int argc, char* argv[] )
89 {
90  mitkCommandLineParser parser;
91 
92  parser.setTitle("Extract Image Statistics");
93  parser.setCategory("Preprocessing Tools");
94  parser.setDescription("");
95  parser.setContributor("MBI");
96 
97  parser.setArgumentPrefix("--", "-");
98  parser.addArgument("help", "h", mitkCommandLineParser::String, "Help:", "Show this help text");
99  parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(),false);
100  parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image / roi image denotin area on which statistics are calculated", us::Any(),true);
101  parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output", "output file (default: filenameOfRoi.nrrd_statistics.txt)", us::Any());
102 
103  std::cout << "test...." << std::endl;
104 
105  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
106  std::cout << "parsedArgs.size()= " << parsedArgs.size() << std::endl;
107  if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h"))
108  {
109  std::cout << "\n\n MiniApp Description: \nCalculates statistics on the supplied image using given mask." << endl;
110  std::cout << "Output is written to the designated output file in this order:" << endl;
111  std::cout << "Mean, Standard Deviation, RMS, Max, Min, Number of Voxels, Volume [mm3]" << endl;
112  std::cout << "\n\n Parameters:"<< endl;
113  std::cout << parser.helpText();
114  return EXIT_SUCCESS;
115  }
116 
117 
118  // Parameters:
119  bool ignoreZeroValues = false;
120  unsigned int timeStep = 0;
121 
122  std::string inputImageFile = us::any_cast<std::string>(parsedArgs["input"]);
123  mitk::Image::Pointer maskImage;
124  if (parsedArgs.count("mask") || parsedArgs.count("m"))
125  {
126  std::string maskImageFile = us::any_cast<std::string>(parsedArgs["mask"]);
127  maskImage = mitk::IOUtil::LoadImage(maskImageFile);
128  }
129 
130  std::string outFile;
131  if (parsedArgs.count("out") || parsedArgs.count("o") )
132  outFile = us::any_cast<std::string>(parsedArgs["out"]);
133  else
134  outFile = inputImageFile + "_statistics.txt";
135 
136  // Load image and mask
137  mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile);
138 
139  // Calculate statistics
142  try
143  {
144  calculator->SetInputImage(inputImage);
145  if (parsedArgs.count("mask") || parsedArgs.count("m"))
146  {
148  imgMask->SetImageMask(maskImage);
149  imgMask->SetTimeStep(timeStep);
150  calculator->SetMask(imgMask.GetPointer());
151  }
152  else
153  {
154  calculator->SetMask(nullptr);
155  }
156 
157  }
158  catch( const itk::ExceptionObject& e)
159  {
160  MITK_ERROR << "Statistic Calculation Failed - ITK Exception:" << e.what();
161  return -1;
162  }
163 
164 
165  if (ignoreZeroValues)
166  {
167  // TODO, cannot have more than one mask, using ignore pixel value will override the image mask :-c
169  ignorePixelMask->SetInputImage(inputImage);
170  ignorePixelMask->SetTimeStep(timeStep);
171  ignorePixelMask->SetIgnoredPixelValue(0);
172  calculator->SetMask(ignorePixelMask.GetPointer());
173  }
174 
175  std::cout << "calculating statistics itk: " << std::endl;
176  try
177  {
178  statisticsStruct = calculator->GetStatistics(timeStep);
179  }
180  catch ( mitk::Exception& e)
181  {
182  MITK_ERROR<< "MITK Exception: " << e.what();
183  return -1;
184  }
185 
186 
187  // Calculate Volume
188  double volume = 0;
189  const mitk::BaseGeometry *geometry = inputImage->GetGeometry();
190  if ( geometry != NULL )
191  {
192  const mitk::Vector3D &spacing = inputImage->GetGeometry()->GetSpacing();
193  volume = spacing[0] * spacing[1] * spacing[2] * (double) statisticsStruct->GetN();
194  }
195 
196  // Write Results to file
197  std::ofstream output;
198  output.open(outFile.c_str());
199  output << statisticsStruct->GetMean() << " , ";
200  output << statisticsStruct->GetStd() << " , ";
201  output << statisticsStruct->GetRMS() << " , ";
202  output << statisticsStruct->GetMax() << " , ";
203  output << statisticsStruct->GetMin() << " , ";
204  output << statisticsStruct->GetN() << " , ";
205  output << volume << "\n";
206 
207  output.flush();
208  output.close();
209 
210  std::cout << "calculating statistics boost: " << std::endl;
211 
212  statistics_res res;
213  AccessByItk_n(inputImage, get_statistics_boost, (res));
214 
215  printstats(res);
216 
217  return EXIT_SUCCESS;
218 }
void get_statistics_boost(itk::Image< TPixel, VImageDimension > *itkImage, statistics_res &res)
itk::Image< unsigned char, 3 > ImageType
#define MITK_ERROR
Definition: mitkLogMacros.h:24
void setContributor(std::string contributor)
static Pointer New()
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
int main(int argc, char *argv[])
#define AccessByItk_n(mitkImage, itkImageTypeFunction, va_tuple)
Access a MITK image by an ITK image with one or more parameters.
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
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)
An object of this class represents an exception of MITK. Please don't instantiate exceptions manually...
Definition: mitkException.h:49
Definition: usAny.h:163
static T max(T x, T y)
Definition: svm.cpp:70
void setCategory(std::string category)
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
void printstats(statistics_res s)
static T min(T x, T y)
Definition: svm.cpp:67
std::string helpText() const
void setTitle(std::string title)
void setDescription(std::string description)
static mitk::Image::Pointer LoadImage(const std::string &path)
LoadImage Convenience method to load an arbitrary mitkImage.
Definition: mitkIOUtil.cpp:597
BaseGeometry Describes the geometry of a data object.