Medical Imaging Interaction Toolkit  2018.4.99-936b789b
Medical Imaging Interaction Toolkit
mitkGIFVolumetricDensityStatistics.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 #include <mitkPixelTypeMultiplex.h>
21 
22 // ITK
23 #include <itkLabelStatisticsImageFilter.h>
24 #include <itkNeighborhoodIterator.h>
25 #include <itkImageRegionConstIteratorWithIndex.h>
26 #include <itkLabelGeometryImageFilter.h>
27 
28 // VTK
29 #include <vtkSmartPointer.h>
30 #include <vtkImageMarchingCubes.h>
31 #include <vtkMassProperties.h>
32 #include <vtkDelaunay3D.h>
33 #include <vtkGeometryFilter.h>
34 #include <vtkDoubleArray.h>
35 #include <vtkPCAStatistics.h>
36 #include <vtkTable.h>
37 
38 // STL
39 #include <limits>
40 #include <vnl/vnl_math.h>
41 
42 // Eigen
43 #include <Eigen/Dense>
44 
45 struct GIFVolumetricDensityStatisticsParameters
46 {
47  double volume;
48  mitk::FeatureID id;
49 };
50 
51 template<typename TPixel, unsigned int VImageDimension>
52 void
53 CalculateVolumeDensityStatistic(const itk::Image<TPixel, VImageDimension>* itkImage, const mitk::Image* mask, GIFVolumetricDensityStatisticsParameters params, mitk::GIFVolumetricDensityStatistics::FeatureListType & featureList)
54 {
55  typedef itk::Image<TPixel, VImageDimension> ImageType;
56  typedef itk::Image<unsigned short, VImageDimension> MaskType;
57 
58  double volume = params.volume;
59 
60  typename MaskType::Pointer maskImage = MaskType::New();
61  mitk::CastToItkImage(mask, maskImage);
62 
63  itk::ImageRegionConstIteratorWithIndex<ImageType> imgA(itkImage, itkImage->GetLargestPossibleRegion());
64  itk::ImageRegionConstIteratorWithIndex<ImageType> imgB(itkImage, itkImage->GetLargestPossibleRegion());
65  itk::ImageRegionConstIteratorWithIndex<MaskType> maskA(maskImage, maskImage->GetLargestPossibleRegion());
66  itk::ImageRegionConstIteratorWithIndex<MaskType> maskB(maskImage, maskImage->GetLargestPossibleRegion());
67 
68  double moranA = 0;
69  double moranB = 0;
70  double geary = 0;
71  double Nv = 0;
72  double w_ij = 0;
73  double mean = 0;
74 
75  typename ImageType::PointType pointA;
76  typename ImageType::PointType pointB;
77 
78  while (!imgA.IsAtEnd())
79  {
80  if (maskA.Get() > 0)
81  {
82  Nv += 1;
83  mean += imgA.Get();
84  }
85  ++imgA;
86  ++maskA;
87  }
88  mean /= Nv;
89  imgA.GoToBegin();
90  maskA.GoToBegin();
91 
92  while (!imgA.IsAtEnd())
93  {
94  if (maskA.Get() > 0)
95  {
96  imgB.GoToBegin();
97  maskB.GoToBegin();
98  while (!imgB.IsAtEnd())
99  {
100  if ((imgA.GetIndex() == imgB.GetIndex()) ||
101  (maskB.Get() < 1))
102  {
103  ++imgB;
104  ++maskB;
105  continue;
106  }
107  itkImage->TransformIndexToPhysicalPoint(maskA.GetIndex(), pointA);
108  itkImage->TransformIndexToPhysicalPoint(maskB.GetIndex(), pointB);
109 
110  double w = 1 / pointA.EuclideanDistanceTo(pointB);
111  moranA += w*(imgA.Get() - mean)* (imgB.Get() - mean);
112  geary += w * (imgA.Get() - imgB.Get()) * (imgA.Get() - imgB.Get());
113 
114  w_ij += w;
115 
116  ++imgB;
117  ++maskB;
118  }
119  moranB += (imgA.Get() - mean)* (imgA.Get() - mean);
120  }
121  ++imgA;
122  ++maskA;
123  }
124 
125  MITK_INFO << "Volume: " << volume;
126  MITK_INFO << " Mean: " << mean;
127  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume integrated intensity"), volume* mean));
128  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume Moran's I index"), Nv / w_ij * moranA / moranB));
129  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume Geary's C measure"), ( Nv -1 ) / 2 / w_ij * geary/ moranB));
130 }
131 
132 void calculateMOBB(vtkPointSet *pointset, double &volume, double &surface)
133 {
135 
136  for (int cellID = 0; cellID < pointset->GetNumberOfCells(); ++cellID)
137  {
138  auto cell = pointset->GetCell(cellID);
139 
140  for (int edgeID = 0; edgeID < 3; ++edgeID)
141  {
142  auto edge = cell->GetEdge(edgeID);
143 
144  double pA[3], pB[3];
145  double pAA[3], pBB[3];
146 
147  vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
148  transform->PostMultiply();
149  pointset->GetPoint(edge->GetPointId(0), pA);
150  pointset->GetPoint(edge->GetPointId(1), pB);
151 
152  double angleZ = std::atan2((- pA[2] + pB[2]) ,(pA[1] - pB[1]));
153  angleZ *= 180 / vnl_math::pi;
154  if (pA[2] == pB[2])
155  angleZ = 0;
156 
157  transform->RotateX(angleZ);
158  transform->TransformPoint(pA, pAA);
159  transform->TransformPoint(pB, pBB);
160 
161  double angleY = std::atan2((pAA[1] -pBB[1]) ,-(pAA[0] - pBB[0]));
162  angleY *= 180 / vnl_math::pi;
163  if (pAA[1] == pBB[1])
164  angleY = 0;
165  transform->RotateZ(angleY);
166 
167  double p0[3];
168  pointset->GetPoint(edge->GetPointId(0), p0);
169 
170  double curMinX = std::numeric_limits<double>::max();
171  double curMaxX = std::numeric_limits<double>::lowest();
172  double curMinY = std::numeric_limits<double>::max();
173  double curMaxY = std::numeric_limits<double>::lowest();
174  double curMinZ = std::numeric_limits<double>::max();
175  double curMaxZ = std::numeric_limits<double>::lowest();
176  for (int pointID = 0; pointID < pointset->GetNumberOfPoints(); ++pointID)
177  {
178  double p[3];
179  double p2[3];
180  pointset->GetPoint(pointID, p);
181  p[0] -= p0[0]; p[1] -= p0[1]; p[2] -= p0[2];
182  transform->TransformPoint(p, p2);
183 
184  curMinX = std::min<double>(p2[0], curMinX);
185  curMaxX = std::max<double>(p2[0], curMaxX);
186  curMinY = std::min<double>(p2[1], curMinY);
187  curMaxY = std::max<double>(p2[1], curMaxY);
188  curMinZ = std::min<double>(p2[2], curMinZ);
189  curMaxZ = std::max<double>(p2[2], curMaxZ);
190  }
191 
192  if ((curMaxX - curMinX)*(curMaxY - curMinY)*(curMaxZ - curMinZ) < volume)
193  {
194  volume = (curMaxX - curMinX)*(curMaxY - curMinY)*(curMaxZ - curMinZ);
195  surface = (curMaxX - curMinX)*(curMaxX - curMinX) + (curMaxY - curMinY)*(curMaxY - curMinY) + (curMaxZ - curMinZ)*(curMaxZ - curMinZ);
196  surface *= 2;
197  }
198 
199 
200  }
201  }
202 }
203 
204 void calculateMEE(vtkPointSet *pointset, double &vol, double &surf, double tolerance=0.0001)
205 {
206  // Inspired by https://github.com/smdabdoub/ProkaryMetrics/blob/master/calc/fitting.py
207 
208  int numberOfPoints = pointset->GetNumberOfPoints();
209  int dimension = 3;
210  Eigen::MatrixXd points(3, numberOfPoints);
211  Eigen::MatrixXd Q(3+1, numberOfPoints);
212  double p[3];
213 
214  std::cout << "Initialize Q " << std::endl;
215  for (int i = 0; i < numberOfPoints; ++i)
216  {
217  pointset->GetPoint(i, p);
218  points(0, i) = p[0];
219  points(1, i) = p[1];
220  points(2, i) = p[2];
221  Q(0, i) = p[0];
222  Q(1, i) = p[1];
223  Q(2, i) = p[2];
224  Q(3, i) = 1.0;
225  }
226 
227  int count = 1;
228  double error = 1;
229  Eigen::VectorXd u_vector(numberOfPoints);
230  u_vector.fill(1.0 / numberOfPoints);
231  Eigen::DiagonalMatrix<double, Eigen::Dynamic> u = u_vector.asDiagonal();
232  Eigen::VectorXd ones(dimension + 1);
233  ones.fill(1);
234  Eigen::MatrixXd Ones = ones.asDiagonal();
235 
236  // Khachiyan Algorithm
237  while (error > tolerance)
238  {
239  auto Qt = Q.transpose();
240  Eigen::MatrixXd X = Q*u*Qt;
241  Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qr(X);
242  Eigen::MatrixXd Xi = qr.solve(Ones);
243 
244  Eigen::MatrixXd M = Qt * Xi * Q;
245 
246  double maximumValue = M(0, 0);
247  int maximumPosition = 0;
248  for (int i = 0; i < numberOfPoints; ++i)
249  {
250  if (maximumValue < M(i, i))
251  {
252  maximumValue = M(i, i);
253  maximumPosition = i;
254  }
255  }
256  double stepsize = (maximumValue - dimension - 1) / ((dimension + 1) * (maximumValue - 1));
257  Eigen::DiagonalMatrix<double, Eigen::Dynamic> new_u = (1.0 - stepsize) * u;
258  new_u.diagonal()[maximumPosition] = (new_u.diagonal())(maximumPosition) + stepsize;
259  ++count;
260  error = (new_u.diagonal() - u.diagonal()).norm();
261  u.diagonal() = new_u.diagonal();
262  }
263 
264  // U = u
265 
266  Eigen::MatrixXd Ai = points * u * points.transpose() - points * u *(points * u).transpose();
267  Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qr(Ai);
268  Eigen::VectorXd ones2(dimension);
269  ones2.fill(1);
270  Eigen::MatrixXd Ones2 = ones2.asDiagonal();
271  Eigen::MatrixXd A = qr.solve(Ones2)*1.0/dimension;
272 
273  Eigen::JacobiSVD<Eigen::MatrixXd> svd(A);
274  double c = 1 / sqrt(svd.singularValues()[0]);
275  double b = 1 / sqrt(svd.singularValues()[1]);
276  double a = 1 / sqrt(svd.singularValues()[2]);
277  double V = 4 * vnl_math::pi*a*b*c / 3;
278 
279  double ad_mvee= 0;
280  double alpha = std::sqrt(1 - b*b / a / a);
281  double beta = std::sqrt(1 - c*c / a / a);
282  for (int i = 0; i < 20; ++i)
283  {
284  ad_mvee += 4 * vnl_math::pi*a*b*(alpha*alpha + beta*beta) / (2 * alpha*beta) * (std::pow(alpha*beta, i)) / (1 - 4 * i*i);
285  }
286  vol = V;
287  surf = ad_mvee;
288 }
289 
291 {
292  SetLongName("volume-density");
293  SetShortName("volden");
294  SetFeatureClassName("Morphological Density");
295 }
296 
298 {
299  std::string name = GetOptionPrefix();
300 
301  parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Volume-Density Statistic", "calculates volume density based features", us::Any());
302 }
303 
305 {
306  FeatureListType featureList;
307 
308  if (image->GetDimension() < 3)
309  {
310  MITK_INFO << "Skipped calculating volumetric density features; only 3D images are supported ....";
311  return featureList;
312  }
313 
314  MITK_INFO << "Start calculating volumetric density features ....";
315 
316  vtkSmartPointer<vtkImageMarchingCubes> mesher = vtkSmartPointer<vtkImageMarchingCubes>::New();
317  vtkSmartPointer<vtkMassProperties> stats = vtkSmartPointer<vtkMassProperties>::New();
318  vtkSmartPointer<vtkMassProperties> stats2 = vtkSmartPointer<vtkMassProperties>::New();
319  auto nonconstVtkData = const_cast<vtkImageData*>(mask->GetVtkImageData());
320  mesher->SetInputData(nonconstVtkData);
321  mesher->SetValue(0, 0.5);
322  stats->SetInputConnection(mesher->GetOutputPort());
323  stats->Update();
324 
325  vtkSmartPointer<vtkDelaunay3D> delaunay =
326  vtkSmartPointer< vtkDelaunay3D >::New();
327  delaunay->SetInputConnection(mesher->GetOutputPort());
328  delaunay->SetAlpha(0);
329  delaunay->Update();
330  vtkSmartPointer<vtkGeometryFilter> geometryFilter =
331  vtkSmartPointer<vtkGeometryFilter>::New();
332  geometryFilter->SetInputConnection(delaunay->GetOutputPort());
333  geometryFilter->Update();
334  stats2->SetInputConnection(geometryFilter->GetOutputPort());
335  stats2->Update();
336 
337  double vol_mvee;
338  double surf_mvee;
339  calculateMEE(mesher->GetOutput(), vol_mvee, surf_mvee);
340 
341  double vol_mobb;
342  double surf_mobb;
343  calculateMOBB(geometryFilter->GetOutput(), vol_mobb, surf_mobb);
344 
345  double pi = vnl_math::pi;
346 
347  double meshVolume = stats->GetVolume();
348  double meshSurf = stats->GetSurfaceArea();
349 
350  GIFVolumetricDensityStatisticsParameters params;
351  params.volume = meshVolume;
352  params.id = this->CreateTemplateFeatureID();
353  AccessByItk_3(image, CalculateVolumeDensityStatistic, mask, params, featureList);
354 
355  //Calculate center of mass shift
356  int xx = mask->GetDimensions()[0];
357  int yy = mask->GetDimensions()[1];
358  int zz = mask->GetDimensions()[2];
359 
360  double xd = mask->GetGeometry()->GetSpacing()[0];
361  double yd = mask->GetGeometry()->GetSpacing()[1];
362  double zd = mask->GetGeometry()->GetSpacing()[2];
363 
364  int minimumX = xx;
365  int maximumX = 0;
366  int minimumY = yy;
367  int maximumY = 0;
368  int minimumZ = zz;
369  int maximumZ = 0;
370 
371  vtkSmartPointer<vtkDoubleArray> dataset1Arr = vtkSmartPointer<vtkDoubleArray>::New();
372  vtkSmartPointer<vtkDoubleArray> dataset2Arr = vtkSmartPointer<vtkDoubleArray>::New();
373  vtkSmartPointer<vtkDoubleArray> dataset3Arr = vtkSmartPointer<vtkDoubleArray>::New();
374  dataset1Arr->SetNumberOfComponents(1);
375  dataset2Arr->SetNumberOfComponents(1);
376  dataset3Arr->SetNumberOfComponents(1);
377  dataset1Arr->SetName("M1");
378  dataset2Arr->SetName("M2");
379  dataset3Arr->SetName("M3");
380 
381  vtkSmartPointer<vtkDoubleArray> dataset1ArrU = vtkSmartPointer<vtkDoubleArray>::New();
382  vtkSmartPointer<vtkDoubleArray> dataset2ArrU = vtkSmartPointer<vtkDoubleArray>::New();
383  vtkSmartPointer<vtkDoubleArray> dataset3ArrU = vtkSmartPointer<vtkDoubleArray>::New();
384  dataset1ArrU->SetNumberOfComponents(1);
385  dataset2ArrU->SetNumberOfComponents(1);
386  dataset3ArrU->SetNumberOfComponents(1);
387  dataset1ArrU->SetName("M1");
388  dataset2ArrU->SetName("M2");
389  dataset3ArrU->SetName("M3");
390 
391  vtkSmartPointer<vtkPoints> points =
392  vtkSmartPointer< vtkPoints >::New();
393 
394  for (int x = 0; x < xx; x++)
395  {
396  for (int y = 0; y < yy; y++)
397  {
398  for (int z = 0; z < zz; z++)
399  {
400  itk::Image<int, 3>::IndexType index;
401 
402  index[0] = x;
403  index[1] = y;
404  index[2] = z;
405 
406  mitk::ScalarType pxImage;
407  mitk::ScalarType pxMask;
408 
412  image,
413  image->GetVolumeData(),
414  index,
415  pxImage,
416  0);
417 
421  mask,
422  mask->GetVolumeData(),
423  index,
424  pxMask,
425  0);
426 
427  //Check if voxel is contained in segmentation
428  if (pxMask > 0)
429  {
430  minimumX = std::min<int>(x, minimumX);
431  minimumY = std::min<int>(y, minimumY);
432  minimumZ = std::min<int>(z, minimumZ);
433  maximumX = std::max<int>(x, maximumX);
434  maximumY = std::max<int>(y, maximumY);
435  maximumZ = std::max<int>(z, maximumZ);
436  points->InsertNextPoint(x * xd, y * yd, z * zd);
437 
438  if (pxImage == pxImage)
439  {
440  dataset1Arr->InsertNextValue(x * xd);
441  dataset2Arr->InsertNextValue(y * yd);
442  dataset3Arr->InsertNextValue(z * zd);
443  }
444  }
445  }
446  }
447  }
448 
449  vtkSmartPointer<vtkTable> datasetTable = vtkSmartPointer<vtkTable>::New();
450  datasetTable->AddColumn(dataset1Arr);
451  datasetTable->AddColumn(dataset2Arr);
452  datasetTable->AddColumn(dataset3Arr);
453 
454  vtkSmartPointer<vtkPCAStatistics> pcaStatistics = vtkSmartPointer<vtkPCAStatistics>::New();
455  pcaStatistics->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, datasetTable);
456  pcaStatistics->SetColumnStatus("M1", 1);
457  pcaStatistics->SetColumnStatus("M2", 1);
458  pcaStatistics->SetColumnStatus("M3", 1);
459  pcaStatistics->RequestSelectedColumns();
460  pcaStatistics->SetDeriveOption(true);
461  pcaStatistics->Update();
462 
463  vtkSmartPointer<vtkDoubleArray> eigenvalues = vtkSmartPointer<vtkDoubleArray>::New();
464  pcaStatistics->GetEigenvalues(eigenvalues);
465 
466  std::vector<double> eigen_val(3);
467  eigen_val[2] = eigenvalues->GetValue(0);
468  eigen_val[1] = eigenvalues->GetValue(1);
469  eigen_val[0] = eigenvalues->GetValue(2);
470 
471  double major = 2 * sqrt(eigen_val[2]);
472  double minor = 2 * sqrt(eigen_val[1]);
473  double least = 2 * sqrt(eigen_val[0]);
474 
475  double alpha = std::sqrt(1 - minor * minor / major / major);
476  double beta = std::sqrt(1 - least * least / major / major);
477 
478  double a = (maximumX - minimumX + 1) * xd;
479  double b = (maximumY - minimumY + 1) * yd;
480  double c = (maximumZ - minimumZ + 1) * zd;
481 
482  double vd_aabb = meshVolume / (a * b * c);
483  double ad_aabb = meshSurf / (2 * a * b + 2 * a * c + 2 * b * c);
484 
485  double vd_aee = 3 * meshVolume / (4.0 * pi * major * minor * least);
486  double ad_aee = 0;
487  for (int i = 0; i < 20; ++i)
488  {
489  ad_aee += 4 * pi * major * minor * (alpha * alpha + beta * beta) / (2 * alpha * beta) * (std::pow(alpha * beta, i)) / (1 - 4 * i * i);
490  }
491  ad_aee = meshSurf / ad_aee;
492 
493  double vd_ch = meshVolume / stats2->GetVolume();
494  double ad_ch = meshSurf / stats2->GetSurfaceArea();
495 
496  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density axis-aligned bounding box"), vd_aabb));
497  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density axis-aligned bounding box"), ad_aabb));
498  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density oriented minimum bounding box"), meshVolume / vol_mobb));
499  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density oriented minimum bounding box"), meshSurf / surf_mobb));
500  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density approx. enclosing ellipsoid"), vd_aee));
501  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density approx. enclosing ellipsoid"), ad_aee));
502  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density approx. minimum volume enclosing ellipsoid"), meshVolume / vol_mvee));
503  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density approx. minimum volume enclosing ellipsoid"), meshSurf / surf_mvee));
504  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density convex hull"), vd_ch));
505  featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density convex hull"), ad_ch));
506 
507  MITK_INFO << "Finished calculating volumetric density features....";
508 
509  return featureList;
510 }
511 
513 {
514  return Superclass::CalculateFeatures(image, mask);
515 }
mitk::ScalarType FastSinglePixelAccess(mitk::PixelType, mitk::Image::Pointer im, ImageDataItem *item, itk::Index< 3 > idx, mitk::ScalarType &val, int component=0)
#define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3)
void calculateMEE(vtkPointSet *pointset, double &vol, double &surf, double tolerance=0.0001)
#define MITK_INFO
Definition: mitkLogMacros.h:18
itk::Image< unsigned char, 3 > ImageType
double ScalarType
unsigned int * GetDimensions() const
Get the sizes of all dimensions as an integer-array.
Definition: mitkImage.cpp:1309
MITKCLCORE_EXPORT FeatureID CreateFeatureID(FeatureID templateID, std::string name)
virtual vtkImageData * GetVtkImageData(int t=0, int n=0)
Get a volume at a specific time t of channel n as a vtkImageData.
Definition: mitkImage.cpp:217
FeatureListType CalculateFeatures(const Image *image, const Image *mask, const Image *maskNoNAN) override
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 calculateMOBB(vtkPointSet *pointset, double &volume, double &surface)
ChannelDescriptor GetChannelDescriptor(int id=0) const
Definition: mitkImage.h:529
PixelType GetPixelType() const
Get the type of channel&#39;s elements.
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:106
FeatureListType DoCalculateFeatures(const Image *image, const Image *mask) override
virtual ImageDataItemPointer GetVolumeData(int t=0, int n=0, void *data=nullptr, ImportMemoryManagementType importMemoryManagement=CopyMemory) const
Definition: mitkImage.cpp:326
Image class for storing images.
Definition: mitkImage.h:72
Definition: usAny.h:163
std::vector< std::pair< FeatureID, double > > FeatureListType
static T max(T x, T y)
Definition: svm.cpp:56
mitk::Image::Pointer image
void CalculateVolumeDensityStatistic(const itk::Image< TPixel, VImageDimension > *itkImage, const mitk::Image *mask, GIFVolumetricDensityStatisticsParameters params, mitk::GIFVolumetricDensityStatistics::FeatureListType &featureList)
void AddArguments(mitkCommandLineParser &parser) const override
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
mitk::Image::Pointer mask
#define mitkPixelTypeMultiplex5(function, ptype, param1, param2, param3, param4, param5)
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:143
void CalculateFeatures(mitk::CoocurenceMatrixHolder &holder, mitk::CoocurenceMatrixFeatures &results)