Medical Imaging Interaction Toolkit  2018.4.99-f51274ea
Medical Imaging Interaction Toolkit
CLGlobalImageFeatures.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 #ifndef mitkCLPolyToNrrd_cpp
13 #define mitkCLPolyToNrrd_cpp
14 
15 #include "time.h"
16 #include <sstream>
17 #include <fstream>
18 
19 #include <mitkIOUtil.h>
20 #include "mitkCommandLineParser.h"
21 
24 
36 #include <mitkGIFLocalIntensity.h>
41 #include <mitkImageAccessByItk.h>
42 #include <mitkImageCast.h>
43 #include <mitkITKImageImport.h>
45 
46 #include <mitkCLResultWritter.h>
47 #include <mitkVersion.h>
48 
49 #include <iostream>
50 #include <locale>
51 
52 #include <itkImageDuplicator.h>
53 #include <itkImageRegionIterator.h>
54 
55 
56 #include "itkNearestNeighborInterpolateImageFunction.h"
57 #include "itkResampleImageFilter.h"
58 
59 #include <QApplication>
61 #include "QmitkRegisterClasses.h"
62 #include "QmitkRenderWindow.h"
63 #include "vtkRenderLargeImage.h"
64 #include "vtkPNGWriter.h"
65 
66 
67 
68 typedef itk::Image< double, 3 > FloatImageType;
69 typedef itk::Image< unsigned short, 3 > MaskImageType;
70 
71 template <class charT>
72 class punct_facet : public std::numpunct<charT> {
73 public:
74  punct_facet(charT sep) :
75  m_Sep(sep)
76  {
77 
78  }
79 protected:
80  charT do_decimal_point() const override { return m_Sep; }
81 private:
82  charT m_Sep;
83 };
84 
85 template<typename TPixel, unsigned int VImageDimension>
86 void
87 ResampleImage(itk::Image<TPixel, VImageDimension>* itkImage, float resolution, mitk::Image::Pointer& newImage)
88 {
89  typedef itk::Image<TPixel, VImageDimension> ImageType;
90  typedef itk::ResampleImageFilter<ImageType, ImageType> ResampleFilterType;
91 
92  typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
93  auto spacing = itkImage->GetSpacing();
94  auto size = itkImage->GetLargestPossibleRegion().GetSize();
95 
96  for (unsigned int i = 0; i < VImageDimension; ++i)
97  {
98  size[i] = size[i] / (1.0*resolution)*(1.0*spacing[i])+1.0;
99  }
100  spacing.Fill(resolution);
101 
102  resampler->SetInput(itkImage);
103  resampler->SetSize(size);
104  resampler->SetOutputSpacing(spacing);
105  resampler->SetOutputOrigin(itkImage->GetOrigin());
106  resampler->SetOutputDirection(itkImage->GetDirection());
107  resampler->Update();
108 
109  newImage->InitializeByItk(resampler->GetOutput());
110  mitk::GrabItkImageMemory(resampler->GetOutput(), newImage);
111 }
112 
113 
114 template<typename TPixel, unsigned int VImageDimension>
115 static void
116 CreateNoNaNMask(itk::Image<TPixel, VImageDimension>* itkValue, mitk::Image::Pointer mask, mitk::Image::Pointer& newMask)
117 {
118  typedef itk::Image< TPixel, VImageDimension> LFloatImageType;
119  typedef itk::Image< unsigned short, VImageDimension> LMaskImageType;
120  typename LMaskImageType::Pointer itkMask = LMaskImageType::New();
121 
122  mitk::CastToItkImage(mask, itkMask);
123 
124  typedef itk::ImageDuplicator< LMaskImageType > DuplicatorType;
125  typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
126  duplicator->SetInputImage(itkMask);
127  duplicator->Update();
128 
129  auto tmpMask = duplicator->GetOutput();
130 
131  itk::ImageRegionIterator<LMaskImageType> mask1Iter(itkMask, itkMask->GetLargestPossibleRegion());
132  itk::ImageRegionIterator<LMaskImageType> mask2Iter(tmpMask, tmpMask->GetLargestPossibleRegion());
133  itk::ImageRegionIterator<LFloatImageType> imageIter(itkValue, itkValue->GetLargestPossibleRegion());
134  while (!mask1Iter.IsAtEnd())
135  {
136  mask2Iter.Set(0);
137  if (mask1Iter.Value() > 0)
138  {
139  // Is not NaN
140  if (imageIter.Value() == imageIter.Value())
141  {
142  mask2Iter.Set(1);
143  }
144  }
145  ++mask1Iter;
146  ++mask2Iter;
147  ++imageIter;
148  }
149 
150  newMask->InitializeByItk(tmpMask);
151  mitk::GrabItkImageMemory(tmpMask, newMask);
152 }
153 
154 template<typename TPixel, unsigned int VImageDimension>
155 static void
156 ResampleMask(itk::Image<TPixel, VImageDimension>* itkMoving, mitk::Image::Pointer ref, mitk::Image::Pointer& newMask)
157 {
158  typedef itk::Image< TPixel, VImageDimension> LMaskImageType;
159  typedef itk::NearestNeighborInterpolateImageFunction< LMaskImageType> NearestNeighborInterpolateImageFunctionType;
160  typedef itk::ResampleImageFilter<LMaskImageType, LMaskImageType> ResampleFilterType;
161 
162  typename NearestNeighborInterpolateImageFunctionType::Pointer nn_interpolator = NearestNeighborInterpolateImageFunctionType::New();
163  typename LMaskImageType::Pointer itkRef = LMaskImageType::New();
164  mitk::CastToItkImage(ref, itkRef);
165 
166 
167  typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
168  resampler->SetInput(itkMoving);
169  resampler->SetReferenceImage(itkRef);
170  resampler->UseReferenceImageOn();
171  resampler->SetInterpolator(nn_interpolator);
172  resampler->Update();
173 
174  newMask->InitializeByItk(resampler->GetOutput());
175  mitk::GrabItkImageMemory(resampler->GetOutput(), newMask);
176 }
177 
178 static void
180  mitk::Image::Pointer maskNoNaN, mitk::Image::Pointer morphMask,
181  int direction,
182  std::vector<mitk::Image::Pointer> &imageVector,
183  std::vector<mitk::Image::Pointer> &maskVector,
184  std::vector<mitk::Image::Pointer> &maskNoNaNVector,
185  std::vector<mitk::Image::Pointer> &morphMaskVector)
186 {
187  typedef itk::Image< double, 2 > FloatImage2DType;
188  typedef itk::Image< unsigned short, 2 > MaskImage2DType;
189 
190  FloatImageType::Pointer itkFloat = FloatImageType::New();
191  MaskImageType::Pointer itkMask = MaskImageType::New();
192  MaskImageType::Pointer itkMaskNoNaN = MaskImageType::New();
193  MaskImageType::Pointer itkMorphMask = MaskImageType::New();
194  mitk::CastToItkImage(mask, itkMask);
195  mitk::CastToItkImage(maskNoNaN, itkMaskNoNaN);
196  mitk::CastToItkImage(image, itkFloat);
197  mitk::CastToItkImage(morphMask, itkMorphMask);
198 
199  int idxA, idxB, idxC;
200  switch (direction)
201  {
202  case 0:
203  idxA = 1; idxB = 2; idxC = 0;
204  break;
205  case 1:
206  idxA = 0; idxB = 2; idxC = 1;
207  break;
208  case 2:
209  idxA = 0; idxB = 1; idxC = 2;
210  break;
211  default:
212  idxA = 1; idxB = 2; idxC = 0;
213  break;
214  }
215 
216  auto imageSize = image->GetLargestPossibleRegion().GetSize();
217  FloatImageType::IndexType index3D;
218  FloatImage2DType::IndexType index2D;
219  FloatImage2DType::SpacingType spacing2D;
220  spacing2D[0] = itkFloat->GetSpacing()[idxA];
221  spacing2D[1] = itkFloat->GetSpacing()[idxB];
222 
223  for (unsigned int i = 0; i < imageSize[idxC]; ++i)
224  {
225  FloatImage2DType::RegionType region;
226  FloatImage2DType::IndexType start;
227  FloatImage2DType::SizeType size;
228  start[0] = 0; start[1] = 0;
229  size[0] = imageSize[idxA];
230  size[1] = imageSize[idxB];
231  region.SetIndex(start);
232  region.SetSize(size);
233 
234  FloatImage2DType::Pointer image2D = FloatImage2DType::New();
235  image2D->SetRegions(region);
236  image2D->Allocate();
237 
238  MaskImage2DType::Pointer mask2D = MaskImage2DType::New();
239  mask2D->SetRegions(region);
240  mask2D->Allocate();
241 
242  MaskImage2DType::Pointer masnNoNaN2D = MaskImage2DType::New();
243  masnNoNaN2D->SetRegions(region);
244  masnNoNaN2D->Allocate();
245 
246  MaskImage2DType::Pointer morph2D = MaskImage2DType::New();
247  morph2D->SetRegions(region);
248  morph2D->Allocate();
249 
250 
251  unsigned long voxelsInMask = 0;
252 
253  for (unsigned int a = 0; a < imageSize[idxA]; ++a)
254  {
255  for (unsigned int b = 0; b < imageSize[idxB]; ++b)
256  {
257  index3D[idxA] = a;
258  index3D[idxB] = b;
259  index3D[idxC] = i;
260  index2D[0] = a;
261  index2D[1] = b;
262  image2D->SetPixel(index2D, itkFloat->GetPixel(index3D));
263  mask2D->SetPixel(index2D, itkMask->GetPixel(index3D));
264  masnNoNaN2D->SetPixel(index2D, itkMaskNoNaN->GetPixel(index3D));
265  morph2D->SetPixel(index2D, itkMorphMask->GetPixel(index3D));
266  voxelsInMask += (itkMask->GetPixel(index3D) > 0) ? 1 : 0;
267 
268  }
269  }
270 
271  image2D->SetSpacing(spacing2D);
272  mask2D->SetSpacing(spacing2D);
273  masnNoNaN2D->SetSpacing(spacing2D);
274  morph2D->SetSpacing(spacing2D);
275 
276  mitk::Image::Pointer tmpFloatImage = mitk::Image::New();
277  tmpFloatImage->InitializeByItk(image2D.GetPointer());
278  mitk::GrabItkImageMemory(image2D, tmpFloatImage);
279 
280  mitk::Image::Pointer tmpMaskImage = mitk::Image::New();
281  tmpMaskImage->InitializeByItk(mask2D.GetPointer());
282  mitk::GrabItkImageMemory(mask2D, tmpMaskImage);
283 
284  mitk::Image::Pointer tmpMaskNoNaNImage = mitk::Image::New();
285  tmpMaskNoNaNImage->InitializeByItk(masnNoNaN2D.GetPointer());
286  mitk::GrabItkImageMemory(masnNoNaN2D, tmpMaskNoNaNImage);
287 
288  mitk::Image::Pointer tmpMorphMaskImage = mitk::Image::New();
289  tmpMorphMaskImage->InitializeByItk(morph2D.GetPointer());
290  mitk::GrabItkImageMemory(morph2D, tmpMorphMaskImage);
291 
292  if (voxelsInMask > 0)
293  {
294  imageVector.push_back(tmpFloatImage);
295  maskVector.push_back(tmpMaskImage);
296  maskNoNaNVector.push_back(tmpMaskNoNaNImage);
297  morphMaskVector.push_back(tmpMorphMaskImage);
298  }
299  }
300 }
301 
302 static
304 {
305  // Create a Standalone Datastorage for the single purpose of saving screenshots..
307  QmitkRenderWindow renderWindow;
308  renderWindow.GetRenderer()->SetDataStorage(ds);
309 
310  auto nodeI = mitk::DataNode::New();
311  nodeI->SetData(image);
312  auto nodeM = mitk::DataNode::New();
313  nodeM->SetData(mask);
314  ds->Add(nodeI);
315  ds->Add(nodeM);
316 
317  auto geo = ds->ComputeBoundingGeometry3D(ds->GetAll());
319 
320  mitk::SliceNavigationController::Pointer sliceNaviController = renderWindow.GetSliceNavigationController();
321  unsigned int numberOfSteps = 1;
322  if (sliceNaviController)
323  {
324  numberOfSteps = sliceNaviController->GetSlice()->GetSteps();
325  sliceNaviController->GetSlice()->SetPos(0);
326  }
327 
328  renderWindow.show();
329  renderWindow.resize(256, 256);
330 
331  for (unsigned int currentStep = 0; currentStep < numberOfSteps; ++currentStep)
332  {
333  if (sliceNaviController)
334  {
335  sliceNaviController->GetSlice()->SetPos(currentStep);
336  }
337 
338  renderWindow.GetRenderer()->PrepareRender();
339 
340  vtkRenderWindow* renderWindow2 = renderWindow.GetVtkRenderWindow();
341  mitk::BaseRenderer* baserenderer = mitk::BaseRenderer::GetInstance(renderWindow2);
342  auto vtkRender = baserenderer->GetVtkRenderer();
343  vtkRender->GetRenderWindow()->WaitForCompletion();
344 
345  vtkRenderLargeImage* magnifier = vtkRenderLargeImage::New();
346  magnifier->SetInput(vtkRender);
347  magnifier->SetMagnification(3.0);
348 
349  std::stringstream ss;
350  ss << path << "_Idx-" << index << "_Step-"<<currentStep<<".png";
351  std::string tmpImageName;
352  ss >> tmpImageName;
353  auto fileWriter = vtkPNGWriter::New();
354  fileWriter->SetInputConnection(magnifier->GetOutputPort());
355  fileWriter->SetFileName(tmpImageName.c_str());
356  fileWriter->Write();
357  fileWriter->Delete();
358  }
359 }
360 
361 int main(int argc, char* argv[])
362 {
363  // Commented : Updated to a common interface, include, if possible, mask is type unsigned short, uses Quantification, Comments
364  // Name follows standard scheme with Class Name::Feature Name
365  // Commented 2: Updated to use automatic inclusion of list of parameters if required.
367  mitk::GIFFirstOrderStatistics::Pointer firstOrderCalculator = mitk::GIFFirstOrderStatistics::New(); //Commented 2
368  mitk::GIFFirstOrderHistogramStatistics::Pointer firstOrderHistoCalculator = mitk::GIFFirstOrderHistogramStatistics::New(); // Commented 2, Tested
369  mitk::GIFFirstOrderNumericStatistics::Pointer firstOrderNumericCalculator = mitk::GIFFirstOrderNumericStatistics::New(); // Commented 2, Tested
370  mitk::GIFVolumetricStatistics::Pointer volCalculator = mitk::GIFVolumetricStatistics::New(); // Commented 2, Tested
372  mitk::GIFCooccurenceMatrix::Pointer coocCalculator = mitk::GIFCooccurenceMatrix::New(); // Commented 2, Will not be tested
376  mitk::GIFGreyLevelSizeZone::Pointer glszCalculator = mitk::GIFGreyLevelSizeZone::New(); // Commented 2, Tested
377  mitk::GIFGreyLevelDistanceZone::Pointer gldzCalculator = mitk::GIFGreyLevelDistanceZone::New(); //Commented 2, Tested
378  mitk::GIFLocalIntensity::Pointer lociCalculator = mitk::GIFLocalIntensity::New(); //Commented 2, Tested
381  mitk::GIFCurvatureStatistic::Pointer curvCalculator = mitk::GIFCurvatureStatistic::New(); //Commented 2, Tested
382 
383  std::vector<mitk::AbstractGlobalImageFeature::Pointer> features;
384  features.push_back(volCalculator.GetPointer());
385  features.push_back(voldenCalculator.GetPointer());
386  features.push_back(curvCalculator.GetPointer());
387  features.push_back(firstOrderCalculator.GetPointer());
388  features.push_back(firstOrderNumericCalculator.GetPointer());
389  features.push_back(firstOrderHistoCalculator.GetPointer());
390  features.push_back(ivohCalculator.GetPointer());
391  features.push_back(lociCalculator.GetPointer());
392  features.push_back(coocCalculator.GetPointer());
393  features.push_back(cooc2Calculator.GetPointer());
394  features.push_back(ngldCalculator.GetPointer());
395  features.push_back(rlCalculator.GetPointer());
396  features.push_back(glszCalculator.GetPointer());
397  features.push_back(gldzCalculator.GetPointer());
398  features.push_back(ipCalculator.GetPointer());
399  features.push_back(ngtdCalculator.GetPointer());
400 
401  mitkCommandLineParser parser;
402  parser.setArgumentPrefix("--", "-");
404  param.AddParameter(parser);
405 
406  parser.addArgument("--","-", mitkCommandLineParser::String, "---", "---", us::Any(),true);
407  for (auto cFeature : features)
408  {
409  cFeature->AddArguments(parser);
410  }
411 
412  parser.addArgument("--", "-", mitkCommandLineParser::String, "---", "---", us::Any(), true);
413  parser.addArgument("description","d",mitkCommandLineParser::String,"Text","Description that is added to the output",us::Any());
414  parser.addArgument("direction", "dir", mitkCommandLineParser::String, "Int", "Allows to specify the direction for Cooc and RL. 0: All directions, 1: Only single direction (Test purpose), 2,3,4... Without dimension 0,1,2... ", us::Any());
415  parser.addArgument("slice-wise", "slice", mitkCommandLineParser::String, "Int", "Allows to specify if the image is processed slice-wise (number giving direction) ", us::Any());
416  parser.addArgument("output-mode", "omode", mitkCommandLineParser::Int, "Int", "Defines if the results of an image / slice are written in a single row (0 , default) or column (1).");
417 
418  // Miniapp Infos
419  parser.setCategory("Classification Tools");
420  parser.setTitle("Global Image Feature calculator");
421  parser.setDescription("Calculates different global statistics for a given segmentation / image combination");
422  parser.setContributor("German Cancer Research Center (DKFZ)");
423 
424  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
425  param.ParseParameter(parsedArgs);
426 
427  if (parsedArgs.size()==0)
428  {
429  return EXIT_FAILURE;
430  }
431  if ( parsedArgs.count("help") || parsedArgs.count("h"))
432  {
433  return EXIT_SUCCESS;
434  }
435 
436  //bool savePNGofSlices = true;
437  //std::string folderForPNGOfSlices = "E:\\tmp\\bonekamp\\fig\\";
438 
439  std::string version = "Version: 1.22";
440  MITK_INFO << version;
441 
442  std::ofstream log;
443  if (param.useLogfile)
444  {
445  log.open(param.logfilePath, std::ios::app);
446  log << std::endl;
447  log << version;
448  log << "Image: " << param.imagePath;
449  log << "Mask: " << param.maskPath;
450  }
451 
452 
453  if (param.useDecimalPoint)
454  {
455  std::cout.imbue(std::locale(std::cout.getloc(), new punct_facet<char>(param.decimalPoint)));
456  }
457 
460 
461  mitk::Image::Pointer tmpImage = mitk::IOUtil::Load<mitk::Image>(param.imagePath);
462  mitk::Image::Pointer tmpMask = mitk::IOUtil::Load<mitk::Image>(param.maskPath);
463  image = tmpImage;
464  mask = tmpMask;
465 
466  mitk::Image::Pointer morphMask = mask;
467  if (param.useMorphMask)
468  {
469  morphMask = mitk::IOUtil::Load<mitk::Image>(param.morphPath);
470  }
471 
472  log << " Check for Dimensions -";
473  if ((image->GetDimension() != mask->GetDimension()))
474  {
475  MITK_INFO << "Dimension of image does not match. ";
476  MITK_INFO << "Correct one image, may affect the result";
477  if (image->GetDimension() == 2)
478  {
480  multiFilter2->SetInput(tmpImage);
481  multiFilter2->Update();
482  image = multiFilter2->GetOutput();
483  }
484  if (mask->GetDimension() == 2)
485  {
487  multiFilter3->SetInput(tmpMask);
488  multiFilter3->Update();
489  mask = multiFilter3->GetOutput();
490  }
491  }
492 
493  int writeDirection = 0;
494  if (parsedArgs.count("output-mode"))
495  {
496  writeDirection = us::any_cast<int>(parsedArgs["output-mode"]);
497  }
498 
499  log << " Check for Resolution -";
500  if (param.resampleToFixIsotropic)
501  {
503  AccessByItk_2(image, ResampleImage, param.resampleResolution, newImage);
504  image = newImage;
505  }
506  if ( ! mitk::Equal(mask->GetGeometry(0)->GetOrigin(), image->GetGeometry(0)->GetOrigin()))
507  {
508  MITK_INFO << "Not equal Origins";
509  if (param.ensureSameSpace)
510  {
511  MITK_INFO << "Warning!";
512  MITK_INFO << "The origin of the input image and the mask do not match. They are";
513  MITK_INFO << "now corrected. Please check to make sure that the images still match";
514  image->GetGeometry(0)->SetOrigin(mask->GetGeometry(0)->GetOrigin());
515  } else
516  {
517  return -1;
518  }
519  }
520 
521  log << " Resample if required -";
522  if (param.resampleMask)
523  {
524  mitk::Image::Pointer newMaskImage = mitk::Image::New();
525  AccessByItk_2(mask, ResampleMask, image, newMaskImage);
526  mask = newMaskImage;
527  }
528 
529  log << " Check for Equality -";
530  if ( ! mitk::Equal(mask->GetGeometry(0)->GetSpacing(), image->GetGeometry(0)->GetSpacing()))
531  {
532  MITK_INFO << "Not equal Spacing";
533  if (param.ensureSameSpace)
534  {
535  MITK_INFO << "Warning!";
536  MITK_INFO << "The spacing of the mask was set to match the spacing of the input image.";
537  MITK_INFO << "This might cause unintended spacing of the mask image";
538  image->GetGeometry(0)->SetSpacing(mask->GetGeometry(0)->GetSpacing());
539  } else
540  {
541  MITK_INFO << "The spacing of the mask and the input images is not equal.";
542  MITK_INFO << "Terminating the programm. You may use the '-fi' option";
543  return -1;
544  }
545  }
546 
547  int direction = 0;
548  if (parsedArgs.count("direction"))
549  {
550  direction = mitk::cl::splitDouble(parsedArgs["direction"].ToString(), ';')[0];
551  }
552 
553  MITK_INFO << "Start creating Mask without NaN";
554 
556  AccessByItk_2(image, CreateNoNaNMask, mask, maskNoNaN);
557  //CreateNoNaNMask(mask, image, maskNoNaN);
558 
559 
560  bool sliceWise = false;
561  int sliceDirection = 0;
562  unsigned int currentSlice = 0;
563  bool imageToProcess = true;
564 
565  std::vector<mitk::Image::Pointer> floatVector;
566  std::vector<mitk::Image::Pointer> maskVector;
567  std::vector<mitk::Image::Pointer> maskNoNaNVector;
568  std::vector<mitk::Image::Pointer> morphMaskVector;
569 
570  if ((parsedArgs.count("slice-wise")) && image->GetDimension() > 2)
571  {
572  MITK_INFO << "Enabled slice-wise";
573  sliceWise = true;
574  sliceDirection = mitk::cl::splitDouble(parsedArgs["slice-wise"].ToString(), ';')[0];
575  MITK_INFO << sliceDirection;
576  ExtractSlicesFromImages(image, mask, maskNoNaN, morphMask, sliceDirection, floatVector, maskVector, maskNoNaNVector, morphMaskVector);
577  MITK_INFO << "Slice";
578  }
579 
580  log << " Configure features -";
581  for (auto cFeature : features)
582  {
584  {
585  cFeature->SetMinimumIntensity(param.globalMinimumIntensity);
586  cFeature->SetUseMinimumIntensity(true);
587  }
589  {
590  cFeature->SetMaximumIntensity(param.globalMaximumIntensity);
591  cFeature->SetUseMaximumIntensity(true);
592  }
593  if (param.defineGlobalNumberOfBins)
594  {
595  cFeature->SetBins(param.globalNumberOfBins);
596  MITK_INFO << param.globalNumberOfBins;
597  }
598  cFeature->SetParameter(parsedArgs);
599  cFeature->SetDirection(direction);
600  cFeature->SetEncodeParameters(param.encodeParameter);
601  }
602 
603  bool addDescription = parsedArgs.count("description");
604  mitk::cl::FeatureResultWritter writer(param.outputPath, writeDirection);
605 
606  if (param.useDecimalPoint)
607  {
608  writer.SetDecimalPoint(param.decimalPoint);
609  }
610 
611  std::string description = "";
612  if (addDescription)
613  {
614  description = parsedArgs["description"].ToString();
615  }
616 
617  mitk::Image::Pointer cImage = image;
618  mitk::Image::Pointer cMask = mask;
619  mitk::Image::Pointer cMaskNoNaN = maskNoNaN;
620  mitk::Image::Pointer cMorphMask = morphMask;
621 
622  if (param.useHeader)
623  {
624  writer.AddColumn("SoftwareVersion");
625  writer.AddColumn("Patient");
626  writer.AddColumn("Image");
627  writer.AddColumn("Segmentation");
628  }
629 
630  // Create a QTApplication and a Datastorage
631  // This is necessary in order to save screenshots of
632  // each image / slice.
633  QApplication qtapplication(argc, argv);
635 
636  std::vector<mitk::AbstractGlobalImageFeature::FeatureListType> allStats;
637 
638  log << " Begin Processing -";
639  while (imageToProcess)
640  {
641  if (sliceWise)
642  {
643  cImage = floatVector[currentSlice];
644  cMask = maskVector[currentSlice];
645  cMaskNoNaN = maskNoNaNVector[currentSlice];
646  cMorphMask = morphMaskVector[currentSlice];
647  imageToProcess = (floatVector.size()-1 > (currentSlice)) ? true : false ;
648  }
649  else
650  {
651  imageToProcess = false;
652  }
653 
654  if (param.writePNGScreenshots)
655  {
656  SaveSliceOrImageAsPNG(cImage, cMask, param.pngScreenshotsPath, currentSlice);
657  }
658  if (param.writeAnalysisImage)
659  {
660  mitk::IOUtil::Save(cImage, param.anaylsisImagePath);
661  }
662  if (param.writeAnalysisMask)
663  {
664  mitk::IOUtil::Save(cMask, param.analysisMaskPath);
665  }
666 
668 
669  for (auto cFeature : features)
670  {
671  log << " Calculating " << cFeature->GetFeatureClassName() << " -";
672  cFeature->SetMorphMask(cMorphMask);
673  cFeature->CalculateFeaturesUsingParameters(cImage, cMask, cMaskNoNaN, stats);
674  }
675 
676  for (std::size_t i = 0; i < stats.size(); ++i)
677  {
678  std::cout << stats[i].first << " - " << stats[i].second << std::endl;
679  }
680 
681  writer.AddHeader(description, currentSlice, stats, param.useHeader, addDescription);
682  if (true)
683  {
685  writer.AddSubjectInformation(param.imageFolder);
686  writer.AddSubjectInformation(param.imageName);
687  writer.AddSubjectInformation(param.maskName);
688  }
689  writer.AddResult(description, currentSlice, stats, param.useHeader, addDescription);
690 
691  allStats.push_back(stats);
692  ++currentSlice;
693  }
694 
695  log << " Process Slicewise -";
696  if (sliceWise)
697  {
699  for (std::size_t i = 0; i < allStats[0].size(); ++i)
700  {
701  auto cElement1 = allStats[0][i];
702  cElement1.first = "SliceWise Mean " + cElement1.first;
703  cElement1.second = 0.0;
704  auto cElement2 = allStats[0][i];
705  cElement2.first = "SliceWise Var. " + cElement2.first;
706  cElement2.second = 0.0;
707  statMean.push_back(cElement1);
708  statStd.push_back(cElement2);
709  }
710 
711  for (auto cStat : allStats)
712  {
713  for (std::size_t i = 0; i < cStat.size(); ++i)
714  {
715  statMean[i].second += cStat[i].second / (1.0*allStats.size());
716  }
717  }
718 
719  for (auto cStat : allStats)
720  {
721  for (std::size_t i = 0; i < cStat.size(); ++i)
722  {
723  statStd[i].second += (cStat[i].second - statMean[i].second)*(cStat[i].second - statMean[i].second) / (1.0*allStats.size());
724  }
725  }
726 
727  for (std::size_t i = 0; i < statMean.size(); ++i)
728  {
729  std::cout << statMean[i].first << " - " << statMean[i].second << std::endl;
730  std::cout << statStd[i].first << " - " << statStd[i].second << std::endl;
731  }
732  if (true)
733  {
735  writer.AddSubjectInformation(param.imageFolder);
736  writer.AddSubjectInformation(param.imageName);
737  writer.AddSubjectInformation(param.maskName + " - Mean");
738  }
739  writer.AddResult(description, currentSlice, statMean, param.useHeader, addDescription);
740  if (true)
741  {
743  writer.AddSubjectInformation(param.imageFolder);
744  writer.AddSubjectInformation(param.imageName);
745  writer.AddSubjectInformation(param.maskName + " - Var.");
746  }
747  writer.AddResult(description, currentSlice, statStd, param.useHeader, addDescription);
748  }
749 
750  if (param.useLogfile)
751  {
752  log << "Finished calculation" << std::endl;
753  log.close();
754  }
755  return 0;
756 }
757 
758 #endif
virtual bool InitializeViews(const BaseGeometry *geometry, RequestType type=REQUEST_UPDATE_ALL, bool preserveRoughOrientationInWorldSpace=false)
void AddColumn(std::string value)
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
#define MITK_INFO
Definition: mitkLogMacros.h:18
void ResampleImage(itk::Image< TPixel, VImageDimension > *itkImage, float resolution, mitk::Image::Pointer &newImage)
vtkRenderer * GetVtkRenderer() const
itk::Image< unsigned char, 3 > ImageType
void SetDataStorage(mitk::DataStorage *storage) override
set the datastorage that will be used for rendering
Organizes the rendering process.
void setContributor(std::string contributor)
MITKQTWIDGETS_EXPORT void QmitkRegisterClasses()
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
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)
void AddResult(std::string desc, int slice, mitk::AbstractGlobalImageFeature::FeatureListType stats, bool, bool withDescription)
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
static void CreateNoNaNMask(itk::Image< TPixel, VImageDimension > *itkValue, mitk::Image::Pointer mask, mitk::Image::Pointer &newMask)
Image::Pointer GrabItkImageMemory(itk::SmartPointer< ItkOutputImageType > &itkimage, mitk::Image *mitkImage=nullptr, const BaseGeometry *geometry=nullptr, bool update=true)
Grabs the memory of an itk::Image (with a specific type) and puts it into an mitk::Image.The memory is managed by the mitk::Image after calling this function. The itk::Image remains valid until the mitk::Image decides to free the memory.
std::vector< std::pair< std::string, double > > FeatureListType
void AddSubjectInformation(std::string value)
static Pointer New()
static RenderingManager * GetInstance()
void AddHeader(std::string, int slice, mitk::AbstractGlobalImageFeature::FeatureListType stats, bool withHeader, bool withDescription)
Definition: usAny.h:163
MITK implementation of the QVTKWidget.
#define MITK_REVISION
Definition: mitkVersion.h:11
itk::Image< unsigned short, 3 > MaskImageType
virtual mitk::VtkPropRenderer * GetRenderer()
static void ResampleMask(itk::Image< TPixel, VImageDimension > *itkMoving, mitk::Image::Pointer ref, mitk::Image::Pointer &newMask)
void setCategory(std::string category)
mitk::Image::Pointer image
static Pointer New()
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
std::vector< double > MITKCLUTILITIES_EXPORT splitDouble(std::string str, char delimiter)
virtual void PrepareRender()
This methods contains all method neceassary before a VTK Render() call.
void ParseParameter(std::map< std::string, us::Any > parsedArgs)
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
static void ExtractSlicesFromImages(mitk::Image::Pointer image, mitk::Image::Pointer mask, mitk::Image::Pointer maskNoNaN, mitk::Image::Pointer morphMask, int direction, std::vector< mitk::Image::Pointer > &imageVector, std::vector< mitk::Image::Pointer > &maskVector, std::vector< mitk::Image::Pointer > &maskNoNaNVector, std::vector< mitk::Image::Pointer > &morphMaskVector)
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
static void Save(const mitk::BaseData *data, const std::string &path, bool setPathProperty=false)
Save a mitk::BaseData instance.
Definition: mitkIOUtil.cpp:774
mitk::Image::Pointer mask
virtual mitk::SliceNavigationController * GetSliceNavigationController()
vtkRenderWindow * GetVtkRenderWindow() override
static Pointer New()
#define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2)
void setTitle(std::string title)
void setDescription(std::string description)
itk::Image< double, 3 > FloatImageType
static void SaveSliceOrImageAsPNG(mitk::Image::Pointer image, mitk::Image::Pointer mask, std::string path, int index)
int main(int argc, char *argv[])