diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFFirstOrderStatistics.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFFirstOrderStatistics.cpp index eb687dee6a..9a7b7f0999 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFFirstOrderStatistics.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFFirstOrderStatistics.cpp @@ -1,213 +1,214 @@ /*=================================================================== 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::GIFFirstOrderStatistics::FeatureListType & featureList, mitk::GIFFirstOrderStatistics::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); 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); if (params.m_UseCtRange) { labelStatisticsImageFilter->SetHistogramParameters(1024.5+3096.5, -1024.5,3096.5); } else { labelStatisticsImageFilter->SetHistogramParameters(params.m_HistogramSize, minMaxComputer->GetMinimum(),minMaxComputer->GetMaximum()); } 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 uncorrected_std_dev = std::sqrt((count - 1) / count * labelStatisticsImageFilter->GetVariance(1)); double mean = labelStatisticsImageFilter->GetMean(1); auto histogram = labelStatisticsImageFilter->GetHistogram(1); HIndexType index; index.SetSize(1); double binWidth = histogram->GetBinMax(0, 0) - histogram->GetBinMin(0, 0); double uniformity = 0; double entropy = 0; double squared_sum = 0; double kurtosis = 0; double mean_absolut_deviation = 0; double skewness = 0; double sum_prob = 0; double p10th = histogram->Quantile(0,0.10); double p25th = histogram->Quantile(0,0.25); double p75th = histogram->Quantile(0,0.75); double p90th = histogram->Quantile(0,0.90); double Log2=log(2); for (int i = 0; i < (int)(histogram->GetSize(0)); ++i) { index[0] = i; double prob = histogram->GetFrequency(index); if (prob < 0.1) continue; double voxelValue = histogram->GetBinMin(0, i) +binWidth * 0.5; sum_prob += prob; squared_sum += prob * voxelValue*voxelValue; prob /= count; mean_absolut_deviation += prob* std::abs(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 rms = std::sqrt(squared_sum / count); kurtosis = kurtosis / (uncorrected_std_dev*uncorrected_std_dev * uncorrected_std_dev*uncorrected_std_dev); skewness = skewness / (uncorrected_std_dev*uncorrected_std_dev * uncorrected_std_dev); //mean_absolut_deviation = mean_absolut_deviation; double coveredGrayValueRange = range / imageRange; featureList.push_back(std::make_pair("FirstOrder Range",range)); featureList.push_back(std::make_pair("FirstOrder Uniformity",uniformity)); featureList.push_back(std::make_pair("FirstOrder Entropy",entropy)); featureList.push_back(std::make_pair("FirstOrder Energy",squared_sum)); featureList.push_back(std::make_pair("FirstOrder RMS",rms)); featureList.push_back(std::make_pair("FirstOrder Kurtosis", kurtosis)); featureList.push_back(std::make_pair("FirstOrder Excess Kurtosis", kurtosis-3)); featureList.push_back(std::make_pair("FirstOrder Skewness",skewness)); featureList.push_back(std::make_pair("FirstOrder Mean absolute deviation",mean_absolut_deviation)); featureList.push_back(std::make_pair("FirstOrder Covered Image Intensity Range",coveredGrayValueRange)); featureList.push_back(std::make_pair("FirstOrder Minimum",labelStatisticsImageFilter->GetMinimum(1))); featureList.push_back(std::make_pair("FirstOrder Maximum",labelStatisticsImageFilter->GetMaximum(1))); featureList.push_back(std::make_pair("FirstOrder Mean",labelStatisticsImageFilter->GetMean(1))); featureList.push_back(std::make_pair("FirstOrder Variance",labelStatisticsImageFilter->GetVariance(1))); featureList.push_back(std::make_pair("FirstOrder Sum",labelStatisticsImageFilter->GetSum(1))); featureList.push_back(std::make_pair("FirstOrder Median",labelStatisticsImageFilter->GetMedian(1))); featureList.push_back(std::make_pair("FirstOrder Standard deviation",labelStatisticsImageFilter->GetSigma(1))); featureList.push_back(std::make_pair("FirstOrder No. of Voxel",labelStatisticsImageFilter->GetCount(1))); featureList.push_back(std::make_pair("FirstOrder 10th Percentile",p10th)); featureList.push_back(std::make_pair("FirstOrder 90th Percentile",p90th)); featureList.push_back(std::make_pair("FirstOrder Interquartile Range",(p75th - p25th))); //Calculate the robus mean absolute deviation //First, set all frequencies to 0 that are <10th or >90th percentile 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 double meanRobust = 0.0; 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(); double robustMeanAbsoluteDeviation = 0.0; 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("FirstOrder Robust Mean", meanRobust)); featureList.push_back(std::make_pair("FirstOrder Robust Mean Absolute Deviation",robustMeanAbsoluteDeviation)); } mitk::GIFFirstOrderStatistics::GIFFirstOrderStatistics() : m_HistogramSize(256), m_UseCtRange(false) { } mitk::GIFFirstOrderStatistics::FeatureListType mitk::GIFFirstOrderStatistics::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { FeatureListType featureList; ParameterStruct params; params.m_HistogramSize = this->m_HistogramSize; params.m_UseCtRange = this->m_UseCtRange; AccessByItk_3(image, CalculateFirstOrderStatistics, mask, featureList, params); return featureList; } mitk::GIFFirstOrderStatistics::FeatureNameListType mitk::GIFFirstOrderStatistics::GetFeatureNames() { FeatureNameListType featureList; featureList.push_back("FirstOrder Minimum"); featureList.push_back("FirstOrder Maximum"); featureList.push_back("FirstOrder Mean"); featureList.push_back("FirstOrder Variance"); featureList.push_back("FirstOrder Sum"); featureList.push_back("FirstOrder Median"); featureList.push_back("FirstOrder Standard deviation"); featureList.push_back("FirstOrder No. of Voxel"); return featureList; } diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp index 6a21303883..efa7a5bebb 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp @@ -1,307 +1,402 @@ /*=================================================================== 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 #include #include // ITK #include #include // VTK #include #include #include // STL #include #include // OpenCV #include template void CalculateVolumeStatistic(itk::Image* itkImage, mitk::Image::Pointer mask, mitk::GIFVolumetricStatistics::FeatureListType & featureList) { typedef itk::Image ImageType; typedef itk::Image MaskType; typedef itk::LabelStatisticsImageFilter FilterType; typename MaskType::Pointer maskImage = MaskType::New(); mitk::CastToItkImage(mask, maskImage); typename FilterType::Pointer labelStatisticsImageFilter = FilterType::New(); labelStatisticsImageFilter->SetInput( itkImage ); labelStatisticsImageFilter->SetLabelInput(maskImage); labelStatisticsImageFilter->Update(); double volume = labelStatisticsImageFilter->GetCount(1); double voxelVolume = 1; for (int i = 0; i < (int)(VImageDimension); ++i) { volume *= itkImage->GetSpacing()[i]; voxelVolume *= itkImage->GetSpacing()[i]; } featureList.push_back(std::make_pair("Volumetric Features Volume (pixel based)", volume)); featureList.push_back(std::make_pair("Volumetric Features Voxel Volume", voxelVolume)); } template void - CalculateLargestDiameter(itk::Image* mask, mitk::GIFVolumetricStatistics::FeatureListType & featureList) + CalculateLargestDiameter(itk::Image* mask, mitk::Image::Pointer valueImage, mitk::GIFVolumetricStatistics::FeatureListType & featureList) { + typedef itk::Image ValueImageType; + + typename ValueImageType::Pointer itkValueImage = ValueImageType::New(); + mitk::CastToItkImage(valueImage, itkValueImage); + + typedef itk::Image ImageType; typedef typename ImageType::PointType PointType; typename ImageType::SizeType radius; for (int i=0; i < (int)VImageDimension; ++i) radius[i] = 1; - itk::NeighborhoodIterator iterator(radius,mask, mask->GetRequestedRegion()); + itk::NeighborhoodIterator iterator(radius, mask, mask->GetRequestedRegion()); + itk::NeighborhoodIterator valueIter(radius, itkValueImage, itkValueImage->GetRequestedRegion()); std::vector borderPoints; + + // + // Calculate surface in different directions + // + double surface = 0; + std::vector directionSurface; + for (int i = 0; i < (int)(iterator.Size()); ++i) + { + auto offset = iterator.GetOffset(i); + double deltaS = 1; + int nonZeros = 0; + for (int j = 0; j < VImageDimension; ++j) + { + if (offset[j] != 0 && nonZeros == 0) + { + for (int k = 0; k < VImageDimension; ++k) + { + if (k != j) + deltaS *= mask->GetSpacing()[k]; + } + nonZeros++; + } + else if (offset[j] != 0) + { + deltaS = 0; + } + } + if (nonZeros < 1) + deltaS = 0; + directionSurface.push_back(deltaS); + } + + // + // Prepare calulation of Centre of mass shift + // + PointType normalCenter(0); + PointType normalCenterUncorrected(0); + PointType weightedCenter(0); + PointType currentPoint; + int numberOfPoints = 0; + int numberOfPointsUncorrected = 0; + double sumOfPoints = 0; + while(!iterator.IsAtEnd()) { if (iterator.GetCenterPixel() == 0) { ++iterator; + ++valueIter; continue; } + mask->TransformIndexToPhysicalPoint(iterator.GetIndex(), currentPoint); + + normalCenterUncorrected += currentPoint.GetVectorFromOrigin(); + ++numberOfPointsUncorrected; + + double intensityValue = valueIter.GetCenterPixel(); + if (intensityValue == intensityValue) + { + normalCenter += currentPoint.GetVectorFromOrigin(); + weightedCenter += currentPoint.GetVectorFromOrigin() * intensityValue; + sumOfPoints += intensityValue; + ++numberOfPoints; + } + bool border = false; for (int i = 0; i < (int)(iterator.Size()); ++i) { - if (iterator.GetPixel(i) == 0) + if (iterator.GetPixel(i) == 0 || ( ! iterator.IndexInBounds(i))) { border = true; - break; + surface += directionSurface[i]; + //break; } } if (border) { auto centerIndex = iterator.GetIndex(); PointType centerPoint; mask->TransformIndexToPhysicalPoint(centerIndex, centerPoint ); borderPoints.push_back(centerPoint); } ++iterator; + ++valueIter; } + auto normalCenterVector = normalCenter.GetVectorFromOrigin() / numberOfPoints; + auto normalCenterVectorUncorrected = normalCenter.GetVectorFromOrigin() / numberOfPointsUncorrected; + auto weightedCenterVector = weightedCenter.GetVectorFromOrigin() / sumOfPoints; + auto differenceOfCentersUncorrected = (normalCenterVectorUncorrected - weightedCenterVector).GetNorm(); + auto differenceOfCenters = (normalCenterVector - weightedCenterVector).GetNorm(); + double longestDiameter = 0; unsigned long numberOfBorderPoints = borderPoints.size(); for (int i = 0; i < (int)numberOfBorderPoints; ++i) { auto point = borderPoints[i]; for (int j = i; j < (int)numberOfBorderPoints; ++j) { double newDiameter=point.EuclideanDistanceTo(borderPoints[j]); if (newDiameter > longestDiameter) longestDiameter = newDiameter; } } - featureList.push_back(std::make_pair("Volumetric Features Maximum 3D diameter",longestDiameter)); + featureList.push_back(std::make_pair("Volumetric Features Maximum 3D diameter", longestDiameter)); + featureList.push_back(std::make_pair("Volumetric Features Surface (Voxel based)", surface)); + featureList.push_back(std::make_pair("Volumetric Features Centre of mass shift", differenceOfCenters)); + featureList.push_back(std::make_pair("Volumetric Features Centre of mass shift (Uncorrected)", differenceOfCentersUncorrected)); } mitk::GIFVolumetricStatistics::GIFVolumetricStatistics() { } mitk::GIFVolumetricStatistics::FeatureListType mitk::GIFVolumetricStatistics::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { FeatureListType featureList; AccessByItk_2(image, CalculateVolumeStatistic, mask, featureList); - AccessByItk_1(mask, CalculateLargestDiameter, featureList); + AccessByItk_2(mask, CalculateLargestDiameter, image, featureList); vtkSmartPointer mesher = vtkSmartPointer::New(); vtkSmartPointer stats = vtkSmartPointer::New(); mesher->SetInputData(mask->GetVtkImageData()); stats->SetInputConnection(mesher->GetOutputPort()); stats->Update(); double pi = vnl_math::pi; double meshVolume = stats->GetVolume(); double meshSurf = stats->GetSurfaceArea(); double pixelVolume = featureList[0].second; + double pixelSurface = featureList[3].second; + + MITK_INFO << "Surf: " << pixelSurface << " Vol " << pixelVolume; - double compactness1 = pixelVolume / ( std::sqrt(pi) * std::pow(meshSurf, 2.0/3.0)); + double compactness1 = pixelVolume / (std::sqrt(pi) * std::pow(meshSurf, 2.0 / 3.0)); + double compactness1Pixel = pixelVolume / (std::sqrt(pi) * std::pow(pixelSurface, 2.0 / 3.0)); //This is the definition used by Aertz. However, due to 2/3 this feature is not demensionless. Use compactness3 instead. - double compactness2 = 36*pi*pixelVolume*pixelVolume/meshSurf/meshSurf/meshSurf; - double compactness3 = pixelVolume / ( std::sqrt(pi) * std::pow(meshSurf, 3.0/2.0)); + double compactness2 = 36 * pi*pixelVolume*pixelVolume / meshSurf / meshSurf / meshSurf; + double compactness2Pixel = 36 * pi*pixelVolume*pixelVolume / pixelSurface / pixelSurface / pixelSurface; + double compactness3 = pixelVolume / (std::sqrt(pi) * std::pow(meshSurf, 3.0 / 2.0)); + double compactness3Pixel = pixelVolume / (std::sqrt(pi) * std::pow(pixelSurface, 3.0 / 2.0)); - double sphericity=std::pow(pi,1/3.0) *std::pow(6*pixelVolume, 2.0/3.0) / meshSurf; + double sphericity = std::pow(pi, 1 / 3.0) *std::pow(6 * pixelVolume, 2.0 / 3.0) / meshSurf; + double sphericityPixel = std::pow(pi, 1 / 3.0) *std::pow(6 * pixelVolume, 2.0 / 3.0) / pixelSurface; double surfaceToVolume = meshSurf / pixelVolume; + double surfaceToVolumePixel = pixelSurface / pixelVolume; double sphericalDisproportion = meshSurf / 4 / pi / std::pow(3.0 / 4.0 / pi * pixelVolume, 2.0 / 3.0); - double asphericity = std::pow(compactness2,(-1.0/3.0)) - 1; + double sphericalDisproportionPixel = pixelSurface / 4 / pi / std::pow(3.0 / 4.0 / pi * pixelVolume, 2.0 / 3.0); + double asphericity = std::pow(1.0/compactness2, (1.0 / 3.0)) - 1; + double asphericityPixel = std::pow(1.0/compactness2Pixel, (1.0 / 3.0)) - 1; //Calculate center of mass shift int xx = mask->GetDimensions()[0]; int yy = mask->GetDimensions()[1]; int zz = mask->GetDimensions()[2]; - mitk::Point3D geom; - mitk::Point3D weighted; - unsigned int noOfPx = 0; - double totalGrayValue = 0.0; + double xd = mask->GetGeometry()->GetSpacing()[0]; + double yd = mask->GetGeometry()->GetSpacing()[1]; + double zd = mask->GetGeometry()->GetSpacing()[2]; + std::vector pointsForPCA; + std::vector pointsForPCAUncorrected; - MITK_WARN << xx << " " << yy << " " << zz; for (int x = 0; x < xx; x++) { for (int y = 0; y < yy; y++) { for (int z = 0; z < zz; z++) { itk::Image::IndexType index; index[0] = x; index[1] = y; index[2] = z; mitk::ScalarType pxImage; mitk::ScalarType pxMask; mitkPixelTypeMultiplex5( mitk::FastSinglePixelAccess, image->GetChannelDescriptor().GetPixelType(), image, image->GetVolumeData(), index, pxImage, 0); mitkPixelTypeMultiplex5( mitk::FastSinglePixelAccess, mask->GetChannelDescriptor().GetPixelType(), mask, mask->GetVolumeData(), index, pxMask, 0); //Check if voxel is contained in segmentation - if(pxMask > 0) + if (pxMask > 0) { - geom[0] += x; - geom[1] += y; - geom[2] += z; - - weighted[0] += pxImage*x; - weighted[1] += pxImage*y; - weighted[2] += pxImage*z; - - noOfPx++; - totalGrayValue += pxImage; - cv::Point3d tmp; - tmp.x = x; - tmp.y = y; - tmp.z = z; - - pointsForPCA.push_back(tmp); + tmp.x = x * xd; + tmp.y = y * yd; + tmp.z = z * zd; + pointsForPCAUncorrected.push_back(tmp); + + if (pxImage == pxImage) + { + pointsForPCA.push_back(tmp); + } } - } } } - geom[0] = geom[0] / noOfPx; - geom[1] = geom[1] / noOfPx; - geom[2] = geom[2] / noOfPx; - - weighted[0] = weighted[0] / totalGrayValue; - weighted[1] = weighted[1] / totalGrayValue; - weighted[2] = weighted[2] / totalGrayValue; - - double shift = std::sqrt( - (geom[0] - weighted[0])*(geom[0] - weighted[0]) - + (geom[1] - weighted[1])*(geom[1] - weighted[1]) - + (geom[2] - weighted[2])*(geom[2] - weighted[2]) - ); //Calculate PCA Features int sz = pointsForPCA.size(); cv::Mat data_pts = cv::Mat(sz, 3, CV_64FC1); for (int i = 0; i < data_pts.rows; ++i) { data_pts.at(i, 0) = pointsForPCA[i].x; data_pts.at(i, 1) = pointsForPCA[i].y; data_pts.at(i, 2) = pointsForPCA[i].z; } + //Calculate PCA Features + int szUC = pointsForPCAUncorrected.size(); + cv::Mat data_ptsUC = cv::Mat(szUC, 3, CV_64FC1); + for (int i = 0; i < data_ptsUC.rows; ++i) + { + data_ptsUC.at(i, 0) = pointsForPCAUncorrected[i].x; + data_ptsUC.at(i, 1) = pointsForPCAUncorrected[i].y; + data_ptsUC.at(i, 2) = pointsForPCAUncorrected[i].z; + } + //Perform PCA analysis cv::PCA pca_analysis(data_pts, cv::Mat(), CV_PCA_DATA_AS_ROW); + cv::PCA pca_analysisUC(data_ptsUC, cv::Mat(), CV_PCA_DATA_AS_ROW); //Store the eigenvalues std::vector eigen_val(3); + std::vector eigen_valUC(3); for (int i = 0; i < 3; ++i) { - eigen_val[i] = pca_analysis.eigenvalues.at(0, i); + eigen_val[i] = pca_analysis.eigenvalues.at(0, i); + eigen_valUC[i] = pca_analysisUC.eigenvalues.at(0, i); } - std::sort (eigen_val.begin(), eigen_val.end()); + std::sort(eigen_val.begin(), eigen_val.end()); + std::sort(eigen_valUC.begin(), eigen_valUC.end()); double major = eigen_val[2]; double minor = eigen_val[1]; double least = eigen_val[0]; double elongation = major == 0 ? 0 : minor/major; - double flatness = major == 0 ? 0 :least/major; + double flatness = major == 0 ? 0 : least / major; + double majorUC = eigen_valUC[2]; + double minorUC = eigen_valUC[1]; + double leastUC = eigen_valUC[0]; + double elongationUC = majorUC == 0 ? 0 : minorUC / majorUC; + double flatnessUC = majorUC == 0 ? 0 : leastUC / majorUC; featureList.push_back(std::make_pair("Volumetric Features Volume (mesh based)",meshVolume)); featureList.push_back(std::make_pair("Volumetric Features Surface area",meshSurf)); featureList.push_back(std::make_pair("Volumetric Features Surface to volume ratio",surfaceToVolume)); featureList.push_back(std::make_pair("Volumetric Features Sphericity",sphericity)); featureList.push_back(std::make_pair("Volumetric Features Asphericity",asphericity)); featureList.push_back(std::make_pair("Volumetric Features Compactness 1",compactness1)); featureList.push_back(std::make_pair("Volumetric Features Compactness 2",compactness2)); featureList.push_back(std::make_pair("Volumetric Features Compactness 3",compactness3)); - featureList.push_back(std::make_pair("Volumetric Features Spherical disproportion",sphericalDisproportion)); - featureList.push_back(std::make_pair("Volumetric Features Center of mass Shift",shift)); + featureList.push_back(std::make_pair("Volumetric Features Spherical disproportion", sphericalDisproportion)); + featureList.push_back(std::make_pair("Volumetric Features Surface to volume ratio (Voxel based)", surfaceToVolumePixel)); + featureList.push_back(std::make_pair("Volumetric Features Sphericity (Voxel based)", sphericityPixel)); + featureList.push_back(std::make_pair("Volumetric Features Asphericity (Voxel based)", asphericityPixel)); + featureList.push_back(std::make_pair("Volumetric Features Compactness 1 (Voxel based)", compactness1Pixel)); + featureList.push_back(std::make_pair("Volumetric Features Compactness 2 (Voxel based)", compactness2Pixel)); + featureList.push_back(std::make_pair("Volumetric Features Compactness 3 (Voxel based)", compactness3Pixel)); + featureList.push_back(std::make_pair("Volumetric Features Spherical disproportion (Voxel based)", sphericalDisproportionPixel)); featureList.push_back(std::make_pair("Volumetric Features PCA Major Axis",major)); featureList.push_back(std::make_pair("Volumetric Features PCA Minor Axis",minor)); featureList.push_back(std::make_pair("Volumetric Features PCA Least Axis",least)); featureList.push_back(std::make_pair("Volumetric Features PCA Elongation",elongation)); featureList.push_back(std::make_pair("Volumetric Features PCA Flatness",flatness)); + featureList.push_back(std::make_pair("Volumetric Features PCA Major Axis (Uncorrected)", majorUC)); + featureList.push_back(std::make_pair("Volumetric Features PCA Minor Axis (Uncorrected)", minorUC)); + featureList.push_back(std::make_pair("Volumetric Features PCA Least Axis (Uncorrected)", leastUC)); + featureList.push_back(std::make_pair("Volumetric Features PCA Elongation (Uncorrected)", elongationUC)); + featureList.push_back(std::make_pair("Volumetric Features PCA Flatness (Uncorrected)", flatnessUC)); return featureList; } mitk::GIFVolumetricStatistics::FeatureNameListType mitk::GIFVolumetricStatistics::GetFeatureNames() { FeatureNameListType featureList; featureList.push_back("Volumetric Features Compactness 1"); featureList.push_back("Volumetric Features Compactness 2"); featureList.push_back("Volumetric Features Compactness 3"); featureList.push_back("Volumetric Features Sphericity"); featureList.push_back("Volumetric Features Asphericity"); featureList.push_back("Volumetric Features Surface to volume ratio"); featureList.push_back("Volumetric Features Surface area"); featureList.push_back("Volumetric Features Volume (mesh based)"); featureList.push_back("Volumetric Features Volume (pixel based)"); featureList.push_back("Volumetric Features Spherical disproportion"); featureList.push_back("Volumetric Features Maximum 3D diameter"); return featureList; }