diff --git a/Modules/Classification/CLUtilities/files.cmake b/Modules/Classification/CLUtilities/files.cmake index 17b04b392f..64e037b845 100644 --- a/Modules/Classification/CLUtilities/files.cmake +++ b/Modules/Classification/CLUtilities/files.cmake @@ -1,38 +1,39 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkCLResultWritter.cpp Algorithms/itkLabelSampler.cpp Algorithms/itkSmoothedClassProbabilites.cpp Algorithms/mitkRandomImageSampler.cpp Features/itkNeighborhoodFunctorImageFilter.cpp Features/itkLineHistogramBasedMassImageFilter.cpp GlobalImageFeatures/mitkGIFCooccurenceMatrix.cpp GlobalImageFeatures/mitkGIFCooccurenceMatrix2.cpp GlobalImageFeatures/mitkGIFGreyLevelRunLength.cpp GlobalImageFeatures/mitkGIFImageDescriptionFeatures.cpp GlobalImageFeatures/mitkGIFFirstOrderStatistics.cpp GlobalImageFeatures/mitkGIFFirstOrderHistogramStatistics.cpp + GlobalImageFeatures/mitkGIFFirstOrderNumericStatistics.cpp GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp GlobalImageFeatures/mitkGIFNeighbouringGreyLevelDependenceFeatures.cpp GlobalImageFeatures/mitkGIFNeighbourhoodGreyLevelDifference.cpp GlobalImageFeatures/mitkGIFGreyLevelSizeZone.cpp GlobalImageFeatures/mitkGIFGreyLevelDistanceZone.cpp GlobalImageFeatures/mitkGIFLocalIntensity.cpp GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp GlobalImageFeatures/mitkGIFIntensityVolumeHistogramFeatures.cpp GlobalImageFeatures/mitkGIFNeighbourhoodGreyToneDifferenceFeatures.cpp GlobalImageFeatures/mitkGIFCurvatureStatistic.cpp MiniAppUtils/mitkGlobalImageFeaturesParameter.cpp MiniAppUtils/mitkSplitParameterToVector.cpp mitkCLUtil.cpp ) set( TOOL_FILES ) diff --git a/Modules/Classification/CLUtilities/include/mitkGIFFirstOrderNumericStatistics.h b/Modules/Classification/CLUtilities/include/mitkGIFFirstOrderNumericStatistics.h new file mode 100644 index 0000000000..0a85b0e04b --- /dev/null +++ b/Modules/Classification/CLUtilities/include/mitkGIFFirstOrderNumericStatistics.h @@ -0,0 +1,164 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkGIFFirstOrderStatistics_h +#define mitkGIFFirstOrderStatistics_h + +#include +#include +#include + +namespace mitk +{ + class MITKCLUTILITIES_EXPORT GIFFirstOrderNumericStatistics : public AbstractGlobalImageFeature + { + public: + /** + * \brief Calculates first order statistics of the given image. + * + * The first order statistics for the intensity distribution within a given Region of Interest (ROI) + * is caluclated. The ROI is defined using a mask. + * + * The features are calculated on a quantified image. If the bin-size is too big, the obtained values + * can be errornous and missleading. It is therefore important to use enough bins. The binned approach is + * used in order to avoid floating-point related errors. + * + * This feature calculator is activated by the option -first-order or -fo. + * + * The connected areas are based on the binned image, the binning parameters can be set via the default + * parameters as described in AbstractGlobalImageFeature. It is also possible to determine the + * dimensionality of the neighbourhood using direction-related commands as described in AbstractGlobalImageFeature. + * No other options are possible beside these two options. + * + * The features are calculated based on a mask. It is assumed that the mask is + * of the type of an unsigned short image. All voxels with the value 1 are treated as masked. + * + * The following features are then defined using the (binned) voxel intensity \f$ x_i \f$ of each voxel, the probability + * an intensity \f$ p_x \f$, and the overall number of voxels within the mask \f$ N_v \f$: + * - First Order::Mean: The mean intensity within the ROI + * \f[ \textup{Mean}= \mu = \frac{1}{N_v} \sum x_i \f] + * - First Order::Unbiased Variance: An unbiased estimation of the variance: + * \f[ \textup{Unbiased Variance} = \frac{1}{N_v - 1} \sum \left( x_i - \mu \right)^2 \f] + * - First Order::Biased Variance: An biased estimation of the variance. If not specified otherwise, this is + * used as the variance: + * \f[ \textup{Biased Variance} = \sigma^2 = \frac{1}{N_v} \sum \left( x_i - \mu \right)^2 \f] + * - First Order::Unbiased Standard Deviation: Estimation of diversity within the intensity values + * \f[ \textup{Unbiased Standard Deviation} = \sqrt{\frac{1}{N_v-1} \sum \left( x_i - \mu \right)^2} \f] + * - First Order::Biased Standard Deviation: Estimation of diversity within the intensity values + * \f[ \textup{Biased Standard Deviation} = \sigma = \sqrt{\frac{1}{N_v} \sum \left( x_i - \mu \right)^2} \f] + * - First Order::Skewness: + * \f[ \textup{Skewness} = \frac{\frac{1}{N_v} \sum \left( x_i - \mu \right)^3}{\sigma^3} \f] + * - First Order::Kurtosis: The kurtosis is a measurement of the peakness of the given + * distirbution: + * \f[ \textup{Kurtosis} = \frac{\frac{1}{N_v} \sum \left( x_i - \mu \right)^4}{\sigma^4} \f] + * - First Order::Excess Kurtosis: The kurtosis is a measurement of the peakness of the given + * distirbution. The excess kurtosis is similar to the kurtosis, but is corrected by a fisher correction, + * ensuring that a gaussian distribution has an excess kurtosis of 0. + * \f[ \textup{Excess Kurtosis} = \frac{\frac{1}{N_v} \sum \left( x_i - \mu \right)^4}{\sigma^4} - 3 \f] + * - First Order::Median: The median is defined as the median of the all intensities in the ROI. + * - First Order::Minimum: The minimum is defined as the minimum of the all intensities in the ROI. + * - First Order::05th Percentile: \f$ P_{5\%} \f$ The 5% percentile. 5% of all voxel do have this or a lower intensity. + * - First Order::10th Percentile: \f$ P_{10\%} \f$ The 10% percentile. 10% of all voxel do have this or a lower intensity. + * - First Order::15th Percentile: \f$ P_{15\%} \f$ The 15% percentile. 15% of all voxel do have this or a lower intensity. + * - First Order::20th Percentile: \f$ P_{20\%} \f$ The 20% percentile. 20% of all voxel do have this or a lower intensity. + * - First Order::25th Percentile: \f$ P_{25\%} \f$ The 25% percentile. 25% of all voxel do have this or a lower intensity. + * - First Order::30th Percentile: \f$ P_{30\%} \f$ The 30% percentile. 30% of all voxel do have this or a lower intensity. + * - First Order::35th Percentile: \f$ P_{35\%} \f$ The 35% percentile. 35% of all voxel do have this or a lower intensity. + * - First Order::40th Percentile: \f$ P_{40\%} \f$ The 40% percentile. 40% of all voxel do have this or a lower intensity. + * - First Order::45th Percentile: \f$ P_{45\%} \f$ The 45% percentile. 45% of all voxel do have this or a lower intensity. + * - First Order::50th Percentile: \f$ P_{50\%} \f$ The 50% percentile. 50% of all voxel do have this or a lower intensity. + * - First Order::55th Percentile: \f$ P_{55\%} \f$ The 55% percentile. 55% of all voxel do have this or a lower intensity. + * - First Order::60th Percentile: \f$ P_{60\%} \f$ The 60% percentile. 60% of all voxel do have this or a lower intensity. + * - First Order::65th Percentile: \f$ P_{65\%} \f$ The 65% percentile. 65% of all voxel do have this or a lower intensity. + * - First Order::70th Percentile: \f$ P_{70\%} \f$ The 70% percentile. 70% of all voxel do have this or a lower intensity. + * - First Order::75th Percentile: \f$ P_{75\%} \f$ The 75% percentile. 75% of all voxel do have this or a lower intensity. + * - First Order::80th Percentile: \f$ P_{80\%} \f$ The 80% percentile. 80% of all voxel do have this or a lower intensity. + * - First Order::85th Percentile: \f$ P_{85\%} \f$ The 85% percentile. 85% of all voxel do have this or a lower intensity. + * - First Order::90th Percentile: \f$ P_{90\%} \f$ The 90% percentile. 90% of all voxel do have this or a lower intensity. + * - First Order::95th Percentile: \f$ P_{95\%} \f$ The 95% percentile. 95% of all voxel do have this or a lower intensity. + * - First Order::Maximum: The maximum is defined as the minimum of the all intensities in the ROI. + * - First Order::Range: The range of intensity values is defined as the difference between the maximum + * and minimum intensity in the ROI. + * - First Order::Interquartile Range: The difference between the 75% and 25% quantile. + * - First Order::Mean Absolute Deviation: The mean absolute deviation gives the mean distance of each + * voxel intensity to the overal mean intensity and is a measure of the dispersion of the intensity form the + * mean value: + * \f[ \textup{Mean Absolute Deviation} = \frac{1}{N_v} \sum \left \| x_i - \mu \right \| \f] + * - First Order::Robust Mean: The mean intensity within the ROI for all voxels between the 10% and 90% quantile: + * \f[ \textup{Robust Mean}= \mu_R = \frac{1}{N_{vr}} \sum x_i \f] + * - First Order::Robust Mean Absolute Deviation: The absolute deviation of all intensities within the ROI for + * all voxels between the 10% and 90% quantilefrom the robust mean intensity: + * \f[ \textup{Robust Mean Absolute Deviation}= \mu_R = \frac{1}{N_{vr}} \sum \left \| x_i - \mu_R \right \| \f] + * - First Order::Median Absolute Deviation: Similar to the mean absolute deviation, but uses the median + * instead of the mean to measure the center of the distribution. + * - First Order::Coefficient Of Variation: Measures the dispersion of the intensity distribution: + * \f[ \textup{Coefficient Of Variation} = \frac{sigma}{\mu} \f] + * - First Order::Quantile Coefficient Of Dispersion: A robust alternative to teh coefficient of variance: + * \f[ \textup{Quantile Coefficient Of Dispersion} = \frac{P_{75\%} - P_{25\%} }{P_{75\%} + P_{25\%}} \f] + * - First Order::Energy: The intensity energy: + * \f[ \textup{Energy} = \sum x_i ^2 \f] + * - First Order::Root Mean Square: Root mean square is an important measure for the error. + * \f[ \textup{Root Mean Square} = \sqrt{\frac{\sum x_i ^2}{N_v}} \f] + * - First Order::Uniformity: + * \f[ \textup{Uniformity} = \sum p_x^2 \f] + * - First Order::Entropy: + * \f[ \textup{Entropy} = - \sum p_x \textup{log}_2(p_x) \f] + * - First Order::Entropy: + * \f[ \textup{Entropy} = - \sum p_x \textup{log}_2(p_x) \f] + * - First Order::Covered Image Intensity Range: Percentage of the image intensity range (maximum - minimum in whole + * image) that is covered by the ROI. + * - First Order::Sum: The sum of all intensities. It is correlated to the mean intensity. + * \f[ \textup{Sum} = \sum x_i \f] + * - First Order::Mode: The most common intensity. + * - First Order::Mode Probability: The likelihood of the most common intensity. + * - First Order::Number Of Voxels: \f$ N_v \f$ the number of voxels covered by the ROI. + * - First Order::Image Dimension: The dimensionality of the image (e.g. 2D, 3D, etc.). + * - First Order::Number Of Voxels: The product of all spacing along all dimensions. In 3D, this is equal to the + * volume. + * - First Order::Number Of Voxels: The volume of a single voxel. If the dimensionality is only 2D, this is the + * surface of an voxel. + */ + mitkClassMacro(GIFFirstOrderNumericStatistics,AbstractGlobalImageFeature) + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + GIFFirstOrderNumericStatistics(); + + /** + * \brief Calculates the First Order Features based on a binned version of the image. + */ + FeatureListType CalculateFeatures(const Image::Pointer & image, const Image::Pointer &feature) override; + + /** + * \brief Returns a list of the names of all features that are calculated from this class + */ + FeatureNameListType GetFeatureNames() override; + virtual std::string GetCurrentFeatureEncoding() override; + + virtual void CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &maskNoNAN, FeatureListType &featureList); + virtual void AddArguments(mitkCommandLineParser &parser); + + + struct ParameterStruct { + double MinimumIntensity; + double MaximumIntensity; + int Bins; + std::string prefix; + }; + + }; +} +#endif //mitkGIFFirstOrderStatistics_h diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFFirstOrderNumericStatistics.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFFirstOrderNumericStatistics.cpp new file mode 100644 index 0000000000..a173f9a588 --- /dev/null +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFFirstOrderNumericStatistics.cpp @@ -0,0 +1,327 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include + +// MITK +#include +#include +#include + +// ITK +#include +#include + +// STL +#include + +template +void +CalculateFirstOrderStatistics(itk::Image* itkImage, mitk::Image::Pointer mask, mitk::GIFFirstOrderNumericStatistics::FeatureListType & featureList, mitk::GIFFirstOrderNumericStatistics::ParameterStruct params) +{ + typedef itk::Image ImageType; + typedef itk::Image MaskType; + typedef itk::LabelStatisticsImageFilter FilterType; + typedef typename FilterType::HistogramType HistogramType; + typedef typename HistogramType::IndexType HIndexType; + typedef itk::MinimumMaximumImageCalculator MinMaxComputerType; + + typename MaskType::Pointer maskImage = MaskType::New(); + mitk::CastToItkImage(mask, maskImage); + + double voxelVolume = 1; + for (unsigned int i = 0; i < std::min(3, VImageDimension); ++i) + voxelVolume *= itkImage->GetSpacing()[i]; + double voxelSpace = 1; + for (unsigned int i = 0; i < VImageDimension; ++i) + voxelSpace *= itkImage->GetSpacing()[i]; + + typename MinMaxComputerType::Pointer minMaxComputer = MinMaxComputerType::New(); + minMaxComputer->SetImage(itkImage); + minMaxComputer->Compute(); + double imageRange = minMaxComputer->GetMaximum() - minMaxComputer->GetMinimum(); + + typename FilterType::Pointer labelStatisticsImageFilter = FilterType::New(); + labelStatisticsImageFilter->SetInput( itkImage ); + labelStatisticsImageFilter->SetLabelInput(maskImage); + labelStatisticsImageFilter->SetUseHistograms(true); + + double min = params.MinimumIntensity; + double max = params.MaximumIntensity; + + labelStatisticsImageFilter->SetHistogramParameters(params.Bins, min,max); + labelStatisticsImageFilter->Update(); + + // --------------- Range -------------------- + double range = labelStatisticsImageFilter->GetMaximum(1) - labelStatisticsImageFilter->GetMinimum(1); + // --------------- Uniformity, Entropy -------------------- + double count = labelStatisticsImageFilter->GetCount(1); + //double std_dev = labelStatisticsImageFilter->GetSigma(1); + double mean = labelStatisticsImageFilter->GetMean(1); + double median = labelStatisticsImageFilter->GetMedian(1); + auto histogram = labelStatisticsImageFilter->GetHistogram(1); + bool histogramIsCalculated = histogram; + + HIndexType index; + index.SetSize(1); + + double uniformity = 0; + double entropy = 0; + double squared_sum = 0; + double kurtosis = 0; + double mean_absolut_deviation = 0; + double median_absolut_deviation = 0; + double skewness = 0; + double sum_prob = 0; + double binWidth = 0; + double p05th = 0, p10th = 0, p15th = 0, p20th = 0, p25th = 0, p30th = 0, p35th = 0, p40th = 0, p45th = 0, p50th = 0; + double p55th = 0, p60th = 0, p65th = 0, p70th = 0, p75th = 0, p80th = 0, p85th = 0, p90th = 0, p95th = 0; + + double voxelValue = 0; + + if (histogramIsCalculated) + { + binWidth = histogram->GetBinMax(0, 0) - histogram->GetBinMin(0, 0); + p05th = histogram->Quantile(0, 0.05); + p10th = histogram->Quantile(0, 0.10); + p15th = histogram->Quantile(0, 0.15); + p20th = histogram->Quantile(0, 0.20); + p25th = histogram->Quantile(0, 0.25); + p30th = histogram->Quantile(0, 0.30); + p35th = histogram->Quantile(0, 0.35); + p40th = histogram->Quantile(0, 0.40); + p45th = histogram->Quantile(0, 0.45); + p50th = histogram->Quantile(0, 0.50); + p55th = histogram->Quantile(0, 0.55); + p60th = histogram->Quantile(0, 0.60); + p65th = histogram->Quantile(0, 0.65); + p70th = histogram->Quantile(0, 0.70); + p75th = histogram->Quantile(0, 0.75); + p80th = histogram->Quantile(0, 0.80); + p85th = histogram->Quantile(0, 0.85); + p90th = histogram->Quantile(0, 0.90); + p95th = histogram->Quantile(0, 0.95); + } + double Log2=log(2); + double mode_bin; + double mode_value = 0; + double variance = 0; + if (histogramIsCalculated) + { + for (int i = 0; i < (int)(histogram->GetSize(0)); ++i) + { + index[0] = i; + double prob = histogram->GetFrequency(index); + + + if (prob < 0.00000001) + continue; + + voxelValue = histogram->GetBinMin(0, i) + binWidth * 0.5; + + if (prob > mode_value) + { + mode_value = prob; + mode_bin = voxelValue; + } + + sum_prob += prob; + squared_sum += prob * voxelValue*voxelValue; + + prob /= count; + mean_absolut_deviation += prob* std::abs(voxelValue - mean); + median_absolut_deviation += prob* std::abs(voxelValue - median); + variance += prob * (voxelValue - mean) * (voxelValue - mean); + + kurtosis += prob* (voxelValue - mean) * (voxelValue - mean) * (voxelValue - mean) * (voxelValue - mean); + skewness += prob* (voxelValue - mean) * (voxelValue - mean) * (voxelValue - mean); + + uniformity += prob*prob; + if (prob > 0) + { + entropy += prob * std::log(prob) / Log2; + } + } + } + entropy = -entropy; + + double uncorrected_std_dev = std::sqrt(variance); + double rms = std::sqrt(squared_sum / count); + kurtosis = kurtosis / (variance * variance); + skewness = skewness / (variance * uncorrected_std_dev); + double coveredGrayValueRange = range / imageRange; + double coefficient_of_variation = (mean == 0) ? 0 : std::sqrt(variance) / mean; + double quantile_coefficient_of_dispersion = (p75th - p25th) / (p75th + p25th); + + //Calculate the robust mean absolute deviation + //First, set all frequencies to 0 that are <10th or >90th percentile + double meanRobust = 0.0; + double robustMeanAbsoluteDeviation = 0.0; + if (histogramIsCalculated) + { + for (int i = 0; i < (int)(histogram->GetSize(0)); ++i) + { + index[0] = i; + if (histogram->GetBinMax(0, i) < p10th) + { + histogram->SetFrequencyOfIndex(index, 0); + } + else if (histogram->GetBinMin(0, i) > p90th) + { + histogram->SetFrequencyOfIndex(index, 0); + } + } + + //Calculate the mean + for (int i = 0; i < (int)(histogram->GetSize(0)); ++i) + { + index[0] = i; + meanRobust += histogram->GetFrequency(index) * 0.5 * (histogram->GetBinMin(0, i) + histogram->GetBinMax(0, i)); + } + meanRobust = meanRobust / histogram->GetTotalFrequency(); + for (int i = 0; i < (int)(histogram->GetSize(0)); ++i) + { + index[0] = i; + robustMeanAbsoluteDeviation += std::abs(histogram->GetFrequency(index) * + ((0.5 * (histogram->GetBinMin(0, i) + histogram->GetBinMax(0, i))) + - meanRobust + )); + } + robustMeanAbsoluteDeviation = robustMeanAbsoluteDeviation / histogram->GetTotalFrequency(); + } + + featureList.push_back(std::make_pair(params.prefix + "Mean", labelStatisticsImageFilter->GetMean(1))); + featureList.push_back(std::make_pair(params.prefix + "Unbiased Variance", labelStatisticsImageFilter->GetVariance(1))); //Siehe Definition von Unbiased Variance estimation. (Wird nicht durch n sondern durch n-1 normalisiert) + featureList.push_back(std::make_pair(params.prefix + "Biased Variance", variance)); + featureList.push_back(std::make_pair(params.prefix + "Skewness", skewness)); + featureList.push_back(std::make_pair(params.prefix + "Kurtosis", kurtosis)); + featureList.push_back(std::make_pair(params.prefix + "Median", labelStatisticsImageFilter->GetMedian(1))); + featureList.push_back(std::make_pair(params.prefix + "Minimum", labelStatisticsImageFilter->GetMinimum(1))); + featureList.push_back(std::make_pair(params.prefix + "Maximum", labelStatisticsImageFilter->GetMaximum(1))); + featureList.push_back(std::make_pair(params.prefix + "Range", range)); + featureList.push_back(std::make_pair(params.prefix + "Mean Absolute Deviation", mean_absolut_deviation)); + featureList.push_back(std::make_pair(params.prefix + "Robust Mean Absolute Deviation", robustMeanAbsoluteDeviation)); + featureList.push_back(std::make_pair(params.prefix + "Median Absolute Deviation", median_absolut_deviation)); + featureList.push_back(std::make_pair(params.prefix + "Coefficient Of Variation", coefficient_of_variation)); + featureList.push_back(std::make_pair(params.prefix + "Quantile Coefficient Of Dispersion", quantile_coefficient_of_dispersion)); + featureList.push_back(std::make_pair(params.prefix + "Energy", squared_sum)); + featureList.push_back(std::make_pair(params.prefix + "Root Mean Square", rms)); + + typename HistogramType::MeasurementVectorType mv(1); + mv[0] = 0; + typename HistogramType::IndexType resultingIndex; + histogram->GetIndex(mv, resultingIndex); + featureList.push_back(std::make_pair(params.prefix + "Robust Mean", meanRobust)); + featureList.push_back(std::make_pair(params.prefix + "Uniformity", uniformity)); + featureList.push_back(std::make_pair(params.prefix + "Entropy", entropy)); + featureList.push_back(std::make_pair(params.prefix + "Excess Kurtosis", kurtosis - 3)); + featureList.push_back(std::make_pair(params.prefix + "Covered Image Intensity Range", coveredGrayValueRange)); + featureList.push_back(std::make_pair(params.prefix + "Sum", labelStatisticsImageFilter->GetSum(1))); + featureList.push_back(std::make_pair(params.prefix + "Mode", mode_bin)); + featureList.push_back(std::make_pair(params.prefix + "Mode Probability", mode_value)); + featureList.push_back(std::make_pair(params.prefix + "Unbiased Standard deviation", labelStatisticsImageFilter->GetSigma(1))); + featureList.push_back(std::make_pair(params.prefix + "Biased Standard deviation", sqrt(variance))); + featureList.push_back(std::make_pair(params.prefix + "Number Of Voxels", labelStatisticsImageFilter->GetCount(1))); + + featureList.push_back(std::make_pair(params.prefix + "05th Percentile", p05th)); + featureList.push_back(std::make_pair(params.prefix + "10th Percentile", p10th)); + featureList.push_back(std::make_pair(params.prefix + "15th Percentile", p15th)); + featureList.push_back(std::make_pair(params.prefix + "20th Percentile", p20th)); + featureList.push_back(std::make_pair(params.prefix + "25th Percentile", p25th)); + featureList.push_back(std::make_pair(params.prefix + "30th Percentile", p30th)); + featureList.push_back(std::make_pair(params.prefix + "35th Percentile", p35th)); + featureList.push_back(std::make_pair(params.prefix + "40th Percentile", p40th)); + featureList.push_back(std::make_pair(params.prefix + "45th Percentile", p45th)); + featureList.push_back(std::make_pair(params.prefix + "50th Percentile", p50th)); + featureList.push_back(std::make_pair(params.prefix + "55th Percentile", p55th)); + featureList.push_back(std::make_pair(params.prefix + "60th Percentile", p60th)); + featureList.push_back(std::make_pair(params.prefix + "65th Percentile", p65th)); + featureList.push_back(std::make_pair(params.prefix + "70th Percentile", p70th)); + featureList.push_back(std::make_pair(params.prefix + "75th Percentile", p75th)); + featureList.push_back(std::make_pair(params.prefix + "80th Percentile", p80th)); + featureList.push_back(std::make_pair(params.prefix + "85th Percentile", p85th)); + featureList.push_back(std::make_pair(params.prefix + "90th Percentile", p90th)); + featureList.push_back(std::make_pair(params.prefix + "95th Percentile", p95th)); + featureList.push_back(std::make_pair(params.prefix + "Interquartile Range", (p75th - p25th))); + featureList.push_back(std::make_pair(params.prefix + "Image Dimension", VImageDimension)); + featureList.push_back(std::make_pair(params.prefix + "Voxel Space", voxelSpace)); + featureList.push_back(std::make_pair(params.prefix + "Voxel Volume", voxelVolume)); +} + +mitk::GIFFirstOrderNumericStatistics::GIFFirstOrderNumericStatistics() +{ + SetShortName("fon"); + SetLongName("first-order-numeric"); + SetFeatureClassName("First Order Numeric"); +} + +mitk::GIFFirstOrderNumericStatistics::FeatureListType mitk::GIFFirstOrderNumericStatistics::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) +{ + InitializeQuantifier(image, mask); + FeatureListType featureList; + + ParameterStruct params; + + params.MinimumIntensity = GetQuantifier()->GetMinimum(); + params.MaximumIntensity = GetQuantifier()->GetMaximum(); + params.Bins = GetQuantifier()->GetBins(); + params.prefix = FeatureDescriptionPrefix(); + AccessByItk_3(image, CalculateFirstOrderStatistics, mask, featureList, params); + + return featureList; +} + +mitk::GIFFirstOrderNumericStatistics::FeatureNameListType mitk::GIFFirstOrderNumericStatistics::GetFeatureNames() +{ + FeatureNameListType featureList; + featureList.push_back("First Order::Minimum"); + featureList.push_back("First Order::Maximum"); + featureList.push_back("First Order::Mean"); + featureList.push_back("First Order::Variance"); + featureList.push_back("First Order::Sum"); + featureList.push_back("First Order::Median"); + featureList.push_back("First Order::Standard deviation"); + featureList.push_back("First Order::No. of Voxel"); + return featureList; +} + + +void mitk::GIFFirstOrderNumericStatistics::AddArguments(mitkCommandLineParser &parser) +{ + std::string name = GetOptionPrefix(); + + parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use First Order Statistic (Numeric)", "calculates First Order Statistic (Numeric)", us::Any()); + AddQuantifierArguments(parser); +} + +void +mitk::GIFFirstOrderNumericStatistics::CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &, const Image::Pointer &maskNoNAN, FeatureListType &featureList) +{ + auto parsedArgs = GetParameter(); + if (parsedArgs.count(GetLongName())) + { + InitializeQuantifierFromParameters(feature, maskNoNAN); + MITK_INFO << "Start calculating first order features ...."; + auto localResults = this->CalculateFeatures(feature, maskNoNAN); + featureList.insert(featureList.end(), localResults.begin(), localResults.end()); + MITK_INFO << "Finished calculating first order features...."; + } +} + +std::string mitk::GIFFirstOrderNumericStatistics::GetCurrentFeatureEncoding() +{ + return QuantifierParameterString(); +} \ No newline at end of file