diff --git a/CMake/BuildConfigurations/mitkPhenotypingWorkbench.cmake b/CMake/BuildConfigurations/mitkPhenotypingWorkbench.cmake new file mode 100644 index 0000000000..f1991697f9 --- /dev/null +++ b/CMake/BuildConfigurations/mitkPhenotypingWorkbench.cmake @@ -0,0 +1,58 @@ +message(STATUS "Configuring MITK Phenotyping with all Plugins") + +# Enable non-optional external dependencies +set(MITK_USE_Vigra ON CACHE BOOL "MITK Use Vigra Library" FORCE) +set(MITK_USE_HDF5 ON CACHE BOOL "MITK Use HDF5 Library" FORCE) +set(MITK_USE_MatchPoint ON CACHE BOOL "" FORCE) +set(MITK_USE_DCMTK ON CACHE BOOL "" FORCE) +set(MITK_USE_DCMQI ON CACHE BOOL "" FORCE) +set(MITK_USE_PCRE ON CACHE BOOL "" FORCE) +set(MITK_USE_SWIG ON CACHE BOOL "" FORCE) + +# Disable all apps but MITK Diffusion +set(MITK_BUILD_ALL_APPS OFF CACHE BOOL "Build all MITK applications" FORCE) +set(BUILD_BasicImageProcessingMiniApps ON CACHE BOOL "Build the MITK Basic Image Processing Apps" FORCE) +set(BUILD_ClassificationMiniApps ON CACHE BOOL "Build the MITK Classification Miniapps" FORCE) + +set(MITK_CONFIG_PLUGINS + org.mitk.gui.common + org.mitk.gui.qt.application + org.mitk.gui.qt.basicimageprocessing + org.mitk.gui.qt.classificationsegmentation + org.mitk.gui.qt.common + org.mitk.gui.qt.common.legacy + org.mitk.gui.qt.datamanager + org.mitk.gui.qt.ext + org.mitk.gui.qt.extapplication + org.mitk.gui.qt.imagecropper + org.mitk.gui.qt.imagenavigator + org.mitk.gui.qt.matchpoint.algorithm.batch + org.mitk.gui.qt.matchpoint.algorithm.browser + org.mitk.gui.qt.matchpoint.algorithm.control + org.mitk.gui.qt.matchpoint.manipulator + org.mitk.gui.qt.matchpoint.mapper + org.mitk.gui.qt.matchpoint.visualizer + org.mitk.gui.qt.measurementtoolbox + org.mitk.gui.qt.moviemaker + org.mitk.gui.qt.multilabelsegmentation + org.mitk.gui.qt.preprocessing.resampling + org.mitk.gui.qt.properties + org.mitk.gui.qt.radiomics + org.mitk.gui.qt.segmentation + org.mitk.gui.qt.stdmultiwidgeteditor + org.mitk.gui.qt.viewnavigator + org.mitk.gui.qt.volumevisualization + org.mitk.gui.qt.pointsetinteraction +) + +# Build neither all plugins nor examples +#set(MITK_BUILD_ALL_PLUGINS OFF CACHE BOOL "Build all MITK plugins" FORCE) +set(MITK_BUILD_EXAMPLES OFF CACHE BOOL "Build the MITK examples" FORCE) +set(BUILD_TESTING OFF CACHE BOOL "Build the MITK tests" FORCE) + +# Activate in-application help generation +set(MITK_DOXYGEN_GENERATE_QCH_FILES ON CACHE BOOL "Use doxygen to generate Qt compressed help files for MITK docs" FORCE) +set(BLUEBERRY_USE_QT_HELP ON CACHE BOOL "Enable support for integrating bundle documentation into Qt Help" FORCE) + +# Disable console window +set(MITK_SHOW_CONSOLE_WINDOW ON CACHE BOOL "Use this to enable or disable the console window when starting MITK GUI Applications" FORCE) diff --git a/CMake/Whitelists/Wrapping.cmake b/CMake/Whitelists/Wrapping.cmake index 33ae5929a0..015938fe1e 100644 --- a/CMake/Whitelists/Wrapping.cmake +++ b/CMake/Whitelists/Wrapping.cmake @@ -1,10 +1,20 @@ set(enabled_modules Core + CLCore + CLUtilities + ITKCommon + MatchPointRegistration + Segmentation + Multilabel + DICOMReader + DICOMReaderServices + BasicImageProcessing + DicomRT CommandLine CppMicroServices Classification ) set(enabled_plugins "" ) \ No newline at end of file diff --git a/Modules/BasicImageProcessing/include/mitkTransformationOperation.h b/Modules/BasicImageProcessing/include/mitkTransformationOperation.h index ffdf369bde..c36e4478c8 100644 --- a/Modules/BasicImageProcessing/include/mitkTransformationOperation.h +++ b/Modules/BasicImageProcessing/include/mitkTransformationOperation.h @@ -1,67 +1,79 @@ /*=================================================================== 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 mitkArithmeticOperation_h -#define mitkArithmeticOperation_h +#ifndef mitkTransformationOperation_h +#define mitkTransformationOperation_h #include #include #include namespace mitk { enum BorderCondition { Constant, Periodic, ZeroFluxNeumann }; enum WaveletType { Held, Vow, Simoncelli, Shannon }; enum GridInterpolationPositionType { SameSize, OriginAligned, CenterAligned }; /** \brief Executes a transformation operations on one or two images * * All parameters of the arithmetic operations must be specified during construction. * The actual operation is executed when calling GetResult(). */ class MITKBASICIMAGEPROCESSING_EXPORT TransformationOperation { public: static std::vector MultiResolution(Image::Pointer & image, unsigned int numberOfLevels, bool outputAsDouble = false); static Image::Pointer LaplacianOfGaussian(Image::Pointer & image, double sigma, bool outputAsDouble = false); - static std::vector WaveletForward(Image::Pointer & image, unsigned int numberOfLevels, unsigned int numberOfBands, BorderCondition condition, WaveletType waveletType); + static std::vector WaveletForward(Image::Pointer image, unsigned int numberOfLevels, unsigned int numberOfBands, BorderCondition condition, WaveletType waveletType); static Image::Pointer ResampleImage(Image::Pointer &image, mitk::Vector3D spacing, mitk::ImageMappingInterpolator::Type interpolator, GridInterpolationPositionType position, bool returnAsDouble, bool roundOutput); static Image::Pointer ResampleMask(Image::Pointer &image, mitk::Vector3D spacing, mitk::ImageMappingInterpolator::Type interpolator, GridInterpolationPositionType position); + static Image::Pointer CastToUnsignedChar(Image::Pointer image, int &error); + static Image::Pointer CastToSignedChar(Image::Pointer image, int &error); + static Image::Pointer CastToChar(Image::Pointer image, int &error); + static Image::Pointer CastToUnsignedShort(Image::Pointer image, int &error); + static Image::Pointer CastToShort(Image::Pointer image, int &error); + static Image::Pointer CastToUnsignedInt(Image::Pointer image, int &error); + static Image::Pointer CastToInt(Image::Pointer image, int &error); + static Image::Pointer CastToUnsignedLong(Image::Pointer image, int &error); + static Image::Pointer CastToLong(Image::Pointer image, int &error); + static Image::Pointer CastToFloat(Image::Pointer image, int &error); + static Image::Pointer CastToDouble(Image::Pointer image, int &error); + }; } -#endif // mitkArithmeticOperation_h \ No newline at end of file +#endif // mitkTransformationOperation_h \ No newline at end of file diff --git a/Modules/BasicImageProcessing/src/mitkMaskCleaningOperation.cpp b/Modules/BasicImageProcessing/src/mitkMaskCleaningOperation.cpp index ce6d2bb4b2..75d5320b8c 100644 --- a/Modules/BasicImageProcessing/src/mitkMaskCleaningOperation.cpp +++ b/Modules/BasicImageProcessing/src/mitkMaskCleaningOperation.cpp @@ -1,141 +1,142 @@ /*=================================================================== 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 "mitkMaskCleaningOperation.h" #include #include #include #include #include #include #include "itkCastImageFilter.h" namespace mitk { namespace Functor { template< class TInput, class TOutput> class RangeBasedMasking { public: RangeBasedMasking() {}; ~RangeBasedMasking() {}; bool operator!=(const RangeBasedMasking &) const { return false; } bool operator==(const RangeBasedMasking & other) const { return !(*this != other); } inline TOutput operator()(const TInput & A, const TOutput & B) const { unsigned short erg = B; if (lowerLimitOn && (A < lowerLimit)) { erg = 0; } if (upperLimitOn && (upperLimit < A)) { erg = 0; } return erg; } bool lowerLimitOn = false; bool upperLimitOn = false; double lowerLimit = 0; double upperLimit = 1; }; } } template static void ExecuteRangeBasedMasking(itk::Image* image, mitk::Image::Pointer & mask, bool lowerLimitOn, double lowerLimit, bool upperLimitOn, double upperLimit, mitk::Image::Pointer & resultImage) { typedef itk::Image ImageType; typedef itk::Image MaskImageType; typedef itk::BinaryFunctorImageFilter< ImageType, MaskImageType, MaskImageType, mitk::Functor::RangeBasedMasking > DefaultFilterType; typename MaskImageType::Pointer itkMask = MaskImageType::New(); mitk::CastToItkImage(mask.GetPointer(), itkMask); typename DefaultFilterType::Pointer filter = DefaultFilterType::New(); filter->SetInput1(image); filter->SetInput2(itkMask); filter->GetFunctor().lowerLimitOn = lowerLimitOn; filter->GetFunctor().upperLimitOn = upperLimitOn; filter->GetFunctor().lowerLimit = lowerLimit; filter->GetFunctor().upperLimit = upperLimit; filter->Update(); CastToMitkImage(filter->GetOutput(), resultImage); } mitk::Image::Pointer mitk::MaskCleaningOperation::RangeBasedMasking(Image::Pointer & image, Image::Pointer & mask, bool lowerLimitOn, double lowerLimit, bool upperLimitOn, double upperLimit) { Image::Pointer resultImage; AccessByItk_n(image, ExecuteRangeBasedMasking, (mask, lowerLimitOn, lowerLimit, upperLimitOn, upperLimit, resultImage)); return resultImage; } template static void CalculateMeanAndStd(itk::Image* image, mitk::Image::Pointer & mask, double &mean, double &std) { typedef itk::Image ImageType; typedef itk::Image MaskImageType; typename MaskImageType::Pointer itkMask = MaskImageType::New(); mitk::CastToItkImage(mask.GetPointer(), itkMask); itk::ImageRegionConstIterator image_iter(image, image->GetLargestPossibleRegion()); itk::ImageRegionConstIterator mask_iter(itkMask, itkMask->GetLargestPossibleRegion()); unsigned int number_of_voxels = 0; while (!image_iter.IsAtEnd()) { if (mask_iter.Get() > 0) { mean += image_iter.Get(); std += image_iter.Get() * image_iter.Get(); ++number_of_voxels; } ++image_iter; ++mask_iter; } mean /= number_of_voxels; std /= number_of_voxels; - std -= mean; + std -= mean*mean; std = sqrt(std); + MITK_INFO << "Mean: " << mean << " Sigma: " << std; } mitk::Image::Pointer mitk::MaskCleaningOperation::MaskOutlierFiltering(Image::Pointer & image, Image::Pointer & mask) { Image::Pointer resultImage; double mean = 0; double std = 0; AccessByItk_n(image, CalculateMeanAndStd, (mask, mean, std)); return MaskCleaningOperation::RangeBasedMasking(image, mask, true, mean - 3 * std, true, mean + 3 * std); } \ No newline at end of file diff --git a/Modules/BasicImageProcessing/src/mitkTransformationOperation.cpp b/Modules/BasicImageProcessing/src/mitkTransformationOperation.cpp index 0f0c302634..bbd98ebebb 100644 --- a/Modules/BasicImageProcessing/src/mitkTransformationOperation.cpp +++ b/Modules/BasicImageProcessing/src/mitkTransformationOperation.cpp @@ -1,504 +1,758 @@ /*=================================================================== 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 "mitkTransformationOperation.h" - +#include +#include #include #include #include #include #include #include // Wavelet #include #include #include #include #include #include #include #include #include #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkPeriodicBoundaryCondition.h" #include "itkConstantBoundaryCondition.h" //#include #include "itkCastImageFilter.h" #include "itkUnaryFunctorImageFilter.h" #include #include #include namespace mitk { namespace Functor { template< class TInput> class ThresholdValue { public: ThresholdValue() {}; ~ThresholdValue() {}; bool operator!=(const ThresholdValue &) const { return false; } bool operator==(const ThresholdValue & other) const { return !(*this != other); } inline unsigned short operator()(const TInput & A) const { if (A < value) return 0; else return 1; } double value = 0.0; }; template< class TInput, class TOutput> class RoundValue { public: RoundValue() {}; ~RoundValue() {}; bool operator!=(const RoundValue &) const { return false; } bool operator==(const RoundValue & other) const { return !(*this != other); } inline TOutput operator()(const TInput & A) const { return std::round(A); } }; } } + + +// Error Codes: 0: Successfull +// 1: General Error (Not Specific) +// 2: Error when duplicating images +// 3: Error when casting image +template +static void ExecuteConvertToDataType(itk::Image* image, mitk::Image::Pointer &resultImage, int & isSuccessful) +{ + typedef itk::Image InputImageType; + typedef itk::Image OutputImageType; + + isSuccessful = 1; + + if (std::is_same::value) // If input has already the "right" data type, only clone it. + { + try + { + typedef itk::ImageDuplicator DuplicateFilterType; + typename DuplicateFilterType::Pointer duplicateFilter = DuplicateFilterType::New(); + + duplicateFilter->SetInputImage(image); + duplicateFilter->Update(); + CastToMitkImage(duplicateFilter->GetOutput(), resultImage); + } + catch (...) + { + resultImage = nullptr; + isSuccessful = 2; + return; + } + + } + else // Convert the image data type if it has the "wrong" datatype. + { + try + { + typedef itk::CastImageFilter CastFilterType; + typename CastFilterType::Pointer castFilter = CastFilterType::New(); + + castFilter->SetInput(image); + castFilter->Update(); + CastToMitkImage(castFilter->GetOutput(), resultImage); + } + catch (...) + { + resultImage = nullptr; + isSuccessful = 3; + return; + } + } + + isSuccessful = 0; + return; +} + +// Error Codes: 0: Successfull +// 1: General Error (Not Specific) +// 2: Error when duplicating images +// 3: Error when casting image +// 4: General Error (really early) +// 5: Unsupported image type +// +// Commented types are not +template +static void ExecuteConvertToGivenType(itk::Image* image, std::type_index &type, mitk::Image::Pointer &resultImage, int & isSuccessful) +{ + isSuccessful = 4; + + if (type == typeid(unsigned char)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + else if (type == typeid(signed char)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + else if (type == typeid(char)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + //else if (type == typeid(wchar_t)) + //{ + // ExecuteConvertToDataType(image, resultImage, isSuccessful); + //} + //else if (type == typeid(char16_t)) + //{ + // ExecuteConvertToDataType(image, resultImage, isSuccessful); + //} + //else if (type == typeid(char32_t)) + //{ + // ExecuteConvertToDataType(image, resultImage, isSuccessful); + //} + //else if (type == typeid(bool)) + //{ + // ExecuteConvertToDataType(image, resultImage, isSuccessful); + //} + else if (type == typeid(unsigned short int)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + else if (type == typeid(short int)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + else if (type == typeid(unsigned int)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } else if (type == typeid(int)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + else if (type == typeid(unsigned long int)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + else if (type == typeid(long int)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + //else if (type == typeid(unsigned long long int)) + //{ + // ExecuteConvertToDataType(image, resultImage, isSuccessful); + //} + //else if (type == typeid(long long int)) + //{ + // ExecuteConvertToDataType(image, resultImage, isSuccessful); + //} + else if (type == typeid(float)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + else if (type == typeid(double)) + { + ExecuteConvertToDataType(image, resultImage, isSuccessful); + } + //else if (type == typeid(long double)) + //{ + // ExecuteConvertToDataType(image, resultImage, isSuccessful); + //} + else + { + resultImage = NULL; + isSuccessful = 5; + } +} + + template static void ExecuteMultiResolution(itk::Image* image, unsigned int numberOfLevels, bool outputAsDouble, std::vector &resultImages) { typedef itk::Image ImageType; typedef itk::Image DoubleOutputType; typedef itk::RecursiveMultiResolutionPyramidImageFilter ImageTypeFilterType; typedef itk::RecursiveMultiResolutionPyramidImageFilter DoubleTypeFilterType; if (outputAsDouble) { typename DoubleTypeFilterType::Pointer recursiveMultiResolutionPyramidImageFilter = DoubleTypeFilterType::New(); recursiveMultiResolutionPyramidImageFilter->SetInput(image); recursiveMultiResolutionPyramidImageFilter->SetNumberOfLevels(numberOfLevels); recursiveMultiResolutionPyramidImageFilter->Update(); // This outputs the levels (0 is the lowest resolution) for (unsigned int i = 0; i < numberOfLevels; ++i) { mitk::Image::Pointer outputImage = mitk::Image::New(); CastToMitkImage(recursiveMultiResolutionPyramidImageFilter->GetOutput(i), outputImage); resultImages.push_back(outputImage); } } else { typename ImageTypeFilterType::Pointer recursiveMultiResolutionPyramidImageFilter = ImageTypeFilterType::New(); recursiveMultiResolutionPyramidImageFilter->SetInput(image); recursiveMultiResolutionPyramidImageFilter->SetNumberOfLevels(numberOfLevels); recursiveMultiResolutionPyramidImageFilter->Update(); // This outputs the levels (0 is the lowest resolution) for (unsigned int i = 0; i < numberOfLevels; ++i) { mitk::Image::Pointer outputImage = mitk::Image::New(); CastToMitkImage(recursiveMultiResolutionPyramidImageFilter->GetOutput(i), outputImage); resultImages.push_back(outputImage); } } } std::vector mitk::TransformationOperation::MultiResolution(Image::Pointer & image, unsigned int numberOfLevels, bool outputAsDouble) { std::vector resultImages; AccessByItk_n(image, ExecuteMultiResolution, (numberOfLevels, outputAsDouble, resultImages)); return resultImages; } template static void ExecuteLaplacianOfGaussian(itk::Image* image, double sigma, bool outputAsDouble, mitk::Image::Pointer &resultImage) { typedef itk::Image ImageType; typedef itk::Image DoubleOutputType; typedef itk::LaplacianRecursiveGaussianImageFilter ImageTypeFilterType; typedef itk::LaplacianRecursiveGaussianImageFilter DoubleTypeFilterType; if (outputAsDouble) { typename DoubleTypeFilterType::Pointer filter = DoubleTypeFilterType::New(); filter->SetInput(image); filter->SetSigma(sigma); filter->Update(); CastToMitkImage(filter->GetOutput(), resultImage); } else { typename ImageTypeFilterType::Pointer filter = ImageTypeFilterType::New(); filter->SetInput(image); filter->SetSigma(sigma); filter->Update(); CastToMitkImage(filter->GetOutput(), resultImage); } } mitk::Image::Pointer mitk::TransformationOperation::LaplacianOfGaussian(Image::Pointer & image, double sigma, bool outputAsDouble) { Image::Pointer resultImage; AccessByItk_n(image, ExecuteLaplacianOfGaussian, (sigma, outputAsDouble, resultImage)); return resultImage; } template static void ExecuteSpecificWaveletTransformation(itk::Image* image, unsigned int numberOfLevels, unsigned int numberOfBands, mitk::BorderCondition condition, std::vector &resultImages) { const unsigned int Dimension = VImageDimension; typedef TInputPixel PixelType; typedef TOutputPixel OutputPixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::Image< double, Dimension > DoubleImageType; typedef itk::Image< OutputPixelType, Dimension > OutputImageType; typedef itk::CastImageFilter< ImageType, DoubleImageType > CastFilterType; typedef itk::FFTPadPositiveIndexImageFilter< DoubleImageType > FFTPadType; typedef itk::ForwardFFTImageFilter< DoubleImageType, itk::Image< std::complex, Dimension> > FFTFilterType; typedef typename FFTFilterType::OutputImageType ComplexImageType; typedef TWaveletFunction WaveletFunctionType; typedef itk::WaveletFrequencyFilterBankGenerator< ComplexImageType, WaveletFunctionType > WaveletFilterBankType; typedef itk::WaveletFrequencyForward< ComplexImageType, ComplexImageType, WaveletFilterBankType > ForwardWaveletType; typedef itk::InverseFFTImageFilter< ComplexImageType, OutputImageType > InverseFFTFilterType; // Convert input parameter unsigned int highSubBands = numberOfBands; //inputBands; unsigned int levels = numberOfLevels; + auto oldDirection = image->GetDirection(); + typename ImageType::DirectionType oldDir = image->GetDirection(); + typename ImageType::DirectionType newDir; + + int signedVImageDimension = static_cast(VImageDimension); + + for (int i = 0; i < signedVImageDimension; ++i) + { + for (int j = 0; j < signedVImageDimension; ++j) + { + newDir[i][j] = ((i == j) ? itk::SpacePrecisionType(1.0) : itk::SpacePrecisionType(0)); + } + } + image->SetDirection(newDir); // Perform FFT on input image typename CastFilterType::Pointer castFilter = CastFilterType::New(); castFilter->SetInput(image); // Pad Image so it fits the expect typename FFTPadType::Pointer fftpad = FFTPadType::New(); fftpad->SetSizeGreatestPrimeFactor(4); itk::ConstantBoundaryCondition< DoubleImageType > constantBoundaryCondition; itk::PeriodicBoundaryCondition< DoubleImageType > periodicBoundaryCondition; itk::ZeroFluxNeumannBoundaryCondition< DoubleImageType > zeroFluxNeumannBoundaryCondition; switch (condition) { case mitk::BorderCondition::Constant: fftpad->SetBoundaryCondition(&constantBoundaryCondition); break; case mitk::BorderCondition::Periodic: fftpad->SetBoundaryCondition(&periodicBoundaryCondition); break; case mitk::BorderCondition::ZeroFluxNeumann: fftpad->SetBoundaryCondition(&zeroFluxNeumannBoundaryCondition); break; default: break; } fftpad->SetInput(castFilter->GetOutput()); typename FFTFilterType::Pointer fftFilter = FFTFilterType::New(); fftFilter->SetInput(fftpad->GetOutput()); // Calculate forward transformation typename ForwardWaveletType::Pointer forwardWavelet = ForwardWaveletType::New(); forwardWavelet->SetHighPassSubBands(highSubBands); forwardWavelet->SetLevels(levels); forwardWavelet->SetInput(fftFilter->GetOutput()); forwardWavelet->Update(); - // Obtain target spacing, size and origin typename ComplexImageType::SpacingType inputSpacing; for (unsigned int i = 0; i < Dimension; ++i) { - inputSpacing[i] = image->GetLargestPossibleRegion().GetSize()[i]; + inputSpacing[i] = image->GetSpacing()[i]; } typename ComplexImageType::SpacingType expectedSpacing = inputSpacing; typename ComplexImageType::PointType inputOrigin = image->GetOrigin(); - typename ComplexImageType::PointType expectedOrigin = inputOrigin; - typename ComplexImageType::SizeType inputSize = fftFilter->GetOutput()->GetLargestPossibleRegion().GetSize(); - typename ComplexImageType::SizeType expectedSize = inputSize; + //typename ComplexImageType::PointType expectedOrigin = inputOrigin; + //typename ComplexImageType::SizeType inputSize = fftFilter->GetOutput()->GetLargestPossibleRegion().GetSize(); + //typename ComplexImageType::SizeType expectedSize = inputSize; // Inverse FFT to obtain filtered images typename InverseFFTFilterType::Pointer inverseFFT = InverseFFTFilterType::New(); for (unsigned int level = 0; level < numberOfLevels + 1; ++level) { double scaleFactorPerLevel = std::pow(static_cast< double >(forwardWavelet->GetScaleFactor()),static_cast< double >(level)); for (unsigned int i = 0; i < Dimension; ++i) { - expectedSize[i] = inputSize[i] / scaleFactorPerLevel; - expectedOrigin[i] = inputOrigin[i]; + //expectedOrigin[i] = inputOrigin[i]; expectedSpacing[i] = inputSpacing[i] * scaleFactorPerLevel; } for (unsigned int band = 0; band < highSubBands; ++band) { unsigned int nOutput = level * forwardWavelet->GetHighPassSubBands() + band; // Do not compute bands in low-pass level. if (level == numberOfLevels && band == 0) { nOutput = forwardWavelet->GetTotalOutputs() - 1; } else if (level == numberOfLevels && band != 0) { break; } inverseFFT->SetInput(forwardWavelet->GetOutput(nOutput)); inverseFFT->Update(); auto itkOutputImage = inverseFFT->GetOutput(); + itkOutputImage->SetOrigin(inputOrigin); itkOutputImage->SetSpacing(expectedSpacing); + itkOutputImage->SetDirection(oldDir); mitk::Image::Pointer outputImage = mitk::Image::New(); CastToMitkImage(itkOutputImage, outputImage); resultImages.push_back(outputImage); } } } template static void ExecuteWaveletTransformation(itk::Image* image, unsigned int numberOfLevels, unsigned int numberOfBands, mitk::BorderCondition condition, mitk::WaveletType waveletType, std::vector &resultImages) { typedef itk::Point< double, VImageDimension > PointType; typedef itk::HeldIsotropicWavelet< double, VImageDimension, PointType > HeldIsotropicWaveletType; typedef itk::VowIsotropicWavelet< double, VImageDimension, PointType > VowIsotropicWaveletType; typedef itk::SimoncelliIsotropicWavelet< double, VImageDimension, PointType > SimoncelliIsotropicWaveletType; typedef itk::ShannonIsotropicWavelet< double, VImageDimension, PointType > ShannonIsotropicWaveletType; switch (waveletType) { case mitk::WaveletType::Held: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; case mitk::WaveletType::Shannon: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; case mitk::WaveletType::Simoncelli: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; case mitk::WaveletType::Vow: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; default: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; } } -std::vector mitk::TransformationOperation::WaveletForward(Image::Pointer & image, unsigned int numberOfLevels, unsigned int numberOfBands, mitk::BorderCondition condition, mitk::WaveletType waveletType) +std::vector mitk::TransformationOperation::WaveletForward(Image::Pointer image, unsigned int numberOfLevels, unsigned int numberOfBands, mitk::BorderCondition condition, mitk::WaveletType waveletType) { std::vector resultImages; AccessByItk_n(image, ExecuteWaveletTransformation, (numberOfLevels, numberOfBands, condition, waveletType, resultImages)); return resultImages; } template static void ExecuteImageTypeToDouble(itk::Image* image, mitk::Image::Pointer &outputImage) { typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::Image< double, VImageDimension > DoubleImageType; typedef itk::CastImageFilter< ImageType, DoubleImageType > CastFilterType; typedef itk::ImageDuplicator< DoubleImageType > DuplicatorType; // Perform FFT on input image typename CastFilterType::Pointer castFilter = CastFilterType::New(); castFilter->SetInput(image); castFilter->Update(); typename DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage(castFilter->GetOutput()); duplicator->Update(); CastToMitkImage(duplicator->GetOutput(), outputImage); } template static void ExecuteRoundImage(itk::Image* /*image*/, mitk::Image::Pointer resampledImage, mitk::Image::Pointer &outputImage) { typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::Image< double, VImageDimension > DoubleImageType; typedef itk::UnaryFunctorImageFilter< DoubleImageType, ImageType, mitk::Functor::RoundValue > DefaultFilterType; typename DoubleImageType::Pointer itkImage = DoubleImageType::New(); mitk::CastToItkImage(resampledImage, itkImage); typename DefaultFilterType::Pointer filter = DefaultFilterType::New(); filter->SetInput(itkImage); filter->Update(); CastToMitkImage(filter->GetOutput(), outputImage); } mitk::Image::Pointer mitk::TransformationOperation::ResampleImage(Image::Pointer &image, mitk::Vector3D spacingVector, mitk::ImageMappingInterpolator::Type interpolator, GridInterpolationPositionType position, bool returnAsDouble, bool roundOutput) { // Convert image to double if required mitk::Image::Pointer tmpImage = image; if (returnAsDouble) { AccessByItk_n(image, ExecuteImageTypeToDouble, (tmpImage)); } auto newGeometry = image->GetGeometry()->Clone(); mitk::Vector3D spacing; mitk::BaseGeometry::BoundsArrayType bounds = newGeometry->GetBounds(); for (int i = 0; i < 3; ++i) { spacing[i] = newGeometry->GetSpacing()[i]; //bounds[i*2+1] = newGeometry->GetBounds()[i * 2 + 1]; if (spacingVector[i] > 0) { spacing[i] = spacingVector[i]; if (position == mitk::GridInterpolationPositionType::SameSize) { unsigned int samples = image->GetDimensions()[i]; double currentSpacing = newGeometry->GetSpacing()[i]; double newFactor = std::floor(samples*currentSpacing / spacingVector[i]); spacing[i] = samples * currentSpacing / newFactor; } } bounds[i * 2] = 0; bounds[i*2+1] = std::ceil(bounds[i*2+1] * newGeometry->GetSpacing()[i] *1.0 / spacing[i]); } mitk::Point3D origin = newGeometry->GetOrigin(); if (position == mitk::GridInterpolationPositionType::CenterAligned) { for (int i = 0; i < 3; ++i) { - double oldLength = newGeometry->GetSpacing()[i] * newGeometry->GetBounds()[i*2+1]; - double newLength = spacing[i] * bounds[i*2+1]; + double oldLength = newGeometry->GetSpacing()[i] * (newGeometry->GetBounds()[i*2+1] - 1); + double newLength = spacing[i] * (bounds[i*2+1] - 1); origin[i] = origin[i] - (newLength - oldLength) / 2; } } newGeometry->SetSpacing(spacing); newGeometry->SetOrigin(origin); newGeometry->SetBounds(bounds); mitk::Image::Pointer tmpResult = ImageMappingHelper::map( tmpImage, mitk::GenerateIdentityRegistration3D().GetPointer(), false, 0.0, //Padding Value newGeometry.GetPointer(), false, 0, //Error Value interpolator ); mitk::Image::Pointer result = mitk::Image::New(); if (roundOutput) { AccessByItk_n(tmpImage, ExecuteRoundImage, (tmpResult, result)); } else { result = tmpResult; } return result; } template static void ExecuteImageThresholding(itk::Image* image, mitk::Image::Pointer &resultImage) { typedef itk::Image ImageType; typedef itk::Image MaskType; typedef itk::UnaryFunctorImageFilter< ImageType, MaskType, mitk::Functor::ThresholdValue > DefaultFilterType; typename DefaultFilterType::Pointer filter = DefaultFilterType::New(); filter->SetInput(image); filter->GetFunctor().value = 0.5; filter->Update(); CastToMitkImage(filter->GetOutput(), resultImage); } mitk::Image::Pointer mitk::TransformationOperation::ResampleMask(Image::Pointer &image, mitk::Vector3D spacingVector, mitk::ImageMappingInterpolator::Type interpolator, GridInterpolationPositionType position) { mitk::Image::Pointer result; if (interpolator == mitk::ImageMappingInterpolator::NearestNeighbor) { result = TransformationOperation::ResampleImage(image, spacingVector, interpolator, position, false, false); } else { auto tmpResult = TransformationOperation::ResampleImage(image, spacingVector, interpolator, position, true, false); AccessByItk_n(tmpResult, ExecuteImageThresholding, (result)); } return result; } +mitk::Image::Pointer mitk::TransformationOperation::CastToUnsignedChar(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(unsigned char); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToSignedChar(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(signed char); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToChar(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(char); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToUnsignedShort(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(unsigned short int); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToShort(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(short int); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToUnsignedInt(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(unsigned int); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToInt(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(int); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToUnsignedLong(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(unsigned long int); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToLong(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(long int); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToFloat(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(float); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + +mitk::Image::Pointer mitk::TransformationOperation::CastToDouble(Image::Pointer image, int &error) +{ + mitk::Image::Pointer result; + std::type_index type = typeid(double); + AccessByItk_n(image, ExecuteConvertToGivenType, (type, result, error)); + return result; +} + + + + namespace itk { namespace utils { IndexPairType IndexToLevelBandSteerablePyramid(unsigned int linearIndex, unsigned int levels, unsigned int bands) { unsigned int totalOutputs = 1 + levels * bands; if (linearIndex > totalOutputs - 1) { itkGenericExceptionMacro(<< "Failed converting linearIndex " << linearIndex << " with levels: " << levels << " bands: " << bands << " to Level,Band pair : out of bounds"); } // Low pass (band = 0). if (linearIndex == totalOutputs - 1) { return std::make_pair(levels - 1, 0); } unsigned int band = (linearIndex) % bands + 1; // note integer division ahead. unsigned int level = (linearIndex) / bands; itkAssertInDebugAndIgnoreInReleaseMacro(level < levels); return std::make_pair(level, band); } // Instantiation template unsigned int ComputeMaxNumberOfLevels<3>(const Size< 3 >& inputSize, const unsigned int & scaleFactor); template unsigned int ComputeMaxNumberOfLevels<2>(const Size< 2 >& inputSize, const unsigned int & scaleFactor); } // end namespace utils } // end namespace itk diff --git a/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h b/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h index 362dcd73bf..772ff8fe50 100644 --- a/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h +++ b/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h @@ -1,295 +1,304 @@ /*=================================================================== 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 mitkAbstractGlobalImageFeature_h #define mitkAbstractGlobalImageFeature_h #include #include #include #include #include // STD Includes // Eigen #include // MITK includes #include namespace mitk { /** * * * ## Histogram Configuration ## * Most Feature Generation Classes that use histograms use the same parameters and * initialization logic. In general, all information can be passed either by the corresponding * Setter (which does not differenciate between global setting and feature specific setting) and * a parameter object which can be obtained from the command line arguments, for example. * * If the image values are used for the initializiation of the histogram, it can be defined * whether the whole image is used or only the masked areas to find minima and maxima. This is * done by the option SetIgnoreMask or the corrsponding options * -NAME::ignore-mask-for-histogram and -ignore-mask-for-histogram. If these are * true, the whole image is used for the calculation. * * Depending on the passed arguments, different initialization methods are used. The initialization * is in the following order: * - If Minimum Intensity, Maximum Intensity, and Binsize: The histogram is * initialized between the minimum and maximum intensity. the number of bins is determined by the * binsize. If the distance between minimum and maximum is not a multiple of the binsize, the maximum * is increase so that it is. * - Minimum Intensity, Bins, and Binsize: The histogram is initialized with the * given binsize, and the intensity range from the minimum to \f$maximum = minimum + binsize*bins\f$. * - Minimum Intensity, Maximum Intensity, and Bins: The histogram is initialized * between the given minimum and maximum intensity. The binsize is calculated so that the number * of bins is equal to the given number of bins. * - Binsize, and Minimum Intensity: The maximum is set to the maximum that * occur in the given image. Depending if the mask is considered or not, either only masked voxels or * the whole image is used for the calculation. The initialization is then equal as if the minimum * and maximum would have been given right from the beginning. * - Binsize, and Maximum Intensity: The minimum intensity is set to the minimum that * occur in the given image. Depending if the mask is considered or not, either only masked voxels or * the whole image is used for the calculation. The initialization is then equal as if the minimum * and maximum would have been given right from the beginning. * - Binsize: The maximum and the minimum intensity is set to the minimum and maximum that * occur in the given image. Depending if the mask is considered or not, either only masked voxels or * the whole image is used for the calculation. The initialization is then equal as if the minimum * and maximum would have been given right from the beginning. * - Bins, and Minimum Intensity: The maximum is calculated from the image. Depending * if the mask is considered or not, either only masked voxels or the whole image is used for the calculation. The histogram is * then initialized as if these values would have been given as minimum and maximum intensity. * - Bins, and Maximum Intensity: The minimum is calculated from the image. Depending * if the mask is considered or not, either only masked voxels or the whole image is used for the calculation. The histogram is * then initialized as if these values would have been given as minimum and maximum intensity. * - Bins: The minimum and the maximum is calculated from the image. Depending * if the mask is considered or not, either only masked voxels or * the whole image is used for the calculation. The histogram is * then initialized as if these values would have been given as minimum and maximum intensity. * - No Parameter given:The minimum and maximum intensity from the whole image or masked image is calculated and * the histogram then initialized to this with a standard number of bins (Is set by each filter on its own.) * + * If a fixed binsize is used, it is possible to shift the minimum value by half of a binsize. A use-case for this + * is using a histomgram which is centred around integer values. This option is activated by the parameter + * NAME::correct-for-binsize + * * ### Remark about command line parameter#### * There are generally two options to set a parameter via the command line. A global one that works for * all filters that use histograms and a local one that set this parameter specific for this filter. The * local parameters start with the filter name (Indiciated by NAME) followed by two colons, for example * vol::min to set the minimum intensity for the volume filter. The global parameter is overwritten * by the local parameter, if it is specified. Otherwise, it is still valid. If this prevents the specification * of an histogram initialization method (for example, because the binsize is globally specified but the histogram * should be initialized using a fixed numbe of bins), the parameter NAME::ignore-global-histogram can be passed. * Then, all global histogram parameters are ignored and only local ones are used. * * The maximum intensity can be set by different command line parameters: global for all filters that use histograms * by -minimum-intensity and -minimum. Alternative it can be set only for this filter by * -NAME::minimum and -NAME::min. * * The minimum intensity can be set by different command line parameters: global for all filters that use histograms * by -maximum-intensity and -maximum. Alternative it can be set only for this filter by * \NAME::maximum and NAME::max. * * The binsize can be set by different command line parameters: global for all filters that use histograms * by -binsize. Alternative it can be set only for this filter by * \NAME::binsize. * * The number of bins can be set by different command line parameters: global for all filters that use histograms * by -bins. Alternative it can be set only for this filter by * \NAME::bins. * ### Note to the developers ### * All features are supposed to work the same way if a histogram is used somewhere in * the code. For this, each derived class that makes use of a histogram should use * the Quantifier object. In order to use this object correctly, the AddArguments-Function should * contain the line AddQuantifierArguments(parser);, the CalculateFeaturesUsingParameters function * should contain the line InitializeQuantifierFromParameters(feature, mask); and the CalculateFeatures function * sould contain the line InitializeQuantifier(image, mask);. These function * calls ensure that the necessary options are given to the configuration file, and that the initialization * of the quantifier is done correctly. This ensures an consistend behavior over all FeatureGeneration Classes. * */ class MITKCLCORE_EXPORT AbstractGlobalImageFeature : public BaseData { public: mitkClassMacro(AbstractGlobalImageFeature, BaseData) typedef std::vector< std::pair > FeatureListType; typedef std::vector< std::string> FeatureNameListType; typedef std::map ParameterTypes; /** * \brief Calculates the feature of this abstact interface. Does not necessarily considers the parameter settings. */ virtual FeatureListType CalculateFeatures(const Image::Pointer & feature, const Image::Pointer &mask) = 0; /** * \brief Calculates the given feature Slice-wise. Might not be availble for an individual filter! */ FeatureListType CalculateFeaturesSlicewise(const Image::Pointer & feature, const Image::Pointer &mask, int sliceID); /** * \brief Calculates the feature of this abstact interface. Does not necessarily considers the parameter settings. */ virtual void CalculateFeaturesSliceWiseUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, int sliceID, FeatureListType &featureList); /** * \brief Calculates the feature of this abstact interface. Does not necessarily considers the parameter settings. */ virtual void CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &maskNoNAN, FeatureListType &featureList) = 0; /** * \brief Returns a list of the names of all features that are calculated from this class */ virtual FeatureNameListType GetFeatureNames() = 0; /** * \brief Adds an additional Separator to the name of the feature, which encodes the used parameters */ virtual std::string GetCurrentFeatureEncoding(); /** * \brief Returns a string that encodes the feature class name. * * This Feature returns a string that should be put before every other feature * value. It has the format [::]::[::]. * The options and are only added, if the corresponding * options are set. */ std::string FeatureDescriptionPrefix(); itkSetMacro(Prefix, std::string); itkSetMacro(ShortName, std::string); itkSetMacro(LongName, std::string); itkSetMacro(FeatureClassName, std::string); itkSetMacro(Direction, int); void SetParameter(ParameterTypes param) { m_Parameter=param; }; itkGetConstMacro(Prefix, std::string); itkGetConstMacro(ShortName, std::string); itkGetConstMacro(LongName, std::string); itkGetConstMacro(FeatureClassName, std::string); itkGetConstMacro(Parameter, ParameterTypes); itkSetMacro(UseQuantifier, bool); itkGetConstMacro(UseQuantifier, bool); itkSetMacro(Quantifier, IntensityQuantifier::Pointer); itkGetMacro(Quantifier, IntensityQuantifier::Pointer); itkGetConstMacro(Direction, int); itkSetMacro(MinimumIntensity, double); itkSetMacro(UseMinimumIntensity, bool); itkSetMacro(MaximumIntensity, double); itkSetMacro(UseMaximumIntensity, bool); itkGetConstMacro(MinimumIntensity, double); itkGetConstMacro(UseMinimumIntensity, bool); itkGetConstMacro(MaximumIntensity, double); itkGetConstMacro(UseMaximumIntensity, bool); itkSetMacro(Binsize, double); itkSetMacro(UseBinsize, bool); itkGetConstMacro(Binsize, double); itkGetConstMacro(UseBinsize, bool); - itkSetMacro(MorphMask, mitk::Image::Pointer); - itkGetConstMacro(MorphMask, mitk::Image::Pointer); + itkSetObjectMacro(MorphMask, mitk::Image); + itkGetObjectMacro(MorphMask, mitk::Image); itkSetMacro(Bins, int); itkSetMacro(UseBins, bool); itkGetConstMacro(UseBins, bool); itkGetConstMacro(Bins, int); itkSetMacro(IgnoreMask, bool); itkGetConstMacro(IgnoreMask, bool); itkSetMacro(EncodeParameters, bool); itkGetConstMacro(EncodeParameters, bool); + itkSetMacro(CorrectForBinsize, bool); + itkGetConstMacro(CorrectForBinsize, bool); + std::string GetOptionPrefix() const { if (m_Prefix.length() > 0) return m_Prefix + "::" + m_ShortName; return m_ShortName; } virtual void AddArguments(mitkCommandLineParser &parser) = 0; std::vector SplitDouble(std::string str, char delimiter); void AddQuantifierArguments(mitkCommandLineParser &parser); void InitializeQuantifierFromParameters(const Image::Pointer & feature, const Image::Pointer &mask,unsigned int defaultBins = 256); void InitializeQuantifier(const Image::Pointer & feature, const Image::Pointer &mask, unsigned int defaultBins = 256); std::string QuantifierParameterString(); public: //#ifndef DOXYGEN_SKIP void SetRequestedRegionToLargestPossibleRegion() override {}; bool RequestedRegionIsOutsideOfTheBufferedRegion() override { return true; }; bool VerifyRequestedRegion() override { return false; }; void SetRequestedRegion (const itk::DataObject * /*data*/) override {}; // Override bool IsEmpty() const override { if(IsInitialized() == false) return true; const TimeGeometry* timeGeometry = const_cast(this)->GetUpdatedTimeGeometry(); if(timeGeometry == nullptr) return true; return false; } private: std::string m_Prefix; // Prefix before all input parameters std::string m_ShortName; // Name of all variables std::string m_LongName; // Long version of the name (For turning on) std::string m_FeatureClassName; ParameterTypes m_Parameter; // Parameter setting bool m_UseQuantifier = false; IntensityQuantifier::Pointer m_Quantifier; double m_MinimumIntensity = 0; bool m_UseMinimumIntensity = false; double m_MaximumIntensity = 100; bool m_UseMaximumIntensity = false; bool m_EncodeParameters = false; double m_Binsize = 1; bool m_UseBinsize = false; int m_Bins = 256; bool m_UseBins = true; int m_Direction = 0; bool m_IgnoreMask = false; bool m_CalculateWithParameter = false; + bool m_CorrectForBinsize = false; + mitk::Image::Pointer m_MorphMask = nullptr; //#endif // Skip Doxygen }; } #endif //mitkAbstractGlobalImageFeature_h diff --git a/Modules/Classification/CLCore/include/mitkIntensityQuantifier.h b/Modules/Classification/CLCore/include/mitkIntensityQuantifier.h index 306848c10b..12609fe2d5 100644 --- a/Modules/Classification/CLCore/include/mitkIntensityQuantifier.h +++ b/Modules/Classification/CLCore/include/mitkIntensityQuantifier.h @@ -1,95 +1,96 @@ /*=================================================================== 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 mitkIntensityQuantifier_h #define mitkIntensityQuantifier_h #include #include #include namespace mitk { class MITKCLCORE_EXPORT IntensityQuantifier : public BaseData { public: mitkClassMacro(IntensityQuantifier, BaseData) itkFactorylessNewMacro(Self) itkCloneMacro(Self) IntensityQuantifier(); void InitializeByMinimumMaximum(double minimum, double maximum, unsigned int bins); void InitializeByBinsizeAndBins(double minimum, unsigned int bins, double binsize); void InitializeByBinsizeAndMaximum(double minimum, double maximum, double binsize); void InitializeByImage(mitk::Image::Pointer image, unsigned int bins); void InitializeByImageAndMaximum(mitk::Image::Pointer image, double maximum, unsigned int bins); void InitializeByImageAndMinimum(mitk::Image::Pointer image, double minimum, unsigned int bins); void InitializeByImageRegion(mitk::Image::Pointer image, mitk::Image::Pointer mask, unsigned int bins); void InitializeByImageRegionAndMinimum(mitk::Image::Pointer image, mitk::Image::Pointer mask, double minimum, unsigned int bins); void InitializeByImageRegionAndMaximum(mitk::Image::Pointer image, mitk::Image::Pointer mask, double maximum, unsigned int bins); void InitializeByImageAndBinsize(mitk::Image::Pointer image, double binsize); void InitializeByImageAndBinsizeAndMinimum(mitk::Image::Pointer image, double minimum, double binsize); void InitializeByImageAndBinsizeAndMaximum(mitk::Image::Pointer image, double maximum, double binsize); void InitializeByImageRegionAndBinsize(mitk::Image::Pointer image, mitk::Image::Pointer mask, double binsize); void InitializeByImageRegionAndBinsizeAndMinimum(mitk::Image::Pointer image, mitk::Image::Pointer mask, double minimum, double binsize); void InitializeByImageRegionAndBinsizeAndMaximum(mitk::Image::Pointer image, mitk::Image::Pointer mask, double maximum, double binsize); unsigned int IntensityToIndex(double intensity); double IndexToMinimumIntensity(unsigned int index); double IndexToMeanIntensity(unsigned int index); double IndexToMaximumIntensity(unsigned int index); itkGetConstMacro(Initialized, bool); itkGetConstMacro(Bins, unsigned int); itkGetConstMacro(Binsize, double); itkGetConstMacro(Minimum, double); itkGetConstMacro(Maximum, double); - + itkGetConstMacro(CorrectForBinsize, bool); + itkSetMacro(CorrectForBinsize, bool); public: //#ifndef DOXYGEN_SKIP virtual void SetRequestedRegionToLargestPossibleRegion() override {}; virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() override { return true; }; virtual bool VerifyRequestedRegion() override { return false; }; virtual void SetRequestedRegion (const itk::DataObject * /*data*/) override {}; // Override virtual bool IsEmpty() const override { if(IsInitialized() == false) return true; const TimeGeometry* timeGeometry = const_cast(this)->GetUpdatedTimeGeometry(); if(timeGeometry == nullptr) return true; return false; } private: bool m_Initialized; unsigned int m_Bins; double m_Binsize; double m_Minimum; double m_Maximum; - + bool m_CorrectForBinsize; }; } #endif //mitkIntensityQuantifier_h diff --git a/Modules/Classification/CLCore/src/mitkAbstractGlobalImageFeature.cpp b/Modules/Classification/CLCore/src/mitkAbstractGlobalImageFeature.cpp index 5920b99ce2..06a68a3eb7 100644 --- a/Modules/Classification/CLCore/src/mitkAbstractGlobalImageFeature.cpp +++ b/Modules/Classification/CLCore/src/mitkAbstractGlobalImageFeature.cpp @@ -1,406 +1,436 @@ /*=================================================================== 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 #include #include #include static void ExtractSlicesFromImages(mitk::Image::Pointer image, mitk::Image::Pointer mask, int direction, std::vector &imageVector, std::vector &maskVector) { typedef itk::Image< double, 2 > FloatImage2DType; typedef itk::Image< unsigned short, 2 > MaskImage2DType; typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned short, 3 > MaskImageType; FloatImageType::Pointer itkFloat = FloatImageType::New(); MaskImageType::Pointer itkMask = MaskImageType::New(); mitk::CastToItkImage(mask, itkMask); mitk::CastToItkImage(image, itkFloat); int idxA, idxB, idxC; switch (direction) { case 0: idxA = 1; idxB = 2; idxC = 0; break; case 1: idxA = 0; idxB = 2; idxC = 1; break; case 2: idxA = 0; idxB = 1; idxC = 2; break; default: idxA = 1; idxB = 2; idxC = 0; break; } auto imageSize = image->GetLargestPossibleRegion().GetSize(); FloatImageType::IndexType index3D; FloatImage2DType::IndexType index2D; FloatImage2DType::SpacingType spacing2D; spacing2D[0] = itkFloat->GetSpacing()[idxA]; spacing2D[1] = itkFloat->GetSpacing()[idxB]; for (unsigned int i = 0; i < imageSize[idxC]; ++i) { FloatImage2DType::RegionType region; FloatImage2DType::IndexType start; FloatImage2DType::SizeType size; start[0] = 0; start[1] = 0; size[0] = imageSize[idxA]; size[1] = imageSize[idxB]; region.SetIndex(start); region.SetSize(size); FloatImage2DType::Pointer image2D = FloatImage2DType::New(); image2D->SetRegions(region); image2D->Allocate(); MaskImage2DType::Pointer mask2D = MaskImage2DType::New(); mask2D->SetRegions(region); mask2D->Allocate(); unsigned long voxelsInMask = 0; for (unsigned int a = 0; a < imageSize[idxA]; ++a) { for (unsigned int b = 0; b < imageSize[idxB]; ++b) { index3D[idxA] = a; index3D[idxB] = b; index3D[idxC] = i; index2D[0] = a; index2D[1] = b; image2D->SetPixel(index2D, itkFloat->GetPixel(index3D)); mask2D->SetPixel(index2D, itkMask->GetPixel(index3D)); voxelsInMask += (itkMask->GetPixel(index3D) > 0) ? 1 : 0; } } image2D->SetSpacing(spacing2D); mask2D->SetSpacing(spacing2D); mitk::Image::Pointer tmpFloatImage = mitk::Image::New(); tmpFloatImage->InitializeByItk(image2D.GetPointer()); mitk::GrabItkImageMemory(image2D, tmpFloatImage); mitk::Image::Pointer tmpMaskImage = mitk::Image::New(); tmpMaskImage->InitializeByItk(mask2D.GetPointer()); mitk::GrabItkImageMemory(mask2D, tmpMaskImage); if (voxelsInMask > 0) { imageVector.push_back(tmpFloatImage); maskVector.push_back(tmpMaskImage); } } } std::vector mitk::AbstractGlobalImageFeature::SplitDouble(std::string str, char delimiter) { std::vector internal; std::stringstream ss(str); // Turn the string into a stream. std::string tok; double val; while (std::getline(ss, tok, delimiter)) { std::stringstream s2(tok); s2 >> val; internal.push_back(val); } return internal; } void mitk::AbstractGlobalImageFeature::AddQuantifierArguments(mitkCommandLineParser &parser) { std::string name = GetOptionPrefix(); parser.addArgument(name + "::minimum", name + "::min", mitkCommandLineParser::Float, "Minium Intensity for Quantification", "Defines the minimum Intensity used for Quantification", us::Any()); parser.addArgument(name + "::maximum", name + "::max", mitkCommandLineParser::Float, "Maximum Intensity for Quantification", "Defines the maximum Intensity used for Quantification", us::Any()); parser.addArgument(name + "::bins", name + "::bins", mitkCommandLineParser::Int, "Number of Bins", "Define the number of bins that is used ", us::Any()); parser.addArgument(name + "::binsize", name + "::binsize", mitkCommandLineParser::Float, "Binsize", "Define the size of the used bins", us::Any()); parser.addArgument(name + "::ignore-global-histogram", name + "::ignore-global-histogram", mitkCommandLineParser::Bool, "Ignore the global histogram Parameters", "Ignores the global histogram parameters", us::Any()); parser.addArgument(name + "::ignore-mask-for-histogram", name + "::ignore-mask", mitkCommandLineParser::Bool, "Ignore the global histogram Parameters", "Ignores the global histogram parameters", us::Any()); - + parser.addArgument(name + "::correct-for-binsize", name + "::correct-for-binsize", mitkCommandLineParser::Bool, "Shift the minimum value by half the binsize", "Shift the minimum value by half a binsize", us::Any()); } void mitk::AbstractGlobalImageFeature::InitializeQuantifierFromParameters(const Image::Pointer & feature, const Image::Pointer &mask, unsigned int defaultBins) { unsigned int bins = 0; double binsize = 0; double minimum = 0; double maximum = 0; auto parsedArgs = GetParameter(); std::string name = GetOptionPrefix(); bool useGlobal = true; if (parsedArgs.count(name + "::ignore-global-histogram")) { useGlobal = false; SetUseMinimumIntensity(false); SetUseMaximumIntensity(false); SetUseBinsize(false); SetUseBins(false); } if (useGlobal) { if (parsedArgs.count("ignore-mask-for-histogram")) { bool tmp = us::any_cast(parsedArgs["ignore-mask-for-histogram"]); SetIgnoreMask(tmp); } if (parsedArgs.count("minimum-intensity")) { minimum = us::any_cast(parsedArgs["minimum-intensity"]); SetMinimumIntensity(minimum); SetUseMinimumIntensity(true); } if (parsedArgs.count("maximum-intensity")) { maximum = us::any_cast(parsedArgs["maximum-intensity"]); SetMaximumIntensity(maximum); SetUseMaximumIntensity(true); } if (parsedArgs.count("bins")) { bins = us::any_cast(parsedArgs["bins"]); SetBins(bins); SetUseBins(true); } if (parsedArgs.count("binsize")) { binsize = us::any_cast(parsedArgs["binsize"]); SetBinsize(binsize); SetUseBinsize(true); } + if (parsedArgs.count("correct-for-binsize")) + { + bool tmp = us::any_cast(parsedArgs["correct-for-binsize"]); + SetCorrectForBinsize(tmp); + } } if (parsedArgs.count(name+"::ignore-mask-for-histogram")) { bool tmp = us::any_cast(parsedArgs[name+"::ignore-mask-for-histogram"]); SetIgnoreMask(tmp); } if (parsedArgs.count(name + "::minimum")) { minimum = us::any_cast(parsedArgs[name + "::minimum"]); SetMinimumIntensity(minimum); SetUseMinimumIntensity(true); } if (parsedArgs.count(name + "::maximum")) { maximum = us::any_cast(parsedArgs[name + "::maximum"]); SetMaximumIntensity(maximum); SetUseMaximumIntensity(true); } if (parsedArgs.count(name + "::bins")) { bins = us::any_cast(parsedArgs[name + "::bins"]); SetBins(bins); } if (parsedArgs.count(name + "::binsize")) { binsize = us::any_cast(parsedArgs[name + "::binsize"]); SetBinsize(binsize); SetUseBinsize(true); } + if (parsedArgs.count(name+"::correct-for-binsize")) + { + bool tmp = us::any_cast(parsedArgs[name + "::correct-for-binsize"]); + SetCorrectForBinsize(tmp); + } InitializeQuantifier(feature, mask, defaultBins); } void mitk::AbstractGlobalImageFeature::InitializeQuantifier(const Image::Pointer & feature, const Image::Pointer &mask, unsigned int defaultBins) { m_Quantifier = IntensityQuantifier::New(); + m_Quantifier->SetCorrectForBinsize(this->GetCorrectForBinsize()); if (GetUseMinimumIntensity() && GetUseMaximumIntensity() && GetUseBinsize()) m_Quantifier->InitializeByBinsizeAndMaximum(GetMinimumIntensity(), GetMaximumIntensity(), GetBinsize()); else if (GetUseMinimumIntensity() && GetUseBins() && GetUseBinsize()) m_Quantifier->InitializeByBinsizeAndBins(GetMinimumIntensity(), GetBins(), GetBinsize()); else if (GetUseMinimumIntensity() && GetUseMaximumIntensity() && GetUseBins()) m_Quantifier->InitializeByMinimumMaximum(GetMinimumIntensity(), GetMaximumIntensity(), GetBins()); // Intialize from Image and Binsize else if (GetUseBinsize() && GetIgnoreMask() && GetUseMinimumIntensity()) m_Quantifier->InitializeByImageAndBinsizeAndMinimum(feature, GetMinimumIntensity(), GetBinsize()); else if (GetUseBinsize() && GetIgnoreMask() && GetUseMaximumIntensity()) m_Quantifier->InitializeByImageAndBinsizeAndMaximum(feature, GetMaximumIntensity(), GetBinsize()); else if (GetUseBinsize() && GetIgnoreMask()) m_Quantifier->InitializeByImageAndBinsize(feature, GetBinsize()); // Initialize form Image, Mask and Binsize else if (GetUseBinsize() && GetUseMinimumIntensity()) m_Quantifier->InitializeByImageRegionAndBinsizeAndMinimum(feature, mask, GetMinimumIntensity(), GetBinsize()); else if (GetUseBinsize() && GetUseMaximumIntensity()) m_Quantifier->InitializeByImageRegionAndBinsizeAndMaximum(feature, mask, GetMaximumIntensity(), GetBinsize()); else if (GetUseBinsize()) m_Quantifier->InitializeByImageRegionAndBinsize(feature, mask, GetBinsize()); // Intialize from Image and Bins else if (GetUseBins() && GetIgnoreMask() && GetUseMinimumIntensity()) m_Quantifier->InitializeByImageAndMinimum(feature, GetMinimumIntensity(), GetBins()); else if (GetUseBins() && GetIgnoreMask() && GetUseMaximumIntensity()) m_Quantifier->InitializeByImageAndMaximum(feature, GetMaximumIntensity(), GetBins()); - else if (GetUseBins()) + else if (GetUseBins() && GetIgnoreMask()) m_Quantifier->InitializeByImage(feature, GetBins()); // Intialize from Image, Mask and Bins else if (GetUseBins() && GetUseMinimumIntensity()) m_Quantifier->InitializeByImageRegionAndMinimum(feature, mask, GetMinimumIntensity(), GetBins()); else if (GetUseBins() && GetUseMaximumIntensity()) m_Quantifier->InitializeByImageRegionAndMaximum(feature, mask, GetMaximumIntensity(), GetBins()); - else if (GetUseBins()) + else if (GetUseBins() ) m_Quantifier->InitializeByImageRegion(feature, mask, GetBins()); // Default else if (GetIgnoreMask()) - m_Quantifier->InitializeByImage(feature, GetBins()); + m_Quantifier->InitializeByImage(feature, defaultBins); else m_Quantifier->InitializeByImageRegion(feature, mask, defaultBins); } std::string mitk::AbstractGlobalImageFeature::GetCurrentFeatureEncoding() { return ""; } std::string mitk::AbstractGlobalImageFeature::FeatureDescriptionPrefix() { std::string output; output = m_FeatureClassName + "::"; if (m_EncodeParameters) { output += GetCurrentFeatureEncoding() + "::"; } return output; } std::string mitk::AbstractGlobalImageFeature::QuantifierParameterString() { std::stringstream ss; if (GetUseMinimumIntensity() && GetUseMaximumIntensity() && GetUseBinsize()) ss << "Min-" << GetMinimumIntensity() << "_Max-" << GetMaximumIntensity() << "_BS-" << GetBinsize(); else if (GetUseMinimumIntensity() && GetUseBins() && GetUseBinsize()) ss << "Min-" << GetMinimumIntensity() << "_Bins-" << GetBins() << "_BS-" << GetBinsize(); else if (GetUseMinimumIntensity() && GetUseMaximumIntensity() && GetUseBins()) ss << "Min-" << GetMinimumIntensity() << "_Max-" << GetMaximumIntensity() << "_Bins-" << GetBins(); // Intialize from Image and Binsize else if (GetUseBinsize() && GetIgnoreMask() && GetUseMinimumIntensity()) ss << "Min-" << GetMinimumIntensity() << "_BS-" << GetBinsize() << "_FullImage"; else if (GetUseBinsize() && GetIgnoreMask() && GetUseMaximumIntensity()) ss << "Max-" << GetMaximumIntensity() << "_BS-" << GetBinsize() << "_FullImage"; else if (GetUseBinsize() && GetIgnoreMask()) ss << "BS-" << GetBinsize() << "_FullImage"; // Initialize form Image, Mask and Binsize else if (GetUseBinsize() && GetUseMinimumIntensity()) ss << "Min-" << GetMinimumIntensity() << "_BS-" << GetBinsize(); else if (GetUseBinsize() && GetUseMaximumIntensity()) ss << "Max-" << GetMaximumIntensity() << "_BS-" << GetBinsize(); else if (GetUseBinsize()) ss << "BS-" << GetBinsize(); // Intialize from Image and Bins else if (GetUseBins() && GetIgnoreMask() && GetUseMinimumIntensity()) ss << "Min-" << GetMinimumIntensity() << "_Bins-" << GetBins() << "_FullImage"; else if (GetUseBins() && GetIgnoreMask() && GetUseMaximumIntensity()) ss << "Max-" << GetMaximumIntensity() << "_Bins-" << GetBins() << "_FullImage"; else if (GetUseBins()) ss << "Bins-" << GetBins() << "_FullImage"; // Intialize from Image, Mask and Bins else if (GetUseBins() && GetUseMinimumIntensity()) ss << "Min-" << GetMinimumIntensity() << "_Bins-" << GetBins(); else if (GetUseBins() && GetUseMaximumIntensity()) ss << "Max-" << GetMaximumIntensity() << "_Bins-" << GetBins(); else if (GetUseBins()) ss << "Bins-" << GetBins(); // Default else if (GetIgnoreMask()) ss << "Bins-" << GetBins() << "_FullImage"; else ss << "Bins-" << GetBins(); return ss.str(); } void mitk::AbstractGlobalImageFeature::CalculateFeaturesSliceWiseUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, int sliceID, FeatureListType &featureList) { m_CalculateWithParameter = true; auto result = CalculateFeaturesSlicewise(feature, mask, sliceID); featureList.insert(featureList.end(), result.begin(), result.end()); } mitk::AbstractGlobalImageFeature::FeatureListType mitk::AbstractGlobalImageFeature::CalculateFeaturesSlicewise(const Image::Pointer & feature, const Image::Pointer &mask, int sliceID) { std::vector imageVector; std::vector maskVector; + std::vector morphMaskVector; ExtractSlicesFromImages(feature, mask,sliceID, imageVector, maskVector); std::vector statVector; + bool morphMaskIsNotNull = (GetMorphMask() != NULL); + mitk::Image::Pointer morphMask; + if (morphMaskIsNotNull) + { + morphMask = this->GetMorphMask(); + std::vector tmpVector; + ExtractSlicesFromImages(feature, morphMask, sliceID, tmpVector, morphMaskVector); + } + for (std::size_t index = 0; index < imageVector.size(); ++index) { + if (morphMaskIsNotNull) + { + this->SetMorphMask(morphMaskVector[index].GetPointer()); + } if (m_CalculateWithParameter) { FeatureListType stat; this->CalculateFeaturesUsingParameters(imageVector[index], maskVector[index], maskVector[index], stat); statVector.push_back(stat); } else { auto stat = this->CalculateFeatures(imageVector[index], maskVector[index]); statVector.push_back(stat); } } + if (morphMaskIsNotNull) + { + this->SetMorphMask(morphMask.GetPointer()); + } + if (statVector.size() < 1) return FeatureListType(); FeatureListType statMean, statStd, result; for (std::size_t i = 0; i < statVector[0].size(); ++i) { auto cElement1 = statVector[0][i]; cElement1.first = "SliceWise Mean " + cElement1.first; cElement1.second = 0.0; auto cElement2 = statVector[0][i]; cElement2.first = "SliceWise Var. " + cElement2.first; cElement2.second = 0.0; statMean.push_back(cElement1); statStd.push_back(cElement2); } for (auto cStat : statVector) { for (std::size_t i = 0; i < cStat.size(); ++i) { statMean[i].second += cStat[i].second / (1.0*statVector.size()); } } for (auto cStat : statVector) { for (std::size_t i = 0; i < cStat.size(); ++i) { statStd[i].second += (cStat[i].second - statMean[i].second)*(cStat[i].second - statMean[i].second) / (1.0*statVector.size()); } } for (auto cStat : statVector) { std::copy(cStat.begin(), cStat.end(), std::back_inserter(result)); } std::copy(statMean.begin(), statMean.end(), std::back_inserter(result)); std::copy(statStd.begin(), statStd.end(), std::back_inserter(result)); return result; } \ No newline at end of file diff --git a/Modules/Classification/CLCore/src/mitkIntensityQuantifier.cpp b/Modules/Classification/CLCore/src/mitkIntensityQuantifier.cpp index cbe0ec2536..96e389ba12 100644 --- a/Modules/Classification/CLCore/src/mitkIntensityQuantifier.cpp +++ b/Modules/Classification/CLCore/src/mitkIntensityQuantifier.cpp @@ -1,199 +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 // STD #include // ITK #include // MITK #include #include template static void CalculateImageMinMax(itk::Image* itkImage, double &minimum, double &maximum) { typedef itk::Image ImageType; minimum = std::numeric_limits::max(); maximum = std::numeric_limits::lowest(); itk::ImageRegionConstIterator iter(itkImage, itkImage->GetLargestPossibleRegion()); while (!iter.IsAtEnd()) { minimum = std::min(minimum, iter.Get()); maximum = std::max(maximum, iter.Get()); ++iter; } } template static void CalculateImageRegionMinMax(itk::Image* itkImage, mitk::Image::Pointer mask, double &minimum, double &maximum) { typedef itk::Image ImageType; typedef itk::Image MaskType; typename MaskType::Pointer itkMask = MaskType::New(); mitk::CastToItkImage(mask, itkMask); minimum = std::numeric_limits::max(); maximum = std::numeric_limits::lowest(); itk::ImageRegionConstIterator iter(itkImage, itkImage->GetLargestPossibleRegion()); itk::ImageRegionConstIterator maskIter(itkMask, itkMask->GetLargestPossibleRegion()); while (!iter.IsAtEnd()) { if (maskIter.Get() > 0) { minimum = std::min(minimum, iter.Get()); maximum = std::max(maximum, iter.Get()); } ++iter; ++maskIter; } } mitk::IntensityQuantifier::IntensityQuantifier() : - m_Initialized(false), - m_Bins(0), - m_Binsize(0), - m_Minimum(0), - m_Maximum(0) + m_Initialized(false), + m_Bins(0), + m_Binsize(0), + m_Minimum(0), + m_Maximum(0), + m_CorrectForBinsize(false) {} void mitk::IntensityQuantifier::InitializeByMinimumMaximum(double minimum, double maximum, unsigned int bins) { m_Minimum = minimum; m_Maximum = maximum; m_Bins = bins; m_Binsize = (maximum - minimum) / bins; m_Initialized = true; } void mitk::IntensityQuantifier::InitializeByBinsizeAndBins(double minimum, unsigned int bins, double binsize) { - m_Minimum = minimum; - m_Maximum = minimum + bins*binsize; + if (m_CorrectForBinsize) + { + m_Minimum = minimum- 0.5*binsize; + } + else + { + m_Minimum = minimum; + } + m_Maximum = m_Minimum + bins*binsize; m_Bins = bins; m_Binsize = binsize; m_Initialized = true; } void mitk::IntensityQuantifier::InitializeByBinsizeAndMaximum(double minimum, double maximum, double binsize) { - m_Minimum = minimum; - m_Bins = std::ceil((maximum - minimum) / binsize); + if (m_CorrectForBinsize) + { + m_Minimum = minimum - 0.5*binsize; + } + else + { + m_Minimum = minimum; + } + m_Bins = std::ceil((maximum - m_Minimum) / binsize); m_Maximum = minimum + m_Bins*binsize; m_Binsize = binsize; m_Initialized = true; } void mitk::IntensityQuantifier::InitializeByImage(mitk::Image::Pointer image, unsigned int bins) { double minimum, maximum; AccessByItk_2(image, CalculateImageMinMax, minimum, maximum); InitializeByMinimumMaximum(minimum, maximum, bins); } void mitk::IntensityQuantifier::InitializeByImageAndMinimum(mitk::Image::Pointer image, double minimum, unsigned int bins) { double tmp, maximum; AccessByItk_2(image, CalculateImageMinMax, tmp, maximum); InitializeByMinimumMaximum(minimum, maximum, bins); } void mitk::IntensityQuantifier::InitializeByImageAndMaximum(mitk::Image::Pointer image, double maximum, unsigned int bins) { double minimum, tmp; AccessByItk_2(image, CalculateImageMinMax, minimum, tmp); InitializeByMinimumMaximum(minimum, maximum, bins); } void mitk::IntensityQuantifier::InitializeByImageRegion(mitk::Image::Pointer image, mitk::Image::Pointer mask, unsigned int bins) { double minimum, maximum; AccessByItk_3(image, CalculateImageRegionMinMax, mask, minimum, maximum); InitializeByMinimumMaximum(minimum, maximum, bins); } void mitk::IntensityQuantifier::InitializeByImageRegionAndMinimum(mitk::Image::Pointer image, mitk::Image::Pointer mask, double minimum, unsigned int bins) { double tmp, maximum; AccessByItk_3(image, CalculateImageRegionMinMax, mask, tmp, maximum); InitializeByMinimumMaximum(minimum, maximum, bins); } void mitk::IntensityQuantifier::InitializeByImageRegionAndMaximum(mitk::Image::Pointer image, mitk::Image::Pointer mask, double maximum, unsigned int bins) { double minimum, tmp; AccessByItk_3(image, CalculateImageRegionMinMax, mask, minimum, tmp); InitializeByMinimumMaximum(minimum, maximum, bins); } void mitk::IntensityQuantifier::InitializeByImageAndBinsize(mitk::Image::Pointer image, double binsize) { double minimum, maximum; AccessByItk_2(image, CalculateImageMinMax, minimum, maximum); InitializeByBinsizeAndMaximum(minimum, maximum, binsize); } void mitk::IntensityQuantifier::InitializeByImageAndBinsizeAndMinimum(mitk::Image::Pointer image, double minimum, double binsize) { double tmp, maximum; AccessByItk_2(image, CalculateImageMinMax, tmp, maximum); InitializeByBinsizeAndMaximum(minimum, maximum, binsize); } void mitk::IntensityQuantifier::InitializeByImageAndBinsizeAndMaximum(mitk::Image::Pointer image, double maximum, double binsize) { double minimum, tmp; AccessByItk_2(image, CalculateImageMinMax, minimum, tmp); InitializeByBinsizeAndMaximum(minimum, maximum, binsize); } void mitk::IntensityQuantifier::InitializeByImageRegionAndBinsize(mitk::Image::Pointer image, mitk::Image::Pointer mask, double binsize) { double minimum, maximum; AccessByItk_3(image, CalculateImageRegionMinMax, mask, minimum, maximum); InitializeByBinsizeAndMaximum(minimum, maximum, binsize); } void mitk::IntensityQuantifier::InitializeByImageRegionAndBinsizeAndMinimum(mitk::Image::Pointer image, mitk::Image::Pointer mask, double minimum, double binsize) { double tmp, maximum; AccessByItk_3(image, CalculateImageRegionMinMax, mask, tmp, maximum); InitializeByBinsizeAndMaximum(minimum, maximum, binsize); } void mitk::IntensityQuantifier::InitializeByImageRegionAndBinsizeAndMaximum(mitk::Image::Pointer image, mitk::Image::Pointer mask, double maximum, double binsize) { double minimum, tmp; AccessByItk_3(image, CalculateImageRegionMinMax, mask, minimum, tmp); InitializeByBinsizeAndMaximum(minimum, maximum, binsize); } unsigned int mitk::IntensityQuantifier::IntensityToIndex(double intensity) { double index = std::floor((intensity - m_Minimum) / m_Binsize); return std::max(0, std::min(index, m_Bins-1)); } double mitk::IntensityQuantifier::IndexToMinimumIntensity(unsigned int index) { return index*m_Binsize + m_Minimum; } double mitk::IntensityQuantifier::IndexToMeanIntensity(unsigned int index) { return (index + 0.5) * m_Binsize + m_Minimum; } double mitk::IntensityQuantifier::IndexToMaximumIntensity(unsigned int index) { return (index + 1) * m_Binsize + m_Minimum; } diff --git a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.hxx b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.hxx index f4a702d76b..77fc059832 100644 --- a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.hxx +++ b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.hxx @@ -1,662 +1,662 @@ /*=================================================================== 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. ===================================================================*/ /*========================================================================= * * Copyright Insight Software Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef __itkEnhancedHistogramToRunLengthFeaturesFilter_hxx #define __itkEnhancedHistogramToRunLengthFeaturesFilter_hxx #include "itkEnhancedHistogramToRunLengthFeaturesFilter.h" #include "itkNumericTraits.h" #include "vnl/vnl_math.h" namespace itk { namespace Statistics { //constructor template EnhancedHistogramToRunLengthFeaturesFilter ::EnhancedHistogramToRunLengthFeaturesFilter() : m_NumberOfVoxels(1) { this->ProcessObject::SetNumberOfRequiredInputs( 1 ); // allocate the data objects for the outputs which are // just decorators real types for( unsigned int i = 0; i < 17; i++ ) { this->ProcessObject::SetNthOutput( i, this->MakeOutput( i ) ); } } template void EnhancedHistogramToRunLengthFeaturesFilter< THistogram> ::SetInput( const HistogramType *histogram ) { this->ProcessObject::SetNthInput( 0, const_cast( histogram ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::HistogramType * EnhancedHistogramToRunLengthFeaturesFilter< THistogram> ::GetInput() const { if ( this->GetNumberOfInputs() < 1 ) { return ITK_NULLPTR; } return itkDynamicCastInDebugMode(this->ProcessObject::GetInput( 0 ) ); } template typename EnhancedHistogramToRunLengthFeaturesFilter::DataObjectPointer EnhancedHistogramToRunLengthFeaturesFilter ::MakeOutput( DataObjectPointerArraySizeType itkNotUsed( idx ) ) { return MeasurementObjectType::New().GetPointer(); } template void EnhancedHistogramToRunLengthFeaturesFilter< THistogram>:: GenerateData( void ) { const HistogramType * inputHistogram = this->GetInput(); this->m_TotalNumberOfRuns = static_cast ( inputHistogram->GetTotalFrequency() ); MeasurementType shortRunEmphasis = NumericTraits::ZeroValue(); MeasurementType longRunEmphasis = NumericTraits::ZeroValue(); MeasurementType greyLevelNonuniformity = NumericTraits::ZeroValue(); MeasurementType runLengthNonuniformity = NumericTraits::ZeroValue(); MeasurementType lowGreyLevelRunEmphasis = NumericTraits::ZeroValue(); MeasurementType highGreyLevelRunEmphasis = NumericTraits::ZeroValue(); MeasurementType shortRunLowGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType shortRunHighGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType longRunLowGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType longRunHighGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType runPercentage = NumericTraits::ZeroValue(); MeasurementType numberOfRuns = NumericTraits::ZeroValue(); //Added 15.07.2016 MeasurementType greyLevelVariance = NumericTraits::ZeroValue(); MeasurementType runLengthVariance = NumericTraits::ZeroValue(); MeasurementType runEntropy = NumericTraits::ZeroValue(); //Added 09.09.2016 MeasurementType greyLevelNonuniformityNormalized = NumericTraits::ZeroValue(); MeasurementType runLengthNonuniformityNormalized = NumericTraits::ZeroValue(); vnl_vector greyLevelNonuniformityVector( inputHistogram->GetSize()[0], 0.0 ); vnl_vector runLengthNonuniformityVector( inputHistogram->GetSize()[1], 0.0 ); typedef typename HistogramType::ConstIterator HistogramIterator; double mu_i = 0.0; double mu_j = 0.0; //Calculate the means. for ( HistogramIterator hit = inputHistogram->Begin(); hit != inputHistogram->End(); ++hit ) { IndexType index = hit.GetIndex(); MeasurementType frequency = hit.GetFrequency(); if ( frequency == 0 ) { continue; } // MITK_INFO << index[0] + 1 << "|" << index[1] + 1 << " " << frequency; MeasurementVectorType measurement = hit.GetMeasurementVector(); double i = index[0] + 1; double j = index[1] + 1; double p_ij = frequency / (1.0*m_TotalNumberOfRuns); mu_i += i * p_ij; mu_j += j * p_ij; } // MITK_INFO << "Mu_i " << mu_i << " Mu_j " << mu_j; //Calculate the other features. const double log2 = std::log(2.0); for ( HistogramIterator hit = inputHistogram->Begin(); hit != inputHistogram->End(); ++hit ) { MeasurementType frequency = hit.GetFrequency(); if ( frequency == 0 ) { continue; } MeasurementVectorType measurement = hit.GetMeasurementVector(); IndexType index = hit.GetIndex(); // inputHistogram->GetIndex( hit.GetInstanceIdentifier() ); double i = index[0] + 1; double j = index[1] + 1; double i2 = i*i; double j2 = j*j; double p_ij = frequency / m_TotalNumberOfRuns; greyLevelVariance += ((i - mu_i) * (i - mu_i) * p_ij); runLengthVariance += ((j - mu_j) * (j - mu_j) * p_ij); - runEntropy -= ( p_ij > 0.0001 ) ? p_ij *std::log(p_ij) / log2 : 0; + runEntropy -= p_ij * std::log(p_ij) / log2; // Traditional measures shortRunEmphasis += ( frequency / j2 ); longRunEmphasis += ( frequency * j2 ); greyLevelNonuniformityVector[index[0]] += frequency; runLengthNonuniformityVector[index[1]] += frequency; // measures from Chu et al. - lowGreyLevelRunEmphasis += (i2 > 0.0001) ? ( frequency / i2 ) : 0; + lowGreyLevelRunEmphasis += ( frequency / i2 ); highGreyLevelRunEmphasis += ( frequency * i2 ); // measures from Dasarathy and Holder - shortRunLowGreyLevelEmphasis += ((i2 * j2) > 0.0001) ? ( frequency / ( i2 * j2 ) ) : 0; - shortRunHighGreyLevelEmphasis += (j2 > 0.0001) ? ( frequency * i2 / j2 ) : 0; - longRunLowGreyLevelEmphasis += (i2 > 0.0001) ? ( frequency * j2 / i2 ) : 0; + shortRunLowGreyLevelEmphasis += ( frequency / ( i2 * j2 ) ) ; + shortRunHighGreyLevelEmphasis += ( frequency * i2 / j2 ) ; + longRunLowGreyLevelEmphasis += ( frequency * j2 / i2 ); longRunHighGreyLevelEmphasis += ( frequency * i2 * j2 ); } greyLevelNonuniformity = greyLevelNonuniformityVector.squared_magnitude(); runLengthNonuniformity = runLengthNonuniformityVector.squared_magnitude(); // Normalize all measures by the total number of runs if (this->m_TotalNumberOfRuns > 0) { shortRunEmphasis /= static_cast( this->m_TotalNumberOfRuns ); longRunEmphasis /= static_cast( this->m_TotalNumberOfRuns ); greyLevelNonuniformity /= static_cast( this->m_TotalNumberOfRuns ); runLengthNonuniformity /= static_cast( this->m_TotalNumberOfRuns ); lowGreyLevelRunEmphasis /= static_cast( this->m_TotalNumberOfRuns ); highGreyLevelRunEmphasis /= static_cast( this->m_TotalNumberOfRuns ); shortRunLowGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfRuns ); shortRunHighGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfRuns ); longRunLowGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfRuns ); longRunHighGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfRuns ); runPercentage = static_cast( this->m_TotalNumberOfRuns ) / static_cast( this->m_NumberOfVoxels ); numberOfRuns = static_cast( this->m_TotalNumberOfRuns ) ; greyLevelNonuniformityNormalized = greyLevelNonuniformity / static_cast(this->m_TotalNumberOfRuns); runLengthNonuniformityNormalized = runLengthNonuniformity / static_cast(this->m_TotalNumberOfRuns); } else { shortRunEmphasis = 0; longRunEmphasis = 0; greyLevelNonuniformity = 0; runLengthNonuniformity= 0; lowGreyLevelRunEmphasis = 0; highGreyLevelRunEmphasis = 0; shortRunLowGreyLevelEmphasis = 0; shortRunHighGreyLevelEmphasis= 0; longRunLowGreyLevelEmphasis = 0; longRunHighGreyLevelEmphasis = 0; runPercentage = 0; greyLevelNonuniformityNormalized = 0; runLengthNonuniformityNormalized = 0; numberOfRuns = static_cast( this->m_TotalNumberOfRuns ) ; } MeasurementObjectType* shortRunEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 0 ) ); shortRunEmphasisOutputObject->Set( shortRunEmphasis ); MeasurementObjectType* longRunEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 1 ) ); longRunEmphasisOutputObject->Set( longRunEmphasis ); MeasurementObjectType* greyLevelNonuniformityOutputObject = static_cast( this->ProcessObject::GetOutput( 2 ) ); greyLevelNonuniformityOutputObject->Set( greyLevelNonuniformity ); MeasurementObjectType* greyLevelNonuniformityNormalizedOutputObject = static_cast( this->ProcessObject::GetOutput( 15 ) ); greyLevelNonuniformityNormalizedOutputObject->Set( greyLevelNonuniformityNormalized ); MeasurementObjectType* runLengthNonuniformityNormalizedOutputObject = static_cast( this->ProcessObject::GetOutput( 16 ) ); runLengthNonuniformityNormalizedOutputObject->Set( runLengthNonuniformityNormalized ); MeasurementObjectType* runLengthNonuniformityOutputObject = static_cast( this->ProcessObject::GetOutput( 3 ) ); runLengthNonuniformityOutputObject->Set( runLengthNonuniformity ); MeasurementObjectType* lowGreyLevelRunEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 4 ) ); lowGreyLevelRunEmphasisOutputObject->Set( lowGreyLevelRunEmphasis ); MeasurementObjectType* highGreyLevelRunEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 5 ) ); highGreyLevelRunEmphasisOutputObject->Set( highGreyLevelRunEmphasis ); MeasurementObjectType* shortRunLowGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 6 ) ); shortRunLowGreyLevelEmphasisOutputObject->Set( shortRunLowGreyLevelEmphasis ); MeasurementObjectType* shortRunHighGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 7 ) ); shortRunHighGreyLevelEmphasisOutputObject->Set( shortRunHighGreyLevelEmphasis ); MeasurementObjectType* longRunLowGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 8 ) ); longRunLowGreyLevelEmphasisOutputObject->Set( longRunLowGreyLevelEmphasis ); MeasurementObjectType* longRunHighGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 9 ) ); longRunHighGreyLevelEmphasisOutputObject->Set( longRunHighGreyLevelEmphasis ); MeasurementObjectType* runPercentagesOutputObject = static_cast( this->ProcessObject::GetOutput( 10 ) ); runPercentagesOutputObject->Set( runPercentage ); MeasurementObjectType* numberOfRunsOutputObject = static_cast( this->ProcessObject::GetOutput( 11 ) ); numberOfRunsOutputObject->Set( numberOfRuns ); MeasurementObjectType* greyLevelVarianceOutputObject = static_cast( this->ProcessObject::GetOutput( 12 ) ); greyLevelVarianceOutputObject->Set( greyLevelVariance ); MeasurementObjectType* runLengthVarianceOutputObject = static_cast( this->ProcessObject::GetOutput( 13 ) ); runLengthVarianceOutputObject->Set( runLengthVariance ); MeasurementObjectType* runEntropyOutputObject = static_cast( this->ProcessObject::GetOutput( 14 ) ); runEntropyOutputObject->Set( runEntropy ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunEmphasisOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 0 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 1 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelNonuniformityOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 2 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthNonuniformityOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 3 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetLowGreyLevelRunEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 4 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetHighGreyLevelRunEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 5 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunLowGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 6 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunHighGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 7 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunLowGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 8 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunHighGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 9 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunPercentageOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 10 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetNumberOfRunsOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 11 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelVarianceOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 12 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthVarianceOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 13 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunEntropyOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 14 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelNonuniformityNormalizedOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 15 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthNonuniformityNormalizedOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 16 ) ); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunEmphasis() const { return this->GetShortRunEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunEmphasis() const { return this->GetLongRunEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelNonuniformity() const { return this->GetGreyLevelNonuniformityOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthNonuniformity() const { return this->GetRunLengthNonuniformityOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetLowGreyLevelRunEmphasis() const { return this->GetLowGreyLevelRunEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetHighGreyLevelRunEmphasis() const { return this->GetHighGreyLevelRunEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunLowGreyLevelEmphasis() const { return this->GetShortRunLowGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunHighGreyLevelEmphasis() const { return this->GetShortRunHighGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunLowGreyLevelEmphasis() const { return this->GetLongRunLowGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunHighGreyLevelEmphasis() const { return this->GetLongRunHighGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunPercentage() const { return this->GetRunPercentageOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetNumberOfRuns() const { return this->GetNumberOfRunsOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelVariance() const { return this->GetGreyLevelVarianceOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthVariance() const { return this->GetRunLengthVarianceOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunEntropy() const { return this->GetRunEntropyOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelNonuniformityNormalized() const { return this->GetGreyLevelNonuniformityNormalizedOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthNonuniformityNormalized() const { return this->GetRunLengthNonuniformityNormalizedOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter< THistogram>::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetFeature( RunLengthFeatureName feature ) { switch( feature ) { case ShortRunEmphasis: return this->GetShortRunEmphasis(); case LongRunEmphasis: return this->GetLongRunEmphasis(); case GreyLevelNonuniformity: return this->GetGreyLevelNonuniformity(); case GreyLevelNonuniformityNormalized: return this->GetGreyLevelNonuniformityNormalized(); case RunLengthNonuniformity: return this->GetRunLengthNonuniformity(); case RunLengthNonuniformityNormalized: return this->GetRunLengthNonuniformityNormalized(); case LowGreyLevelRunEmphasis: return this->GetLowGreyLevelRunEmphasis(); case HighGreyLevelRunEmphasis: return this->GetHighGreyLevelRunEmphasis(); case ShortRunLowGreyLevelEmphasis: return this->GetShortRunLowGreyLevelEmphasis(); case ShortRunHighGreyLevelEmphasis: return this->GetShortRunHighGreyLevelEmphasis(); case LongRunLowGreyLevelEmphasis: return this->GetLongRunLowGreyLevelEmphasis(); case LongRunHighGreyLevelEmphasis: return this->GetLongRunHighGreyLevelEmphasis(); case RunPercentage: return this->GetRunPercentage(); case NumberOfRuns: return this->GetNumberOfRuns(); case GreyLevelVariance: return this->GetGreyLevelVariance(); case RunLengthVariance: return this->GetRunLengthVariance(); case RunEntropy: return this->GetRunEntropy(); default: return 0; } } template< typename THistogram> void EnhancedHistogramToRunLengthFeaturesFilter< THistogram>:: PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf( os,indent ); } } // end of namespace Statistics } // end of namespace itk #endif diff --git a/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelDistanceZone.h b/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelDistanceZone.h index 870e556978..f3ad178922 100644 --- a/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelDistanceZone.h +++ b/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelDistanceZone.h @@ -1,178 +1,183 @@ #ifndef mitkGIFGreyLevelDistanceZone_h #define mitkGIFGreyLevelDistanceZone_h #include #include #include #include namespace mitk { struct GreyLevelDistanceZoneFeatures { GreyLevelDistanceZoneFeatures() : SmallDistanceEmphasis(0), LargeDistanceEmphasis(0), LowGreyLevelEmphasis(0), HighGreyLevelEmphasis(0), SmallDistanceLowGreyLevelEmphasis(0), SmallDistanceHighGreyLevelEmphasis(0), LargeDistanceLowGreyLevelEmphasis(0), LargeDistanceHighGreyLevelEmphasis(0), GreyLevelNonUniformity(0), GreyLevelNonUniformityNormalized(0), ZoneDistanceNonUniformity(0), ZoneDistanceNoneUniformityNormalized(0), ZonePercentage(0), GreyLevelMean(0), GreyLevelVariance(0), ZoneDistanceMean(0), ZoneDistanceVariance(0), ZoneDistanceEntropy(0) { } public: double SmallDistanceEmphasis; double LargeDistanceEmphasis; double LowGreyLevelEmphasis; double HighGreyLevelEmphasis; double SmallDistanceLowGreyLevelEmphasis; double SmallDistanceHighGreyLevelEmphasis; double LargeDistanceLowGreyLevelEmphasis; double LargeDistanceHighGreyLevelEmphasis; double GreyLevelNonUniformity; double GreyLevelNonUniformityNormalized; double ZoneDistanceNonUniformity; double ZoneDistanceNoneUniformityNormalized; double ZonePercentage; double GreyLevelMean; double GreyLevelVariance; double ZoneDistanceMean; double ZoneDistanceVariance; double ZoneDistanceEntropy; }; class MITKCLUTILITIES_EXPORT GIFGreyLevelDistanceZone : public AbstractGlobalImageFeature { /** * \brief Calculates the Grey Level Distance Zone * * This class can be used to calculate Grey Level Distance Zone as presented in Thibault et al. 2014. * * The basic idea behind the Grey Level Distance Zone based features is to count the connected areas * with a given intensity value \f$x_i\f$ and a given distance to the border of each segmentation \f$d_i\f$. * Several features are then calculated based on a matrix, that gives the number of occurence for each * combination of \f$x_i\f$ and \f$ d_i \f$ as \f$m_{x,d}\f$. * * This feature calculator is activated by the option -grey-level-distance-zone or -gldz. * * 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. It is expected that the image contains only voxels with value 0 and 1, * of which all voxels with an value equal to one are treated as masked. * * The features depend on the distance to the border of the segmentation ROI. In some cases, the border * definition might be different from the definition of the masked area, for example, if small openings * in the mask should not influence the distance. Due to that, it is possible to submit a second mask, * named Morphological Mask to the features that is then used to calculate the distance of each voxel to * border of the segmented area. The morpological mask can be either set by the function call SetMorphMask() * or by the corresponding global option. (Not parsed by the filter itself, but by the command line tool). * * Beside the complete matrix, which is represented by its individual elements \f$m_{x,d}\f$, som eadditional * values are used for the definition. \f$N_g\f$ is the number of discrete grey levels, \f$ N_d\f$ the number * (or maximum value) of possible distances, and \f$N_s\f$ the total number of zones. * \f$m_{x,d}\f$ gives the number of connected areas with the discrete * grey level x and distance to the boarder of d. Corresponding, \f$p_{x,d} = \frac{m_{x,d}}{N_s} gives the relativ * probability of this matrix cell. \f$ \f$N_v\f$ is the number of voxels. In addition, the marginal * sums \f$m_{x,\cdot} = m_x = \sum_d m_{x,d} \f$ , representing the sum of all zones with a given intensity, and * sums \f$m_{\cdot, d} = m_d = \sum_x m_{x,d} \f$ , representing the sum of all zones with a given distance, are used. * The distance are given as the number of voxels to the border and the voxel intensity is given as the * bin number of the binned image, starting with 1. * * The following features are then defined: * - Grey Level Distance Zone::Small Distance Emphasis: * \f[ \textup{Small Distance Emphasis}= \frac{1}{N_s} \sum_d \frac{m_d}{d^2} \f] * - Grey Level Distance Zone::Large Distance Emphasis: * \f[ \textup{Large Distance Emphasis}= \frac{1}{N_s} \sum_d d^2 m_d \f] * - Grey Level Distance Zone::Low Grey Level Emphasis: * \f[ \textup{Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \frac{m_x}{x^2} \f] * - Grey Level Distance Zone::High Grey Level Emphasis: * \f[ \textup{High Grey Level Emphasis}= \frac{1}{N_s} \sum_x x^2 m_x \f] * - Grey Level Distance Zone::Small Distance Low Grey Level Emphasis: * \f[ \textup{Small Distance Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_d \frac{ m_{x,d}}{x^2 d^2}\f] * - Grey Level Distance Zone::Small Distance High Grey Level Emphasis: * \f[ \textup{Small Distance High Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_d \frac{x^2 m_{x,d}}{d^2}\f] * - Grey Level Distance Zone::Large Distance Low Grey Level Emphasis: * \f[ \textup{Large Distance Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_d \frac{d^2 m_{x,d}}{x^2}\f] * - Grey Level Distance Zone::Large Distance High Grey Level Emphasis: * \f[ \textup{Large Distance High Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_d \x^2 d^2 m_{x,d} \f] * - Grey Level Distance Zone::Grey Level Non-Uniformity: * \f[ \textup{Grey Level Non-Uniformity}= \frac{1}{N_s} \sum_x m_x^2 \f] * - Grey Level Distance Zone::Grey Level Non-Uniformity Normalized: * \f[ \textup{Grey Level Non-Uniformity Normalized}= \frac{1}{N_s^2} \sum_x m_x^2 \f] * - Grey Level Distance Zone::Zone Distance Non-Uniformity: * \f[ \textup{Grey Level Non-Uniformity}= \frac{1}{N_s} \sum_d m_d^2 \f] * - Grey Level Distance Zone::Zone Distance Non-Uniformity Normalized: * \f[ \textup{Grey Level Non-Uniformity Normalized}= \frac{1}{N_s^2} \sum_d m_d^2 \f] * - Grey Level Distance Zone::Zone Percentage: The ratio of zones to the possible zones: * \f[ \textup{Zone Percentage}= \frac{N_s}{N_v} \f] * - Grey Level Distance Zone::Grey Level Mean: * \f[ \textup{Grey Level Mean}= \mu_x = \sum_x \sum_d x p_{x,d} \f] * - Grey Level Distance Zone::Grey Level Variance: * \f[ \textup{Grey Level Variance} = \sum_x \sum_d \left(x - \mu_x \right)^2 p_{x,d} \f] * - Grey Level Distance Zone::Zone Distance Mean: * \f[ \textup{Zone Distance Mean}= \mu_d = \sum_x \sum_d d p_{x,d} \f] * - Grey Level Distance Zone::Zone Distance Variance: * \f[ \textup{Zone Distance Variance} = \sum_x \sum_d \left(d - \mu_d \right)^2 p_{x,d} \f] * - Grey Level Distance Zone::Zone Distance Entropy : * \f[ \textup{Zone Distance Entropy} = - \sum_x \sum_d p_{x,d} \textup{log}_2 ( p_{x,d} ) \f] * - Grey Level Distance Zone::Grey Level Entropy : * \f[ \textup{Grey Level Entropy} = - \sum_x \sum_d p_{x,d} \textup{log}_2 ( p_{x,d} ) \f] */ public: mitkClassMacro(GIFGreyLevelDistanceZone, AbstractGlobalImageFeature); itkFactorylessNewMacro(Self) itkCloneMacro(Self) GIFGreyLevelDistanceZone(); /** * \brief Calculates the Cooccurence-Matrix based features for this class. */ virtual 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 */ virtual FeatureNameListType GetFeatureNames() override; virtual void CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &maskNoNAN, FeatureListType &featureList); virtual void AddArguments(mitkCommandLineParser &parser); virtual std::string GetCurrentFeatureEncoding() override; + itkSetMacro(SmallNeighbourhoodForDistance, bool); + itkGetConstMacro(SmallNeighbourhoodForDistance, bool); + struct GIFGreyLevelDistanceZoneConfiguration { mitk::Image::Pointer distanceMask; mitk::IntensityQuantifier::Pointer Quantifier; unsigned int direction; double MinimumIntensity; double MaximumIntensity; int Bins; + bool SmallNeighbourhoodForDistance; std::string prefix; }; private: + bool m_SmallNeighbourhoodForDistance=true; }; } #endif //mitkGIFGreyLevelDistanceZone_h diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGreyLevelDistanceZone.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGreyLevelDistanceZone.cpp index 74e875ab26..79fa6c14bd 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGreyLevelDistanceZone.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGreyLevelDistanceZone.cpp @@ -1,470 +1,492 @@ #include // MITK #include #include #include #include #include // ITK #include #include #include #include #include namespace mitk{ struct GreyLevelDistanceZoneMatrixHolder { public: GreyLevelDistanceZoneMatrixHolder(mitk::IntensityQuantifier::Pointer quantifier, int number, int maxSize); int IntensityToIndex(double intensity); int m_NumberOfBins; int m_MaximumSize; int m_NumerOfVoxels; Eigen::MatrixXd m_Matrix; mitk::IntensityQuantifier::Pointer m_Quantifier; }; } static void MatrixFeaturesTo(mitk::GreyLevelDistanceZoneFeatures features, std::string prefix, mitk::GIFGreyLevelDistanceZone::FeatureListType &featureList); mitk::GreyLevelDistanceZoneMatrixHolder::GreyLevelDistanceZoneMatrixHolder(mitk::IntensityQuantifier::Pointer quantifier, int number, int maxSize) : m_NumberOfBins(number), m_MaximumSize(maxSize), m_NumerOfVoxels(0), m_Quantifier(quantifier) { m_Matrix.resize(number, maxSize); m_Matrix.fill(0); } int mitk::GreyLevelDistanceZoneMatrixHolder::IntensityToIndex(double intensity) { return m_Quantifier->IntensityToIndex(intensity); } template int CalculateGlSZMatrix(itk::Image* itkImage, itk::Image* mask, itk::Image* distanceImage, std::vector > offsets, bool estimateLargestRegion, mitk::GreyLevelDistanceZoneMatrixHolder &holder) { typedef itk::Image ImageType; typedef itk::Image MaskImageType; typedef typename ImageType::IndexType IndexType; typedef itk::ImageRegionIteratorWithIndex ConstIterType; typedef itk::ImageRegionIteratorWithIndex ConstMaskIterType; auto region = mask->GetLargestPossibleRegion(); typename MaskImageType::RegionType newRegion; newRegion.SetSize(region.GetSize()); newRegion.SetIndex(region.GetIndex()); ConstIterType imageIter(itkImage, itkImage->GetLargestPossibleRegion()); ConstMaskIterType maskIter(mask, mask->GetLargestPossibleRegion()); typename MaskImageType::Pointer visitedImage = MaskImageType::New(); visitedImage->SetRegions(newRegion); visitedImage->Allocate(); visitedImage->FillBuffer(0); int largestRegion = 0; holder.m_NumberOfBins = 0; while (!maskIter.IsAtEnd()) { if (maskIter.Value() > 0 ) { auto startIntensityIndex = holder.IntensityToIndex(imageIter.Value()); std::vector indices; indices.push_back(maskIter.GetIndex()); unsigned int steps = 0; int smallestDistance = 500; while (indices.size() > 0) { auto currentIndex = indices.back(); indices.pop_back(); if (!region.IsInside(currentIndex)) { continue; } auto wasVisited = visitedImage->GetPixel(currentIndex); auto newIntensityIndex = holder.IntensityToIndex(itkImage->GetPixel(currentIndex)); auto isInMask = mask->GetPixel(currentIndex); if ((isInMask > 0) && (newIntensityIndex == startIntensityIndex) && (wasVisited < 1)) { ++(holder.m_NumerOfVoxels); smallestDistance = (smallestDistance > distanceImage->GetPixel(currentIndex)) ? distanceImage->GetPixel(currentIndex) : smallestDistance; ++steps; visitedImage->SetPixel(currentIndex, 1); for (auto offset : offsets) { auto newIndex = currentIndex + offset; indices.push_back(newIndex); newIndex = currentIndex - offset; indices.push_back(newIndex); } } } if (steps > 0) { largestRegion = std::max(steps, largestRegion); steps = std::min(steps, holder.m_MaximumSize); if (!estimateLargestRegion) { holder.m_Matrix(startIntensityIndex, smallestDistance-1) += 1; } } } ++imageIter; ++maskIter; } return largestRegion; } template void itkErode2( itk::Image *sourceImage, mitk::Image::Pointer &resultImage, + bool useSmallNeighbourhood, + int direction, int &maxDistance) { typedef itk::Image ImageType; typedef unsigned short MaskType; typedef itk::Image MaskImageType; typename MaskImageType::Pointer distanceImage = MaskImageType::New(); distanceImage->SetRegions(sourceImage->GetLargestPossibleRegion()); distanceImage->SetOrigin(sourceImage->GetOrigin()); distanceImage->SetSpacing(sourceImage->GetSpacing()); distanceImage->SetDirection(sourceImage->GetDirection()); distanceImage->Allocate(); distanceImage->FillBuffer(std::numeric_limits::max()-1); typename ImageType::SizeType radius; radius.Fill(1); + if ((direction > 1) && (static_cast(direction) < VDimension + 2)) + { + radius[direction - 2] = 0; + } itk::NeighborhoodIterator neighbourIter(radius, sourceImage, sourceImage->GetLargestPossibleRegion()); itk::NeighborhoodIterator distanceIter(radius, distanceImage, distanceImage->GetLargestPossibleRegion()); bool imageChanged = true; while (imageChanged) { imageChanged = false; maxDistance = 0; neighbourIter.GoToBegin(); distanceIter.GoToBegin(); while (!neighbourIter.IsAtEnd()) { MaskType oldDistance = distanceIter.GetCenterPixel(); maxDistance = std::max(maxDistance, oldDistance); if (neighbourIter.GetCenterPixel() < 1) { if (oldDistance > 0) { distanceIter.SetCenterPixel(0); imageChanged = true; } } else if (oldDistance>0) { MaskType minimumDistance = oldDistance; + auto index = distanceIter.GetIndex(); for (unsigned int i = 0; i < distanceIter.Size(); ++i) { + if ( useSmallNeighbourhood) + { + auto cIndex = distanceIter.GetIndex(i); + int differentIndexes = 0; + for (int j = 0; static_cast(j) < VDimension; ++j) + { + differentIndexes += (index[j] == cIndex[j]) ? 0 : 1; + } + if (differentIndexes > 1) + { + continue; + } + } minimumDistance = std::min(minimumDistance, 1+distanceIter.GetPixel(i)); } if (minimumDistance != oldDistance) { distanceIter.SetCenterPixel(minimumDistance); imageChanged = true; } } ++neighbourIter; ++distanceIter; } } mitk::CastToMitkImage(distanceImage, resultImage); } -void erode(mitk::Image::Pointer input, mitk::Image::Pointer &output, int &maxDistance) +void erode(mitk::Image::Pointer input, mitk::Image::Pointer &output, bool useSmallNeighbourhood, int direction, int &maxDistance) { - AccessByItk_2(input, itkErode2, output, maxDistance); + AccessByItk_n(input, itkErode2, (output, useSmallNeighbourhood, direction, maxDistance)); } -void erodeAndAdd(mitk::Image::Pointer input, mitk::Image::Pointer& finalOutput, int &maxDistance) +void erodeAndAdd(mitk::Image::Pointer input, mitk::Image::Pointer& finalOutput, bool useSmallNeighbourhood, int direction, int &maxDistance) { maxDistance = 0; - erode(input, finalOutput, maxDistance); + erode(input, finalOutput, useSmallNeighbourhood, direction, maxDistance); } void static CalculateFeatures( mitk::GreyLevelDistanceZoneMatrixHolder &holder, mitk::GreyLevelDistanceZoneFeatures & results ) { auto SgzMatrix = holder.m_Matrix; auto pgzMatrix = holder.m_Matrix; auto pgMatrix = holder.m_Matrix; auto pzMatrix = holder.m_Matrix; double Ns = pgzMatrix.sum(); pgzMatrix /= Ns; pgMatrix.rowwise().normalize(); pzMatrix.colwise().normalize(); for (int i = 0; i < pgzMatrix.rows(); ++i) for (int j = 0; j < pgzMatrix.cols(); ++j) { if (pgzMatrix(i, j) != pgzMatrix(i, j)) pgzMatrix(i, j) = 0; if (pgMatrix(i, j) != pgMatrix(i, j)) pgMatrix(i, j) = 0; if (pzMatrix(i, j) != pzMatrix(i, j)) pzMatrix(i, j) = 0; } Eigen::VectorXd SgVector = SgzMatrix.rowwise().sum(); Eigen::VectorXd SzVector = SgzMatrix.colwise().sum(); for (int j = 0; j < SzVector.size(); ++j) { results.SmallDistanceEmphasis += SzVector(j) / (j+1) / (j+1); results.LargeDistanceEmphasis += SzVector(j) * (j + 1.0) * (j + 1.0); results.ZoneDistanceNonUniformity += SzVector(j) * SzVector(j); results.ZoneDistanceNoneUniformityNormalized += SzVector(j) * SzVector(j); } for (int i = 0; i < SgVector.size(); ++i) { results.LowGreyLevelEmphasis += SgVector(i) / (i + 1) / (i + 1); results.HighGreyLevelEmphasis += SgVector(i) * (i + 1) * (i + 1); results.GreyLevelNonUniformity += SgVector(i)*SgVector(i); results.GreyLevelNonUniformityNormalized += SgVector(i)*SgVector(i); } for (int i = 0; i < SgzMatrix.rows(); ++i) { for (int j = 0; j < SgzMatrix.cols(); ++j) { results.SmallDistanceLowGreyLevelEmphasis += SgzMatrix(i, j) / (i + 1) / (i + 1) / (j + 1) / (j + 1); results.SmallDistanceHighGreyLevelEmphasis += SgzMatrix(i, j) * (i + 1) * (i + 1) / (j + 1) / (j + 1); results.LargeDistanceLowGreyLevelEmphasis += SgzMatrix(i, j) / (i + 1) / (i + 1) * (j + 1.0) * (j + 1.0); results.LargeDistanceHighGreyLevelEmphasis += SgzMatrix(i, j) * (i + 1) * (i + 1) * (j + 1.0) * (j + 1.0); results.ZonePercentage += SgzMatrix(i, j); results.GreyLevelMean += (i + 1)*pgzMatrix(i, j); results.ZoneDistanceMean += (j + 1)*pgzMatrix(i, j); if (pgzMatrix(i, j) > 0) results.ZoneDistanceEntropy -= pgzMatrix(i, j) * std::log(pgzMatrix(i, j)) / std::log(2); } } for (int i = 0; i < SgzMatrix.rows(); ++i) { for (int j = 0; j < SgzMatrix.cols(); ++j) { results.GreyLevelVariance += (i + 1 - results.GreyLevelMean)*(i + 1 - results.GreyLevelMean)*pgzMatrix(i, j); results.ZoneDistanceVariance += (j + 1 - results.ZoneDistanceMean)*(j + 1 - results.ZoneDistanceMean)*pgzMatrix(i, j); } } results.SmallDistanceEmphasis /= Ns; results.LargeDistanceEmphasis /= Ns; results.LowGreyLevelEmphasis /= Ns; results.HighGreyLevelEmphasis /= Ns; results.SmallDistanceLowGreyLevelEmphasis /= Ns; results.SmallDistanceHighGreyLevelEmphasis /= Ns; results.LargeDistanceLowGreyLevelEmphasis /= Ns; results.LargeDistanceHighGreyLevelEmphasis /= Ns; results.GreyLevelNonUniformity /= Ns; results.GreyLevelNonUniformityNormalized /= Ns*Ns; results.ZoneDistanceNonUniformity /= Ns; results.ZoneDistanceNoneUniformityNormalized /= Ns*Ns; results.ZonePercentage = Ns / holder.m_NumerOfVoxels;// results.ZonePercentage; } template static void CalculateGreyLevelDistanceZoneFeatures(itk::Image* itkImage, mitk::Image::Pointer mask, mitk::GIFGreyLevelDistanceZone::FeatureListType & featureList, mitk::GIFGreyLevelDistanceZone::GIFGreyLevelDistanceZoneConfiguration config) { typedef itk::Image MaskType; typedef itk::Neighborhood NeighborhoodType; typedef itk::Offset OffsetType; /////////////////////////////////////////////////////////////////////////////////////////////// int maximumDistance = 0; mitk::Image::Pointer mitkDistanceImage = mitk::Image::New(); - erodeAndAdd(config.distanceMask, mitkDistanceImage, maximumDistance); + erodeAndAdd(config.distanceMask, mitkDistanceImage, config.SmallNeighbourhoodForDistance, config.direction, maximumDistance); typename MaskType::Pointer distanceImage = MaskType::New(); mitk::CastToItkImage(mitkDistanceImage, distanceImage); typename MaskType::Pointer maskImage = MaskType::New(); mitk::CastToItkImage(mask, maskImage); //Find possible directions std::vector < itk::Offset > offsetVector; NeighborhoodType hood; hood.SetRadius(1); unsigned int centerIndex = hood.GetCenterNeighborhoodIndex(); OffsetType offset; for (unsigned int d = 0; d < centerIndex; d++) { offset = hood.GetOffset(d); bool useOffset = true; for (unsigned int i = 0; i < VImageDimension; ++i) { if ((config.direction == i + 2) && offset[i] != 0) { useOffset = false; } } if (useOffset) { offsetVector.push_back(offset); } } if (config.direction == 1) { offsetVector.clear(); offset[0] = 0; offset[1] = 0; offset[2] = 1; offsetVector.push_back(offset); } MITK_INFO << "Maximum Distance: " << maximumDistance; std::vector resultVector; mitk::GreyLevelDistanceZoneMatrixHolder holderOverall(config.Quantifier, config.Bins, maximumDistance + 1); mitk::GreyLevelDistanceZoneFeatures overallFeature; CalculateGlSZMatrix(itkImage, maskImage, distanceImage, offsetVector, false, holderOverall); CalculateFeatures(holderOverall, overallFeature); MatrixFeaturesTo(overallFeature, config.prefix, featureList); } static void MatrixFeaturesTo(mitk::GreyLevelDistanceZoneFeatures features, std::string prefix, mitk::GIFGreyLevelDistanceZone::FeatureListType &featureList) { featureList.push_back(std::make_pair(prefix + "Small Distance Emphasis", features.SmallDistanceEmphasis)); featureList.push_back(std::make_pair(prefix + "Large Distance Emphasis", features.LargeDistanceEmphasis)); featureList.push_back(std::make_pair(prefix + "Low Grey Level Emphasis", features.LowGreyLevelEmphasis)); featureList.push_back(std::make_pair(prefix + "High Grey Level Emphasis", features.HighGreyLevelEmphasis)); featureList.push_back(std::make_pair(prefix + "Small Distance Low Grey Level Emphasis", features.SmallDistanceLowGreyLevelEmphasis)); featureList.push_back(std::make_pair(prefix + "Small Distance High Grey Level Emphasis", features.SmallDistanceHighGreyLevelEmphasis)); featureList.push_back(std::make_pair(prefix + "Large Distance Low Grey Level Emphasis", features.LargeDistanceLowGreyLevelEmphasis)); featureList.push_back(std::make_pair(prefix + "Large Distance High Grey Level Emphasis", features.LargeDistanceHighGreyLevelEmphasis)); featureList.push_back(std::make_pair(prefix + "Grey Level Non-Uniformity", features.GreyLevelNonUniformity)); featureList.push_back(std::make_pair(prefix + "Grey Level Non-Uniformity Normalized", features.GreyLevelNonUniformityNormalized)); featureList.push_back(std::make_pair(prefix + "Distance Size Non-Uniformity", features.ZoneDistanceNonUniformity)); featureList.push_back(std::make_pair(prefix + "Distance Size Non-Uniformity Normalized", features.ZoneDistanceNoneUniformityNormalized)); featureList.push_back(std::make_pair(prefix + "Zone Percentage", features.ZonePercentage)); featureList.push_back(std::make_pair(prefix + "Grey Level Mean", features.GreyLevelMean)); featureList.push_back(std::make_pair(prefix + "Grey Level Variance", features.GreyLevelVariance)); featureList.push_back(std::make_pair(prefix + "Zone Distance Mean", features.ZoneDistanceMean)); featureList.push_back(std::make_pair(prefix + "Zone Distance Variance", features.ZoneDistanceVariance)); featureList.push_back(std::make_pair(prefix + "Zone Distance Entropy", features.ZoneDistanceEntropy)); featureList.push_back(std::make_pair(prefix + "Grey Level Entropy", features.ZoneDistanceEntropy)); } - mitk::GIFGreyLevelDistanceZone::GIFGreyLevelDistanceZone() + mitk::GIFGreyLevelDistanceZone::GIFGreyLevelDistanceZone() : m_SmallNeighbourhoodForDistance(true) { SetShortName("gldz"); SetLongName("distance-zone"); SetFeatureClassName("Grey Level Distance Zone"); } mitk::GIFGreyLevelDistanceZone::FeatureListType mitk::GIFGreyLevelDistanceZone::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { InitializeQuantifier(image, mask); FeatureListType featureList; GIFGreyLevelDistanceZoneConfiguration config; config.direction = GetDirection(); - if (GetMorphMask().IsNull()) + if (GetMorphMask()==NULL) { config.distanceMask = mask->Clone(); } else { - config.distanceMask = GetMorphMask(); + config.distanceMask = GetMorphMask()->Clone(); } config.MinimumIntensity = GetQuantifier()->GetMinimum(); config.MaximumIntensity = GetQuantifier()->GetMaximum(); config.Bins = GetQuantifier()->GetBins(); config.prefix = FeatureDescriptionPrefix(); config.Quantifier = GetQuantifier(); + config.SmallNeighbourhoodForDistance = GetSmallNeighbourhoodForDistance(); AccessByItk_3(image, CalculateGreyLevelDistanceZoneFeatures, mask, featureList, config); return featureList; } mitk::GIFGreyLevelDistanceZone::FeatureNameListType mitk::GIFGreyLevelDistanceZone::GetFeatureNames() { FeatureNameListType featureList; return featureList; } void mitk::GIFGreyLevelDistanceZone::AddArguments(mitkCommandLineParser &parser) { std::string name = GetOptionPrefix(); parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Grey Level Distance Zone", "Calculates the size zone based features.", us::Any()); + AddQuantifierArguments(parser); } void mitk::GIFGreyLevelDistanceZone::CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &maskNoNAN, FeatureListType &featureList) { auto parsedArgs = GetParameter(); std::string name = GetOptionPrefix(); if (parsedArgs.count(GetLongName())) { InitializeQuantifierFromParameters(feature, mask); MITK_INFO << "Start calculating Grey Level Distance Zone ...."; auto localResults = this->CalculateFeatures(feature, maskNoNAN); featureList.insert(featureList.end(), localResults.begin(), localResults.end()); MITK_INFO << "Finished calculating Grey Level Distance Zone."; } } std::string mitk::GIFGreyLevelDistanceZone::GetCurrentFeatureEncoding() { return QuantifierParameterString(); } diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFNeighbourhoodGreyToneDifferenceFeatures.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFNeighbourhoodGreyToneDifferenceFeatures.cpp index 70a6837f27..eec786aaaa 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFNeighbourhoodGreyToneDifferenceFeatures.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFNeighbourhoodGreyToneDifferenceFeatures.cpp @@ -1,221 +1,228 @@ /*=================================================================== 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 // STL #include struct GIFNeighbourhoodGreyToneDifferenceParameter { int Range = 1; + int direction = 0; mitk::IntensityQuantifier::Pointer quantifier; std::string prefix; }; template static void CalculateIntensityPeak(itk::Image* itkImage, mitk::Image::Pointer mask, GIFNeighbourhoodGreyToneDifferenceParameter params, mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::FeatureListType & featureList) { typedef itk::Image ImageType; typedef itk::Image MaskType; typename MaskType::Pointer itkMask = MaskType::New(); mitk::CastToItkImage(mask, itkMask); typename ImageType::SizeType regionSize; regionSize.Fill(params.Range); + if ((params.direction > 1) && (static_cast(params.direction) < VImageDimension + 2)) + { + regionSize[params.direction - 2] = 0; + } + itk::NeighborhoodIterator iter(regionSize, itkImage, itkImage->GetLargestPossibleRegion()); itk::NeighborhoodIterator iterMask(regionSize, itkMask, itkMask->GetLargestPossibleRegion()); std::vector pVector; std::vector sVector; pVector.resize(params.quantifier->GetBins(), 0); sVector.resize(params.quantifier->GetBins(), 0); int count = 0; while (!iter.IsAtEnd()) { if (iterMask.GetCenterPixel() > 0) { int localCount = 0; double localMean = 0; unsigned int localIndex = params.quantifier->IntensityToIndex(iter.GetCenterPixel()); for (itk::SizeValueType i = 0; i < iter.Size(); ++i) { if (i == (iter.Size() / 2)) continue; if (iterMask.GetPixel(i) > 0) { ++localCount; localMean += params.quantifier->IntensityToIndex(iter.GetPixel(i)) + 1; } } if (localCount > 0) { localMean /= localCount; } localMean = std::abs(localIndex + 1 - localMean); pVector[localIndex] += 1; sVector[localIndex] += localMean; ++count; } ++iterMask; ++iter; } unsigned int Ngp = 0; for (unsigned int i = 0; i < params.quantifier->GetBins(); ++i) { if (pVector[i] > 0.1) { ++Ngp; } pVector[i] /= count; } double sumS = 0; double sumStimesP = 0; double contrastA = 0; double busynessA = 0; double complexity = 0; double strengthA = 0; for (unsigned int i = 0; i < params.quantifier->GetBins(); ++i) { sumS += sVector[i]; sumStimesP += pVector[i] * sVector[i]; for (unsigned int j = 0; j < params.quantifier->GetBins(); ++j) { double iMinusj = 1.0*i - 1.0*j; contrastA += pVector[i] * pVector[j] * iMinusj*iMinusj; if ((pVector[i] > 0) && (pVector[j] > 0)) { busynessA += std::abs((i + 1.0)*pVector[i] - (j + 1.0)*pVector[j]); complexity += std::abs(iMinusj)*(pVector[i] * sVector[i] + pVector[j] * sVector[j]) / (pVector[i] + pVector[j]); strengthA += (pVector[i] + pVector[j])*iMinusj*iMinusj; } } } double coarsness = 1.0 / std::min(sumStimesP, 1000000); double contrast = 0; double busyness = 0; if (Ngp > 1) { contrast = contrastA / Ngp / (Ngp - 1) / count * sumS; busyness = sumStimesP / busynessA; } complexity /= count; double strength = 0; if (sumS > 0) { strength = strengthA / sumS; } std::string prefix = params.prefix; featureList.push_back(std::make_pair(prefix + "Coarsness", coarsness)); featureList.push_back(std::make_pair(prefix + "Contrast", contrast)); featureList.push_back(std::make_pair(prefix + "Busyness", busyness)); featureList.push_back(std::make_pair(prefix + "Complexity", complexity)); featureList.push_back(std::make_pair(prefix + "Strength", strength)); } mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::GIFNeighbourhoodGreyToneDifferenceFeatures() : m_Range(1) { SetLongName("neighbourhood-grey-tone-difference"); SetShortName("ngtd"); SetFeatureClassName("Neighbourhood Grey Tone Difference"); } mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::FeatureListType mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { FeatureListType featureList; InitializeQuantifierFromParameters(image, mask); GIFNeighbourhoodGreyToneDifferenceParameter params; params.Range = GetRange(); params.quantifier = GetQuantifier(); params.prefix = FeatureDescriptionPrefix(); + params.direction = GetDirection(); AccessByItk_3(image, CalculateIntensityPeak, mask, params, featureList); return featureList; } mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::FeatureNameListType mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::GetFeatureNames() { FeatureNameListType featureList; return featureList; } void mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::AddArguments(mitkCommandLineParser &parser) { AddQuantifierArguments(parser); std::string name = GetOptionPrefix(); parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Neighbourhood Grey Tone Difference", "calculates Neighborhood Grey Tone based features", us::Any()); parser.addArgument(name + "::range", name + "::range", mitkCommandLineParser::Int, "Range for the local intensity", "Give the range that should be used for the local intensity in mm", us::Any()); } void mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &, FeatureListType &featureList) { InitializeQuantifierFromParameters(feature, mask); std::string name = GetOptionPrefix(); auto parsedArgs = GetParameter(); if (parsedArgs.count(GetLongName())) { MITK_INFO << "Start calculating Neighbourhood Grey Tone Difference features ...."; if (parsedArgs.count(name + "::range")) { int range = us::any_cast(parsedArgs[name + "::range"]); this->SetRange(range); } auto localResults = this->CalculateFeatures(feature, mask); featureList.insert(featureList.end(), localResults.begin(), localResults.end()); MITK_INFO << "Finished calculating Neighbourhood Grey Tone Difference features...."; } } std::string mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::GetCurrentFeatureEncoding() { std::ostringstream ss; ss << m_Range; std::string strRange = ss.str(); return QuantifierParameterString() + "_Range-" + ss.str(); } diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp index 9e184ae7db..e7c52db715 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp @@ -1,531 +1,620 @@ /*=================================================================== 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 #include #include // VTK #include #include #include #include #include #include #include #include // STL #include #include // Eigen #include struct GIFVolumetricDensityStatisticsParameters { double volume; std::string prefix; }; +static double LegendrePn(unsigned int n, double x) +{ + if (n == 0) + { + return 1.0; + } + else if (n == 1) + { + return x; + } + else if (n == 2) + { + return ((3.0 * x*x) - 1.0) * 0.5; + } + + if (x == 1.0) + { + return 1.0; + } + + if (x == -1.0) + { + return ((n % 2 == 0) ? 1.0 : -1.0); + } + + if ((x == 0.0) && (n % 2)) + { + return 0.0; + } + + /* We could simply do this: + return (double(((2 * n) - 1)) * x * Pn(n - 1, x) - + (double(n - 1)) * Pn(n - 2, x)) / (double)n ; + but it could be slow for large n */ + + double pnm1(LegendrePn(2,x)); + double pnm2(LegendrePn(1,x)); + double pn(pnm1); + + for (unsigned int l = 3; l <= n; l++) + { + pn = (((2.0 * (double)l) - 1.0) * x * pnm1 - + (((double)l - 1.0) * pnm2)) / (double)l; + pnm2 = pnm1; + pnm1 = pn; + } + + return pn; +} + + template void -CalculateVolumeDensityStatistic(itk::Image* itkImage, mitk::Image::Pointer mask, GIFVolumetricDensityStatisticsParameters params, mitk::GIFVolumetricDensityStatistics::FeatureListType & featureList) +CalculateVolumeDensityStatistic(itk::Image* itkImage, mitk::Image::Pointer originalMask, mitk::Image::Pointer mask, GIFVolumetricDensityStatisticsParameters params, mitk::GIFVolumetricDensityStatistics::FeatureListType & featureList) { typedef itk::Image ImageType; typedef itk::Image MaskType; - double volume = params.volume; std::string prefix = params.prefix; typename MaskType::Pointer maskImage = MaskType::New(); + typename MaskType::Pointer originalMaskImage = MaskType::New(); mitk::CastToItkImage(mask, maskImage); + mitk::CastToItkImage(originalMask, originalMaskImage); + itk::ImageRegionConstIteratorWithIndex imgA(itkImage, itkImage->GetLargestPossibleRegion()); - itk::ImageRegionConstIteratorWithIndex imgB(itkImage, itkImage->GetLargestPossibleRegion()); itk::ImageRegionConstIteratorWithIndex maskA(maskImage, maskImage->GetLargestPossibleRegion()); - itk::ImageRegionConstIteratorWithIndex maskB(maskImage, maskImage->GetLargestPossibleRegion()); + itk::ImageRegionConstIteratorWithIndex orignalMaskIter(originalMaskImage, originalMaskImage->GetLargestPossibleRegion()); double moranA = 0; double moranB = 0; double geary = 0; double Nv = 0; double w_ij = 0; double mean = 0; + unsigned int originalMaskVoxelCount = 0; typename ImageType::PointType pointA; typename ImageType::PointType pointB; while (!imgA.IsAtEnd()) { if (maskA.Get() > 0) { Nv += 1; mean += imgA.Get(); } + if (orignalMaskIter.Get() > 0) + { + ++originalMaskVoxelCount; + } ++imgA; ++maskA; + ++orignalMaskIter; } mean /= Nv; + double volume = originalMaskVoxelCount * originalMaskImage->GetSpacing()[0] * originalMaskImage->GetSpacing()[1] * originalMaskImage->GetSpacing()[2]; + imgA.GoToBegin(); maskA.GoToBegin(); + std::vector< typename ImageType::PointType > vectorPointsInMask; + std::vector< TPixel > vectorValuesInMask; + + vectorPointsInMask.reserve(Nv); + vectorValuesInMask.reserve(Nv); + while (!imgA.IsAtEnd()) { if (maskA.Get() > 0) { - imgB.GoToBegin(); - maskB.GoToBegin(); - while (!imgB.IsAtEnd()) - { - if ((imgA.GetIndex() == imgB.GetIndex()) || - (maskB.Get() < 1)) - { - ++imgB; - ++maskB; - continue; - } - itkImage->TransformIndexToPhysicalPoint(maskA.GetIndex(), pointA); - itkImage->TransformIndexToPhysicalPoint(maskB.GetIndex(), pointB); + auto maskAIndex = maskA.GetIndex(); + itkImage->TransformIndexToPhysicalPoint(maskAIndex, pointA); - double w = 1 / pointA.EuclideanDistanceTo(pointB); - moranA += w*(imgA.Get() - mean)* (imgB.Get() - mean); - geary += w * (imgA.Get() - imgB.Get()) * (imgA.Get() - imgB.Get()); - - w_ij += w; - - ++imgB; - ++maskB; - } - moranB += (imgA.Get() - mean)* (imgA.Get() - mean); + vectorPointsInMask.push_back(pointA); + vectorValuesInMask.push_back(imgA.Get()); } ++imgA; ++maskA; } + std::size_t elementsInVectors = vectorPointsInMask.size(); + + for (std::size_t idxA = 0; idxA < elementsInVectors; ++idxA) + { + pointA = vectorPointsInMask[idxA]; + double valueA = vectorValuesInMask[idxA]; + double valueAMinusMean = valueA - mean; + + for (std::size_t idxB = idxA+1; idxB < elementsInVectors; ++idxB) + { + pointB = vectorPointsInMask[idxB]; + double valueB = vectorValuesInMask[idxB]; + + double w = 2 * 1 / pointA.EuclideanDistanceTo(pointB); // Using symetry to avoid double calculation + moranA += w * valueAMinusMean * (valueB - mean); + geary += w * (valueA - valueB) * (valueA - valueB); + + w_ij += w; + } + moranB += valueAMinusMean * valueAMinusMean; + } MITK_INFO << "Volume: " << volume; MITK_INFO << " Mean: " << mean; featureList.push_back(std::make_pair(prefix + "Volume integrated intensity", volume* mean)); featureList.push_back(std::make_pair(prefix + "Volume Moran's I index", Nv / w_ij * moranA / moranB)); featureList.push_back(std::make_pair(prefix + "Volume Geary's C measure", ( Nv -1 ) / 2 / w_ij * geary/ moranB)); } void calculateMOBB(vtkPointSet *pointset, double &volume, double &surface) { volume = std::numeric_limits::max(); for (int cellID = 0; cellID < pointset->GetNumberOfCells(); ++cellID) { auto cell = pointset->GetCell(cellID); for (int edgeID = 0; edgeID < 3; ++edgeID) { auto edge = cell->GetEdge(edgeID); double pA[3], pB[3]; double pAA[3], pBB[3]; vtkSmartPointer transform = vtkSmartPointer::New(); transform->PostMultiply(); pointset->GetPoint(edge->GetPointId(0), pA); pointset->GetPoint(edge->GetPointId(1), pB); double angleZ = std::atan2((- pA[2] + pB[2]) ,(pA[1] - pB[1])); angleZ *= 180 / vnl_math::pi; if (pA[2] == pB[2]) angleZ = 0; transform->RotateX(angleZ); transform->TransformPoint(pA, pAA); transform->TransformPoint(pB, pBB); double angleY = std::atan2((pAA[1] -pBB[1]) ,-(pAA[0] - pBB[0])); angleY *= 180 / vnl_math::pi; if (pAA[1] == pBB[1]) angleY = 0; transform->RotateZ(angleY); double p0[3]; pointset->GetPoint(edge->GetPointId(0), p0); double curMinX = std::numeric_limits::max(); double curMaxX = std::numeric_limits::lowest(); double curMinY = std::numeric_limits::max(); double curMaxY = std::numeric_limits::lowest(); double curMinZ = std::numeric_limits::max(); double curMaxZ = std::numeric_limits::lowest(); for (int pointID = 0; pointID < pointset->GetNumberOfPoints(); ++pointID) { double p[3]; double p2[3]; pointset->GetPoint(pointID, p); p[0] -= p0[0]; p[1] -= p0[1]; p[2] -= p0[2]; transform->TransformPoint(p, p2); curMinX = std::min(p2[0], curMinX); curMaxX = std::max(p2[0], curMaxX); curMinY = std::min(p2[1], curMinY); curMaxY = std::max(p2[1], curMaxY); curMinZ = std::min(p2[2], curMinZ); curMaxZ = std::max(p2[2], curMaxZ); } if ((curMaxX - curMinX)*(curMaxY - curMinY)*(curMaxZ - curMinZ) < volume) { volume = (curMaxX - curMinX)*(curMaxY - curMinY)*(curMaxZ - curMinZ); surface = (curMaxX - curMinX)*(curMaxX - curMinX) + (curMaxY - curMinY)*(curMaxY - curMinY) + (curMaxZ - curMinZ)*(curMaxZ - curMinZ); surface *= 2; } } } } -void calculateMEE(vtkPointSet *pointset, double &vol, double &surf, double tolerance=0.0001) +void calculateMEE(vtkPointSet *pointset, double &vol, double &surf, double tolerance=0.05) { // Inspired by https://github.com/smdabdoub/ProkaryMetrics/blob/master/calc/fitting.py int numberOfPoints = pointset->GetNumberOfPoints(); int dimension = 3; Eigen::MatrixXd points(3, numberOfPoints); Eigen::MatrixXd Q(3+1, numberOfPoints); double p[3]; std::cout << "Initialize Q " << std::endl; for (int i = 0; i < numberOfPoints; ++i) { pointset->GetPoint(i, p); points(0, i) = p[0]; points(1, i) = p[1]; points(2, i) = p[2]; Q(0, i) = p[0]; Q(1, i) = p[1]; Q(2, i) = p[2]; Q(3, i) = 1.0; } int count = 1; double error = 1; Eigen::VectorXd u_vector(numberOfPoints); u_vector.fill(1.0 / numberOfPoints); Eigen::DiagonalMatrix u = u_vector.asDiagonal(); Eigen::VectorXd ones(dimension + 1); ones.fill(1); Eigen::MatrixXd Ones = ones.asDiagonal(); // Khachiyan Algorithm while (error > tolerance) { auto Qt = Q.transpose(); Eigen::MatrixXd X = Q*u*Qt; Eigen::FullPivHouseholderQR qr(X); Eigen::MatrixXd Xi = qr.solve(Ones); Eigen::MatrixXd M = Qt * Xi * Q; double maximumValue = M(0, 0); int maximumPosition = 0; for (int i = 0; i < numberOfPoints; ++i) { if (maximumValue < M(i, i)) { maximumValue = M(i, i); maximumPosition = i; } } double stepsize = (maximumValue - dimension - 1) / ((dimension + 1) * (maximumValue - 1)); Eigen::DiagonalMatrix new_u = (1.0 - stepsize) * u; new_u.diagonal()[maximumPosition] = (new_u.diagonal())(maximumPosition) + stepsize; ++count; error = (new_u.diagonal() - u.diagonal()).norm(); u.diagonal() = new_u.diagonal(); } // U = u Eigen::MatrixXd Ai = points * u * points.transpose() - points * u *(points * u).transpose(); Eigen::FullPivHouseholderQR qr(Ai); Eigen::VectorXd ones2(dimension); ones2.fill(1); Eigen::MatrixXd Ones2 = ones2.asDiagonal(); Eigen::MatrixXd A = qr.solve(Ones2)*1.0/dimension; Eigen::JacobiSVD svd(A); double c = 1 / sqrt(svd.singularValues()[0]); double b = 1 / sqrt(svd.singularValues()[1]); double a = 1 / sqrt(svd.singularValues()[2]); double V = 4 * vnl_math::pi*a*b*c / 3; double ad_mvee= 0; double alpha = std::sqrt(1 - b*b / a / a); double beta = std::sqrt(1 - c*c / a / a); for (int i = 0; i < 20; ++i) { ad_mvee += 4 * vnl_math::pi*a*b*(alpha*alpha + beta*beta) / (2 * alpha*beta) * (std::pow(alpha*beta, i)) / (1 - 4 * i*i); } vol = V; surf = ad_mvee; } mitk::GIFVolumetricDensityStatistics::FeatureListType mitk::GIFVolumetricDensityStatistics::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { + // Check if Image is at least of dimension 3, otherwise return without calculating + // as features only defined in 3D FeatureListType featureList; if (image->GetDimension() < 3) { return featureList; } + mitk::Image::Pointer original_mask = GetMorphMask(); + if (original_mask.IsNull()) + { + original_mask = mask->Clone(); + } + std::string prefix = FeatureDescriptionPrefix(); vtkSmartPointer mesher = vtkSmartPointer::New(); vtkSmartPointer stats = vtkSmartPointer::New(); vtkSmartPointer stats2 = vtkSmartPointer::New(); - mesher->SetInputData(mask->GetVtkImageData()); + mesher->SetInputData(original_mask->GetVtkImageData()); mesher->SetValue(0, 0.5); stats->SetInputConnection(mesher->GetOutputPort()); stats->Update(); vtkSmartPointer delaunay = vtkSmartPointer< vtkDelaunay3D >::New(); delaunay->SetInputConnection(mesher->GetOutputPort()); delaunay->SetAlpha(0); delaunay->Update(); vtkSmartPointer geometryFilter = vtkSmartPointer::New(); geometryFilter->SetInputConnection(delaunay->GetOutputPort()); geometryFilter->Update(); stats2->SetInputConnection(geometryFilter->GetOutputPort()); stats2->Update(); - double vol_mvee; - double surf_mvee; + double vol_mvee=0; + double surf_mvee=0; calculateMEE(mesher->GetOutput(), vol_mvee, surf_mvee); - double vol_mobb; - double surf_mobb; - calculateMOBB(geometryFilter->GetOutput(), vol_mobb, surf_mobb); + //double vol_mobb=0; + //double surf_mobb=0; + //calculateMOBB(geometryFilter->GetOutput(), vol_mobb, surf_mobb); double pi = vnl_math::pi; double meshVolume = stats->GetVolume(); double meshSurf = stats->GetSurfaceArea(); GIFVolumetricDensityStatisticsParameters params; params.volume = meshVolume; params.prefix = prefix; - AccessByItk_3(image, CalculateVolumeDensityStatistic, mask, params, featureList); + AccessByItk_n(image, CalculateVolumeDensityStatistic, (original_mask, mask, params, featureList)); //Calculate center of mass shift int xx = mask->GetDimensions()[0]; int yy = mask->GetDimensions()[1]; int zz = mask->GetDimensions()[2]; - double xd = mask->GetGeometry()->GetSpacing()[0]; - double yd = mask->GetGeometry()->GetSpacing()[1]; - double zd = mask->GetGeometry()->GetSpacing()[2]; + double spacingX = mask->GetGeometry()->GetSpacing()[0]; + double spacingY = mask->GetGeometry()->GetSpacing()[1]; + double spacingZ = mask->GetGeometry()->GetSpacing()[2]; int minimumX=xx; int maximumX=0; int minimumY=yy; int maximumY=0; int minimumZ=zz; int maximumZ=0; vtkSmartPointer dataset1Arr = vtkSmartPointer::New(); vtkSmartPointer dataset2Arr = vtkSmartPointer::New(); vtkSmartPointer dataset3Arr = vtkSmartPointer::New(); dataset1Arr->SetNumberOfComponents(1); dataset2Arr->SetNumberOfComponents(1); dataset3Arr->SetNumberOfComponents(1); dataset1Arr->SetName("M1"); dataset2Arr->SetName("M2"); dataset3Arr->SetName("M3"); vtkSmartPointer dataset1ArrU = vtkSmartPointer::New(); vtkSmartPointer dataset2ArrU = vtkSmartPointer::New(); vtkSmartPointer dataset3ArrU = vtkSmartPointer::New(); dataset1ArrU->SetNumberOfComponents(1); dataset2ArrU->SetNumberOfComponents(1); dataset3ArrU->SetNumberOfComponents(1); dataset1ArrU->SetName("M1"); dataset2ArrU->SetName("M2"); dataset3ArrU->SetName("M3"); vtkSmartPointer points = vtkSmartPointer< vtkPoints >::New(); 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; + mitk::ScalarType valueOriginalMask; mitkPixelTypeMultiplex5( mitk::FastSinglePixelAccess, image->GetChannelDescriptor().GetPixelType(), image, image->GetVolumeData(), index, pxImage, 0); + mitkPixelTypeMultiplex5( + mitk::FastSinglePixelAccess, + original_mask->GetChannelDescriptor().GetPixelType(), + original_mask, + original_mask->GetVolumeData(), + index, + pxMask, + 0); + mitkPixelTypeMultiplex5( mitk::FastSinglePixelAccess, mask->GetChannelDescriptor().GetPixelType(), mask, mask->GetVolumeData(), index, - pxMask, + valueOriginalMask, 0); //Check if voxel is contained in segmentation - if (pxMask > 0) + if (valueOriginalMask > 0) { minimumX = std::min(x, minimumX); minimumY = std::min(y, minimumY); minimumZ = std::min(z, minimumZ); maximumX = std::max(x, maximumX); maximumY = std::max(y, maximumY); maximumZ = std::max(z, maximumZ); - points->InsertNextPoint(x*xd, y*yd, z*zd); - + } + if (pxMask > 0) + { + points->InsertNextPoint(x*spacingX, y*spacingY, z*spacingZ); if (pxImage == pxImage) { - dataset1Arr->InsertNextValue(x*xd); - dataset2Arr->InsertNextValue(y*yd); - dataset3Arr->InsertNextValue(z*zd); + dataset1Arr->InsertNextValue(x*spacingX); + dataset2Arr->InsertNextValue(y*spacingY); + dataset3Arr->InsertNextValue(z*spacingZ); } } } } } vtkSmartPointer datasetTable = vtkSmartPointer::New(); datasetTable->AddColumn(dataset1Arr); datasetTable->AddColumn(dataset2Arr); datasetTable->AddColumn(dataset3Arr); vtkSmartPointer pcaStatistics = vtkSmartPointer::New(); pcaStatistics->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, datasetTable); pcaStatistics->SetColumnStatus("M1", 1); pcaStatistics->SetColumnStatus("M2", 1); pcaStatistics->SetColumnStatus("M3", 1); pcaStatistics->RequestSelectedColumns(); pcaStatistics->SetDeriveOption(true); pcaStatistics->Update(); vtkSmartPointer eigenvalues = vtkSmartPointer::New(); pcaStatistics->GetEigenvalues(eigenvalues); std::vector eigen_val(3); eigen_val[2] = eigenvalues->GetValue(0); eigen_val[1] = eigenvalues->GetValue(1); eigen_val[0] = eigenvalues->GetValue(2); double major = 2*sqrt(eigen_val[2]); double minor = 2*sqrt(eigen_val[1]); double least = 2*sqrt(eigen_val[0]); double alpha = std::sqrt(1 - minor*minor / major / major); double beta = std::sqrt(1 - least*least / major / major); - double a = (maximumX - minimumX+1) * xd; - double b = (maximumY - minimumY+1) * yd; - double c = (maximumZ - minimumZ+1) * zd; + double a = (maximumX - minimumX+1) * spacingX; + double b = (maximumY - minimumY+1) * spacingY; + double c = (maximumZ - minimumZ+1) * spacingZ; double vd_aabb = meshVolume / (a*b*c); double ad_aabb = meshSurf / (2 * a*b + 2 * a*c + 2 * b*c); double vd_aee = 3 * meshVolume / (4.0*pi*major*minor*least); double ad_aee = 0; for (int i = 0; i < 20; ++i) { - ad_aee += 4 * pi*major*minor*(alpha*alpha + beta*beta) / (2 * alpha*beta) * (std::pow(alpha*beta, i)) / (1 - 4 * i*i); + double legendreValue = LegendrePn(i, (alpha*alpha + beta * beta) / (2 * alpha*beta)); + ad_aee += 4 * pi*major*minor* legendreValue* (std::pow(alpha*beta, i)) / (1 - 4 * i*i); } ad_aee = meshSurf / ad_aee; double vd_ch = meshVolume / stats2->GetVolume(); double ad_ch = meshSurf / stats2->GetSurfaceArea(); featureList.push_back(std::make_pair(prefix + "Volume density axis-aligned bounding box", vd_aabb)); featureList.push_back(std::make_pair(prefix + "Surface density axis-aligned bounding box", ad_aabb)); - featureList.push_back(std::make_pair(prefix + "Volume density oriented minimum bounding box", meshVolume / vol_mobb)); - featureList.push_back(std::make_pair(prefix + "Surface density oriented minimum bounding box", meshSurf / surf_mobb)); +// featureList.push_back(std::make_pair(prefix + "Volume density oriented minimum bounding box", meshVolume / vol_mobb)); +// featureList.push_back(std::make_pair(prefix + "Surface density oriented minimum bounding box", meshSurf / surf_mobb)); featureList.push_back(std::make_pair(prefix + "Volume density approx. enclosing ellipsoid", vd_aee)); featureList.push_back(std::make_pair(prefix + "Surface density approx. enclosing ellipsoid", ad_aee)); featureList.push_back(std::make_pair(prefix + "Volume density approx. minimum volume enclosing ellipsoid", meshVolume / vol_mvee)); featureList.push_back(std::make_pair(prefix + "Surface density approx. minimum volume enclosing ellipsoid", meshSurf / surf_mvee)); featureList.push_back(std::make_pair(prefix + "Volume density convex hull", vd_ch)); featureList.push_back(std::make_pair(prefix + "Surface density convex hull", ad_ch)); return featureList; } mitk::GIFVolumetricDensityStatistics::GIFVolumetricDensityStatistics() { SetLongName("volume-density"); SetShortName("volden"); SetFeatureClassName("Morphological Density"); } mitk::GIFVolumetricDensityStatistics::FeatureNameListType mitk::GIFVolumetricDensityStatistics::GetFeatureNames() { FeatureNameListType featureList; return featureList; } void mitk::GIFVolumetricDensityStatistics::AddArguments(mitkCommandLineParser &parser) { std::string name = GetOptionPrefix(); parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Volume-Density Statistic", "calculates volume density based features", us::Any()); } void mitk::GIFVolumetricDensityStatistics::CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &, FeatureListType &featureList) { auto parsedArgs = GetParameter(); if (parsedArgs.count(GetLongName())) { MITK_INFO << "Start calculating volumetric density features ...."; auto localResults = this->CalculateFeatures(feature, mask); featureList.insert(featureList.end(), localResults.begin(), localResults.end()); MITK_INFO << "Finished calculating volumetric density features...."; } } diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp index 4520ff559f..37eb8b5ea9 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricStatistics.cpp @@ -1,470 +1,527 @@ /*=================================================================== 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 #include #include #include // STL #include template void CalculateVolumeStatistic(itk::Image* itkImage, mitk::Image::Pointer mask, mitk::GIFVolumetricStatistics::FeatureListType & featureList, std::string prefix) { 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(prefix + "Voxel Volume", voxelVolume)); featureList.push_back(std::make_pair(prefix + "Volume (voxel based)", volume)); } template void CalculateLargestDiameter(itk::Image* mask, mitk::Image::Pointer valueImage, mitk::GIFVolumetricStatistics::FeatureListType & featureList, std::string prefix) { 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 valueIter(radius, itkValueImage, itkValueImage->GetRequestedRegion()); std::vector borderPoints; unsigned int maskDimensionX = mask->GetLargestPossibleRegion().GetSize()[0]; unsigned int maskDimensionY = mask->GetLargestPossibleRegion().GetSize()[1]; unsigned int maskDimensionZ = mask->GetLargestPossibleRegion().GetSize()[2]; double maskVoxelSpacingX = mask->GetSpacing()[0]; double maskVoxelSpacingY = mask->GetSpacing()[1]; double maskVoxelSpacingZ = mask->GetSpacing()[2]; int maskMinimumX = maskDimensionX; int maskMaximumX = 0; int maskMinimumY = maskDimensionY; int maskMaximumY = 0; int maskMinimumZ = maskDimensionZ; int maskMaximumZ = 0; // // 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 (unsigned int j = 0; j < VImageDimension; ++j) { if (offset[j] != 0 && nonZeros == 0) { for (unsigned 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; } maskMinimumX = (maskMinimumX > iterator.GetIndex()[0]) ? iterator.GetIndex()[0] : maskMinimumX; maskMaximumX = (maskMaximumX < iterator.GetIndex()[0]) ? iterator.GetIndex()[0] : maskMaximumX; maskMinimumY = (maskMinimumY > iterator.GetIndex()[1]) ? iterator.GetIndex()[1] : maskMinimumY; maskMaximumY = (maskMaximumY < iterator.GetIndex()[1]) ? iterator.GetIndex()[1] : maskMaximumY; maskMinimumZ = (maskMinimumZ > iterator.GetIndex()[2]) ? iterator.GetIndex()[2] : maskMinimumZ; maskMaximumZ = (maskMaximumZ < iterator.GetIndex()[2]) ? iterator.GetIndex()[2] : maskMaximumZ; 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 || ( ! iterator.IndexInBounds(i))) { border = true; 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; + PointType pointA, pointB; 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; + pointA = point; + pointB = borderPoints[j]; + } } } - double boundingBoxVolume = maskVoxelSpacingX* (maskMaximumX - maskMinimumX) * maskVoxelSpacingY* (maskMaximumY - maskMinimumY) * maskVoxelSpacingZ* (maskMaximumZ - maskMinimumZ); + // Correct for using only the center of the voxels in the first step + // by appending the position with a offset of one voxel + MITK_INFO << pointA; + MITK_INFO << pointB; + if (VImageDimension >= 3 && longestDiameter > 0) + { + pointA[0] += maskVoxelSpacingX * ((pointA[0] > pointB[0]) ? +1 : -1); + pointA[1] += maskVoxelSpacingY * ((pointA[1] > pointB[1]) ? +1 : -1); + pointA[2] += maskVoxelSpacingZ * ((pointA[2] > pointB[2]) ? +1 : -1); + MITK_INFO << pointA; + MITK_INFO << pointB; + longestDiameter = pointA.EuclideanDistanceTo(pointB); + } + + + + double boundingBoxVolume = maskVoxelSpacingX* (1 + maskMaximumX - maskMinimumX) * maskVoxelSpacingY* (1 + maskMaximumY - maskMinimumY) * maskVoxelSpacingZ* (1 + maskMaximumZ - maskMinimumZ); featureList.push_back(std::make_pair(prefix + "Maximum 3D diameter", longestDiameter)); featureList.push_back(std::make_pair(prefix + "Surface (voxel based)", surface)); featureList.push_back(std::make_pair(prefix + "Centre of mass shift", differenceOfCenters)); featureList.push_back(std::make_pair(prefix + "Centre of mass shift (uncorrected)", differenceOfCentersUncorrected)); featureList.push_back(std::make_pair(prefix + "Bounding Box Volume", boundingBoxVolume)); } mitk::GIFVolumetricStatistics::GIFVolumetricStatistics() { SetLongName("volume"); SetShortName("vol"); SetFeatureClassName("Volumetric Features"); } mitk::GIFVolumetricStatistics::FeatureListType mitk::GIFVolumetricStatistics::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { FeatureListType featureList; if (image->GetDimension() < 3) { return featureList; } AccessByItk_3(image, CalculateVolumeStatistic, mask, featureList, FeatureDescriptionPrefix()); AccessByItk_3(mask, CalculateLargestDiameter, image, featureList, FeatureDescriptionPrefix()); vtkSmartPointer mesher = vtkSmartPointer::New(); vtkSmartPointer stats = vtkSmartPointer::New(); mesher->SetInputData(mask->GetVtkImageData()); mesher->SetValue(0, 0.5); stats->SetInputConnection(mesher->GetOutputPort()); stats->Update(); double pi = vnl_math::pi; double meshVolume = stats->GetVolume(); double meshSurf = stats->GetSurfaceArea(); double pixelVolume = featureList[1].second; double pixelSurface = featureList[3].second; + itk::Point pointA; + itk::Point pointB; + double longestMeshDiameter = 0; + auto polyData = mesher->GetOutput(); + for (vtkIdType pointIDA = 0; pointIDA < polyData->GetNumberOfPoints(); ++pointIDA) + { + pointA[0] = polyData->GetPoint(pointIDA)[0]; + pointA[1] = polyData->GetPoint(pointIDA)[1]; + pointA[2] = polyData->GetPoint(pointIDA)[2]; + for (vtkIdType pointIDB = 0; pointIDB < polyData->GetNumberOfPoints(); ++pointIDB) + { + pointB[0] = polyData->GetPoint(pointIDB)[0]; + pointB[1] = polyData->GetPoint(pointIDB)[1]; + pointB[2] = polyData->GetPoint(pointIDB)[2]; + double newDistance = pointA.EuclideanDistanceTo(pointB); + if (newDistance > longestMeshDiameter) + { + longestMeshDiameter = newDistance; + } + } + } + + + + + + + + + + + + + + MITK_INFO << "Surface: " << pixelSurface << " Volume: " << pixelVolume; 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 compactness2MeshMesh = 36 * pi*meshVolume*meshVolume / 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 compactness3MeshMesh = meshVolume / (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 sphericityMesh = std::pow(pi, 1 / 3.0) *std::pow(6 * meshVolume, 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 / meshVolume; double surfaceToVolumePixel = pixelSurface / pixelVolume; double sphericalDisproportion = meshSurf / 4 / pi / std::pow(3.0 / 4.0 / pi * pixelVolume, 2.0 / 3.0); double sphericalDisproportionMesh = meshSurf / 4 / pi / std::pow(3.0 / 4.0 / pi * meshVolume, 2.0 / 3.0); 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 asphericityMesh = std::pow(1.0 / compactness2MeshMesh, (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]; double xd = mask->GetGeometry()->GetSpacing()[0]; double yd = mask->GetGeometry()->GetSpacing()[1]; double zd = mask->GetGeometry()->GetSpacing()[2]; vtkSmartPointer dataset1Arr = vtkSmartPointer::New(); vtkSmartPointer dataset2Arr = vtkSmartPointer::New(); vtkSmartPointer dataset3Arr = vtkSmartPointer::New(); dataset1Arr->SetNumberOfComponents(1); dataset2Arr->SetNumberOfComponents(1); dataset3Arr->SetNumberOfComponents(1); dataset1Arr->SetName("M1"); dataset2Arr->SetName("M2"); dataset3Arr->SetName("M3"); vtkSmartPointer dataset1ArrU = vtkSmartPointer::New(); vtkSmartPointer dataset2ArrU = vtkSmartPointer::New(); vtkSmartPointer dataset3ArrU = vtkSmartPointer::New(); dataset1ArrU->SetNumberOfComponents(1); dataset2ArrU->SetNumberOfComponents(1); dataset3ArrU->SetNumberOfComponents(1); dataset1ArrU->SetName("M1"); dataset2ArrU->SetName("M2"); dataset3ArrU->SetName("M3"); 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) { dataset1ArrU->InsertNextValue(x*xd); dataset2ArrU->InsertNextValue(y*yd); dataset3ArrU->InsertNextValue(z*zd); if (pxImage == pxImage) { dataset1Arr->InsertNextValue(x*xd); dataset2Arr->InsertNextValue(y*yd); dataset3Arr->InsertNextValue(z*zd); } } } } } vtkSmartPointer datasetTable = vtkSmartPointer::New(); datasetTable->AddColumn(dataset1Arr); datasetTable->AddColumn(dataset2Arr); datasetTable->AddColumn(dataset3Arr); vtkSmartPointer datasetTableU = vtkSmartPointer::New(); datasetTableU->AddColumn(dataset1ArrU); datasetTableU->AddColumn(dataset2ArrU); datasetTableU->AddColumn(dataset3ArrU); vtkSmartPointer pcaStatistics = vtkSmartPointer::New(); pcaStatistics->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, datasetTable); pcaStatistics->SetColumnStatus("M1", 1); pcaStatistics->SetColumnStatus("M2", 1); pcaStatistics->SetColumnStatus("M3", 1); pcaStatistics->RequestSelectedColumns(); pcaStatistics->SetDeriveOption(true); pcaStatistics->Update(); vtkSmartPointer eigenvalues = vtkSmartPointer::New(); pcaStatistics->GetEigenvalues(eigenvalues); pcaStatistics->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, datasetTableU); pcaStatistics->Update(); vtkSmartPointer eigenvaluesU = vtkSmartPointer::New(); pcaStatistics->GetEigenvalues(eigenvaluesU); std::vector eigen_val(3); std::vector eigen_valUC(3); eigen_val[2] = eigenvalues->GetValue(0); eigen_val[1] = eigenvalues->GetValue(1); eigen_val[0] = eigenvalues->GetValue(2); eigen_valUC[2] = eigenvaluesU->GetValue(0); eigen_valUC[1] = eigenvaluesU->GetValue(1); eigen_valUC[0] = eigenvaluesU->GetValue(2); double major = 4*sqrt(eigen_val[2]); double minor = 4*sqrt(eigen_val[1]); double least = 4*sqrt(eigen_val[0]); double elongation = (major == 0) ? 0 : sqrt(eigen_val[1] / eigen_val[2]); double flatness = (major == 0) ? 0 : sqrt(eigen_val[0] / eigen_val[2]); double majorUC = 4*sqrt(eigen_valUC[2]); double minorUC = 4*sqrt(eigen_valUC[1]); double leastUC = 4*sqrt(eigen_valUC[0]); double elongationUC = majorUC == 0 ? 0 : sqrt(eigen_valUC[1] / eigen_valUC[2]); double flatnessUC = majorUC == 0 ? 0 : sqrt(eigen_valUC[0] / eigen_valUC[2]); std::string prefix = FeatureDescriptionPrefix(); featureList.push_back(std::make_pair(prefix + "Volume (mesh based)",meshVolume)); featureList.push_back(std::make_pair(prefix + "Surface (mesh based)",meshSurf)); + featureList.push_back(std::make_pair(prefix + "Maximum 3D diameter (mesh based)", longestMeshDiameter)); featureList.push_back(std::make_pair(prefix + "Surface to volume ratio (mesh based)",surfaceToVolume)); featureList.push_back(std::make_pair(prefix + "Sphericity (mesh based)",sphericity)); featureList.push_back(std::make_pair(prefix + "Sphericity (mesh, mesh based)", sphericityMesh)); featureList.push_back(std::make_pair(prefix + "Asphericity (mesh based)", asphericity)); featureList.push_back(std::make_pair(prefix + "Asphericity (mesh, mesh based)", asphericityMesh)); featureList.push_back(std::make_pair(prefix + "Compactness 1 (mesh based)", compactness3)); featureList.push_back(std::make_pair(prefix + "Compactness 1 old (mesh based)" ,compactness1)); featureList.push_back(std::make_pair(prefix + "Compactness 2 (mesh based)",compactness2)); featureList.push_back(std::make_pair(prefix + "Compactness 1 (mesh, mesh based)", compactness3MeshMesh)); featureList.push_back(std::make_pair(prefix + "Compactness 2 (mesh, mesh based)", compactness2MeshMesh)); featureList.push_back(std::make_pair(prefix + "Spherical disproportion (mesh based)", sphericalDisproportion)); featureList.push_back(std::make_pair(prefix + "Spherical disproportion (mesh, mesh based)", sphericalDisproportionMesh)); featureList.push_back(std::make_pair(prefix + "Surface to volume ratio (voxel based)", surfaceToVolumePixel)); featureList.push_back(std::make_pair(prefix + "Sphericity (voxel based)", sphericityPixel)); featureList.push_back(std::make_pair(prefix + "Asphericity (voxel based)", asphericityPixel)); featureList.push_back(std::make_pair(prefix + "Compactness 1 (voxel based)", compactness3Pixel)); featureList.push_back(std::make_pair(prefix + "Compactness 1 old (voxel based)", compactness1Pixel)); featureList.push_back(std::make_pair(prefix + "Compactness 2 (voxel based)", compactness2Pixel)); featureList.push_back(std::make_pair(prefix + "Spherical disproportion (voxel based)", sphericalDisproportionPixel)); featureList.push_back(std::make_pair(prefix + "PCA Major axis length",major)); featureList.push_back(std::make_pair(prefix + "PCA Minor axis length",minor)); featureList.push_back(std::make_pair(prefix + "PCA Least axis length",least)); featureList.push_back(std::make_pair(prefix + "PCA Elongation",elongation)); featureList.push_back(std::make_pair(prefix + "PCA Flatness",flatness)); featureList.push_back(std::make_pair(prefix + "PCA Major axis length (uncorrected)", majorUC)); featureList.push_back(std::make_pair(prefix + "PCA Minor axis length (uncorrected)", minorUC)); featureList.push_back(std::make_pair(prefix + "PCA Least axis length (uncorrected)", leastUC)); featureList.push_back(std::make_pair(prefix + "PCA Elongation (uncorrected)", elongationUC)); featureList.push_back(std::make_pair(prefix + "PCA Flatness (uncorrected)", flatnessUC)); return featureList; } mitk::GIFVolumetricStatistics::FeatureNameListType mitk::GIFVolumetricStatistics::GetFeatureNames() { FeatureNameListType featureList; return featureList; } void mitk::GIFVolumetricStatistics::AddArguments(mitkCommandLineParser &parser) { std::string name = GetOptionPrefix(); parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Volume-Statistic", "calculates volume based features", us::Any()); } void mitk::GIFVolumetricStatistics::CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &, FeatureListType &featureList) { auto parsedArgs = GetParameter(); if (parsedArgs.count(GetLongName())) { MITK_INFO << "Start calculating Volumetric Features::...."; auto localResults = this->CalculateFeatures(feature, mask); featureList.insert(featureList.end(), localResults.begin(), localResults.end()); MITK_INFO << "Finished calculating volumetric features...."; } } diff --git a/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.cpp index eb7b353ef3..b755e551e3 100644 --- a/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.cpp +++ b/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.cpp @@ -1,393 +1,393 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include "mapRegistration.h" #include "mitkImageMappingHelper.h" #include "mitkRegistrationHelper.h" template typename ::itk::InterpolateImageFunction< TImage >::Pointer generateInterpolator(mitk::ImageMappingInterpolator::Type interpolatorType) { typedef ::itk::InterpolateImageFunction< TImage > BaseInterpolatorType; typename BaseInterpolatorType::Pointer result; switch (interpolatorType) { case mitk::ImageMappingInterpolator::NearestNeighbor: { result = ::itk::NearestNeighborInterpolateImageFunction::New(); break; } case mitk::ImageMappingInterpolator::BSpline_3: { typename ::itk::BSplineInterpolateImageFunction::Pointer spInterpolator = ::itk::BSplineInterpolateImageFunction::New(); spInterpolator->SetSplineOrder(3); result = spInterpolator; break; } case mitk::ImageMappingInterpolator::WSinc_Hamming: { result = ::itk::WindowedSincInterpolateImageFunction::New(); break; } case mitk::ImageMappingInterpolator::WSinc_Welch: { result = ::itk::WindowedSincInterpolateImageFunction >::New(); break; } default: { result = ::itk::LinearInterpolateImageFunction::New(); break; } } return result; }; template void doMITKMap(const ::itk::Image* input, mitk::ImageMappingHelper::ResultImageType::Pointer& result, const mitk::ImageMappingHelper::RegistrationType*& registration, bool throwOnOutOfInputAreaError, const double& paddingValue, const mitk::ImageMappingHelper::ResultImageGeometryType*& resultGeometry, bool throwOnMappingError, const double& errorValue, mitk::ImageMappingInterpolator::Type interpolatorType) { typedef ::map::core::Registration ConcreteRegistrationType; typedef ::map::core::ImageMappingTask, ::itk::Image > MappingTaskType; typename MappingTaskType::Pointer spTask = MappingTaskType::New(); typedef typename MappingTaskType::ResultImageDescriptorType ResultImageDescriptorType; typename ResultImageDescriptorType::Pointer resultDescriptor; //check if image and result geometry fits the passed registration ///////////////////////////////////////////////////////////////// if (registration->getMovingDimensions()!=VImageDimension) { map::core::OStringStream str; str << "Dimension of MITK image ("<getMovingDimensions()<<")."; throw mitk::AccessByItkException(str.str()); } if (registration->getTargetDimensions()!=VImageDimension) { map::core::OStringStream str; str << "Dimension of MITK image ("<getTargetDimensions()<<")."; throw mitk::AccessByItkException(str.str()); } const ConcreteRegistrationType* castedReg = dynamic_cast(registration); if (registration->getTargetDimensions()==2 && resultGeometry) { mitk::ImageMappingHelper::ResultImageGeometryType::BoundsArrayType bounds = resultGeometry->GetBounds(); if (bounds[4]!=0 || bounds[5]!=0) { //array "bounds" is constructed as [min Dim1, max Dim1, min Dim2, max Dim2, min Dim3, max Dim3] //therfore [4] and [5] must be 0 map::core::OStringStream str; str << "Dimension of defined result geometry does not equal the target dimension of the registration object ("<getTargetDimensions()<<")."; throw mitk::AccessByItkException(str.str()); } } //check/create resultDescriptor ///////////////////////// if (resultGeometry) { resultDescriptor = ResultImageDescriptorType::New(); typename ResultImageDescriptorType::PointType origin; typename ResultImageDescriptorType::SizeType size; typename ResultImageDescriptorType::SpacingType fieldSpacing; typename ResultImageDescriptorType::DirectionType matrix; mitk::ImageMappingHelper::ResultImageGeometryType::BoundsArrayType geoBounds = resultGeometry->GetBounds(); mitk::Vector3D geoSpacing = resultGeometry->GetSpacing(); mitk::Point3D geoOrigin = resultGeometry->GetOrigin(); mitk::AffineTransform3D::MatrixType geoMatrix = resultGeometry->GetIndexToWorldTransform()->GetMatrix(); for (unsigned int i = 0; i(geoOrigin[i]); fieldSpacing[i] = static_cast(geoSpacing[i]); size[i] = static_cast(geoBounds[(2*i)+1]-geoBounds[2*i])*fieldSpacing[i]; } //Matrix extraction matrix.SetIdentity(); unsigned int i; unsigned int j; /// \warning 2D MITK images could have a 3D rotation, since they have a 3x3 geometry matrix. /// If it is only a rotation around the transversal plane normal, it can be express with a 2x2 matrix. /// In this case, the ITK image conservs this information and is identical to the MITK image! /// If the MITK image contains any other rotation, the ITK image will have no rotation at all. /// Spacing is of course conserved in both cases. // the following loop devides by spacing now to normalize columns. // counterpart of InitializeByItk in mitkImage.h line 372 of revision 15092. // Check if information is lost if ( VImageDimension == 2) { if ( ( geoMatrix[0][2] != 0) || ( geoMatrix[1][2] != 0) || ( geoMatrix[2][0] != 0) || ( geoMatrix[2][1] != 0) || (( geoMatrix[2][2] != 1) && ( geoMatrix[2][2] != -1) )) { // The 2D MITK image contains 3D rotation information. // This cannot be expressed in a 2D ITK image, so the ITK image will have no rotation } else { // The 2D MITK image can be converted to an 2D ITK image without information loss! for ( i=0; i < 2; ++i) { for( j=0; j < 2; ++j ) { matrix[i][j] = geoMatrix[i][j]/fieldSpacing[j]; } } } } else if (VImageDimension == 3) { // Normal 3D image. Conversion possible without problem! for ( i=0; i < 3; ++i) { for( j=0; j < 3; ++j ) { matrix[i][j] = geoMatrix[i][j]/fieldSpacing[j]; } } } else { assert(0); throw mitk::AccessByItkException("Usage of resultGeometry for 2D images is not yet implemented."); /**@TODO Implement extraction of 2D-Rotation-Matrix out of 3D-Rotation-Matrix * to cover this case as well. * matrix = extract2DRotationMatrix(resultGeometry)*/ } resultDescriptor->setOrigin(origin); resultDescriptor->setSize(size); resultDescriptor->setSpacing(fieldSpacing); resultDescriptor->setDirection(matrix); } //do the mapping ///////////////////////// typedef ::itk::InterpolateImageFunction< ::itk::Image > BaseInterpolatorType; typename BaseInterpolatorType::Pointer interpolator = generateInterpolator< ::itk::Image >(interpolatorType); assert(interpolator.IsNotNull()); spTask->setImageInterpolator(interpolator); spTask->setInputImage(input); spTask->setRegistration(castedReg); spTask->setResultImageDescriptor(resultDescriptor); spTask->setThrowOnMappingError(throwOnMappingError); spTask->setErrorValue(errorValue); spTask->setThrowOnPaddingError(throwOnOutOfInputAreaError); spTask->setPaddingValue(paddingValue); spTask->execute(); mitk::CastToMitkImage<>(spTask->getResultImage(),result); } mitk::ImageMappingHelper::ResultImageType::Pointer mitk::ImageMappingHelper::map(const InputImageType* input, const RegistrationType* registration, bool throwOnOutOfInputAreaError, const double& paddingValue, const ResultImageGeometryType* resultGeometry, bool throwOnMappingError, const double& errorValue, mitk::ImageMappingInterpolator::Type interpolatorType) { if (!registration) { mitkThrow() << "Cannot map image. Passed registration wrapper pointer is nullptr."; } if (!input) { mitkThrow() << "Cannot map image. Passed image pointer is nullptr."; } ResultImageType::Pointer result; if(input->GetTimeSteps()==1) { //map the image and done AccessByItk_n(input, doMITKMap, (result, registration, throwOnOutOfInputAreaError, paddingValue, resultGeometry, throwOnMappingError, errorValue, interpolatorType)); } else { //map every time step and compose mitk::TimeGeometry::ConstPointer timeGeometry = input->GetTimeGeometry(); mitk::TimeGeometry::Pointer mappedTimeGeometry = timeGeometry->Clone(); for (unsigned int i = 0; iGetTimeSteps(); ++i) { ResultImageGeometryType::Pointer mappedGeometry = resultGeometry->Clone(); mappedTimeGeometry->SetTimeStepGeometry(mappedGeometry,i); } result = mitk::Image::New(); result->Initialize(input->GetPixelType(),*mappedTimeGeometry, 1, input->GetTimeSteps()); for (unsigned int i = 0; iGetTimeSteps(); ++i) { mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(input); imageTimeSelector->SetTimeNr(i); imageTimeSelector->UpdateLargestPossibleRegion(); InputImageType::Pointer timeStepInput = imageTimeSelector->GetOutput(); ResultImageType::Pointer timeStepResult; AccessByItk_n(timeStepInput, doMITKMap, (timeStepResult, registration, throwOnOutOfInputAreaError, paddingValue, resultGeometry, throwOnMappingError, errorValue, interpolatorType)); mitk::ImageReadAccessor readAccess(timeStepResult); result->SetVolume(readAccess.GetData(),i); } } return result; } mitk::ImageMappingHelper::ResultImageType::Pointer mitk::ImageMappingHelper::map(const InputImageType* input, const MITKRegistrationType* registration, bool throwOnOutOfInputAreaError, const double& paddingValue, const ResultImageGeometryType* resultGeometry, - bool throwOnMappingError, const double& errorValue, mitk::ImageMappingInterpolator::Type) + bool throwOnMappingError, const double& errorValue, mitk::ImageMappingInterpolator::Type interpolator) { if (!registration) { mitkThrow() << "Cannot map image. Passed registration wrapper pointer is nullptr."; } if (!registration->GetRegistration()) { mitkThrow() << "Cannot map image. Passed registration wrapper containes no registration."; } if (!input) { mitkThrow() << "Cannot map image. Passed image pointer is nullptr."; } - ResultImageType::Pointer result = map(input, registration->GetRegistration(), throwOnOutOfInputAreaError, paddingValue, resultGeometry, throwOnMappingError, errorValue); + ResultImageType::Pointer result = map(input, registration->GetRegistration(), throwOnOutOfInputAreaError, paddingValue, resultGeometry, throwOnMappingError, errorValue, interpolator); return result; } mitk::ImageMappingHelper::ResultImageType::Pointer mitk::ImageMappingHelper:: refineGeometry(const InputImageType* input, const RegistrationType* registration, bool throwOnError) { mitk::ImageMappingHelper::ResultImageType::Pointer result = nullptr; if (!registration) { mitkThrow() << "Cannot refine image geometry. Passed registration pointer is nullptr."; } if (!input) { mitkThrow() << "Cannot refine image geometry. Passed image pointer is nullptr."; } mitk::MITKRegistrationHelper::Affine3DTransformType::Pointer spTransform = mitk::MITKRegistrationHelper::getAffineMatrix(registration,false); if(spTransform.IsNull() && throwOnError) { mitkThrow() << "Cannot refine image geometry. Registration does not contain a suitable direct mapping kernel (3D affine transformation or compatible required)."; } if(spTransform.IsNotNull()) { //copy input image result = input->Clone(); //refine geometries for(unsigned int i = 0; i < result->GetTimeSteps(); ++i) { //refine every time step result->GetGeometry(i)->Compose(spTransform); } result->GetTimeGeometry()->Update(); } return result; } mitk::ImageMappingHelper::ResultImageType::Pointer mitk::ImageMappingHelper:: refineGeometry(const InputImageType* input, const MITKRegistrationType* registration, bool throwOnError) { if (!registration) { mitkThrow() << "Cannot refine image geometry. Passed registration wrapper pointer is nullptr."; } if (!registration->GetRegistration()) { mitkThrow() << "Cannot refine image geometry. Passed registration wrapper containes no registration."; } if (!input) { mitkThrow() << "Cannot refine image geometry. Passed image pointer is nullptr."; } ResultImageType::Pointer result = refineGeometry(input, registration->GetRegistration(), throwOnError); return result; } bool mitk::ImageMappingHelper:: canRefineGeometry(const RegistrationType* registration) { bool result = true; if (!registration) { mitkThrow() << "Cannot check refine capability of registration. Passed registration pointer is nullptr."; } //if the helper does not return null, we can refine the geometry. result = mitk::MITKRegistrationHelper::getAffineMatrix(registration,false).IsNotNull(); return result; } bool mitk::ImageMappingHelper:: canRefineGeometry(const MITKRegistrationType* registration) { if (!registration) { mitkThrow() << "Cannot check refine capability of registration. Passed registration wrapper pointer is nullptr."; } if (!registration->GetRegistration()) { mitkThrow() << "Cannot check refine capability of registration. Passed registration wrapper containes no registration."; } return canRefineGeometry(registration->GetRegistration()); } diff --git a/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkGIFConfigurationPanel.cpp b/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkGIFConfigurationPanel.cpp index 56fc0d851f..6f04c9d2d1 100644 --- a/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkGIFConfigurationPanel.cpp +++ b/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkGIFConfigurationPanel.cpp @@ -1,221 +1,225 @@ /*=================================================================== 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 "QmitkGIFConfigurationPanel.h" // QT #include #include #include #include #include #include #include #include #include mitkUI::GIFConfigurationPanel::GIFConfigurationPanel(QWidget * parent, mitk::AbstractGlobalImageFeature::Pointer calculator) : QWidget(parent), m_FeatureCalculator(calculator) { QVBoxLayout * lay = new QVBoxLayout; QHBoxLayout * checkboxLayout = new QHBoxLayout; m_CheckCalculateFeature = new QCheckBox; m_CheckCalculateFeature->setText(m_FeatureCalculator->GetFeatureClassName().c_str()); m_ButtonShowAdditionalConfiguration = new QPushButton; m_ButtonShowAdditionalConfiguration->setText("+"); m_ButtonShowAdditionalConfiguration->setMaximumWidth(30); m_ButtonShowAdditionalConfiguration->setCheckable(true); checkboxLayout->addWidget(m_CheckCalculateFeature); checkboxLayout->addWidget(m_ButtonShowAdditionalConfiguration); lay->addItem(checkboxLayout); QFormLayout * argumentLayout = new QFormLayout; QLabel * label1 = new QLabel("Use Argument"); QLabel * label2 = new QLabel("Argument Value"); argumentLayout->addRow(label1, label2); mitkCommandLineParser parser; m_FeatureCalculator->AddArguments(parser); std::vector < std::map > argumentList = parser.getArgumentList(); for (auto argument : argumentList) { QString longarg(argument["longarg"].ToString().c_str()); if (longarg.contains("::")) { QCheckBox * argumentBox = new QCheckBox; QWidget * secondWidget = NULL; argumentBox->setText(longarg); mitkCommandLineParser::Type type = us::any_cast(argument["valuetype"]); switch (type) { case mitkCommandLineParser::Bool: secondWidget = new QCheckBox; break; case mitkCommandLineParser::String: { QLineEdit* lineEdit = new QLineEdit; secondWidget = lineEdit; break; } case mitkCommandLineParser::Int: { QSpinBox* spinBox = new QSpinBox(); spinBox->setMinimum(std::numeric_limits::min()); spinBox->setMaximum(std::numeric_limits::max()); secondWidget = spinBox; break; } case mitkCommandLineParser::Float: { QDoubleSpinBox* spindBox = new QDoubleSpinBox; spindBox->setMinimum(std::numeric_limits::lowest()); spindBox->setMaximum(std::numeric_limits::max()); secondWidget = spindBox; break; } default: secondWidget = new QLabel("unkonw type"); } argumentLayout->addRow(argumentBox, secondWidget); } } if (argumentList.size() < 2) { m_ButtonShowAdditionalConfiguration->setVisible(false); } m_GroupBoxArguments = new QGroupBox; m_GroupBoxArguments->setTitle(""); m_GroupBoxArguments->setLayout(argumentLayout); m_GroupBoxArguments->setVisible(false); lay->addWidget(m_GroupBoxArguments); //lay->addItem(argumentLayout); // Buttons see https://joekuan.wordpress.com/2015/09/23/list-of-qt-icons/ // Resolution https://itk.org/Doxygen/html/classitk_1_1RecursiveMultiResolutionPyramidImageFilter.html // Wavelet https://code.google.com/archive/p/nwave/source/default/source this->setLayout(lay); connect((QObject*)(m_ButtonShowAdditionalConfiguration), SIGNAL(clicked(bool)), this, SLOT(OnSButtonShowAdditionalConfigurationPressed(bool))); } void mitkUI::GIFConfigurationPanel::OnSButtonShowAdditionalConfigurationPressed(bool /*status*/) { if (m_ButtonShowAdditionalConfiguration->isChecked()) { m_ButtonShowAdditionalConfiguration->setText("-"); m_GroupBoxArguments->setVisible(true); } else { m_ButtonShowAdditionalConfiguration->setText("+"); m_GroupBoxArguments->setVisible(false); } } void mitkUI::GIFConfigurationPanel::CalculateFeaturesUsingParameters(const mitk::Image::Pointer & feature, const mitk::Image::Pointer &mask, std::map < std::string, us::Any> parameter, mitk::AbstractGlobalImageFeature::FeatureListType &featureList) { parameter[m_FeatureCalculator->GetLongName()] = us::Any(true); if (m_CheckCalculateFeature->isChecked()) { for (int i = 0; i < m_GroupBoxArguments->layout()->count(); i+=2) { QCheckBox * argumentBox = dynamic_cast(m_GroupBoxArguments->layout()->itemAt(i)->widget()); if (argumentBox != NULL) { if (argumentBox->isChecked() == false) { continue; } std::string argumentName = argumentBox->text().toStdString(); QCheckBox * paramBool = dynamic_cast(m_GroupBoxArguments->layout()->itemAt(i + 1)->widget()); QLineEdit * paramText = dynamic_cast(m_GroupBoxArguments->layout()->itemAt(i + 1)->widget()); QSpinBox * paramInt = dynamic_cast(m_GroupBoxArguments->layout()->itemAt(i + 1)->widget()); QDoubleSpinBox * paramFloat = dynamic_cast(m_GroupBoxArguments->layout()->itemAt(i + 1)->widget()); if (paramBool == NULL && paramText == NULL && paramInt == NULL && paramFloat == NULL) { continue; } us::Any value; if (paramBool != NULL) { value = us::Any(paramBool->isChecked()); } if (paramText != NULL) { value = us::Any(paramText->text().toStdString()); } if (paramInt != NULL) { value = us::Any(paramInt->value()); } if (paramFloat != NULL) { value = us::Any(float(paramFloat->value())); } parameter[argumentName] = value; MITK_INFO << argumentName << " : " << value.ToString(); } } auto tmpPointer = m_FeatureCalculator->Clone(); mitk::AbstractGlobalImageFeature::Pointer tmpCalc = dynamic_cast(tmpPointer.GetPointer()); for (auto item : parameter) { MITK_INFO << item.first << " : " << item.second.ToString(); } tmpCalc->SetParameter(parameter); bool calculateSliceWise = false; int slice = 0; if (parameter.count("slice-wise")) { slice = us::any_cast(parameter["slice-wise"]); calculateSliceWise = true; } + if (parameter.count("direction")) + { + tmpCalc->SetDirection(us::any_cast(parameter["direction"])); + } if (parameter.count("encode-parameter-in-name")) { bool encodeParameter = us::any_cast(parameter["encode-parameter-in-name"]); tmpCalc->SetEncodeParameters(encodeParameter); } if (calculateSliceWise) { tmpCalc->CalculateFeaturesSliceWiseUsingParameters(feature, mask, slice, featureList); } else { tmpCalc->CalculateFeaturesUsingParameters(feature, mask, mask, featureList); } } } diff --git a/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationView.cpp b/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationView.cpp index 88ad07f15f..4bca11d9cd 100644 --- a/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationView.cpp +++ b/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationView.cpp @@ -1,379 +1,499 @@ /*=================================================================== 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 "QmitkRadiomicsTransformationView.h" // QT includes (GUI) #include #include #include #include #include #include #include +#include +#include +#include // Berry includes (selection service) #include #include // MITK includes (GUI) #include #include "QmitkDataNodeSelectionProvider.h" #include "mitkDataNodeObject.h" // MITK includes (general #include #include #include #include #include // Specific GUI Includes #include "QmitkGIFConfigurationPanel.h" QmitkRadiomicsTransformation::QmitkRadiomicsTransformation() : QmitkAbstractView(), m_Controls(nullptr) { } QmitkRadiomicsTransformation::~QmitkRadiomicsTransformation() { //berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); //if(s) // s->RemoveSelectionListener(m_SelectionListener); } void QmitkRadiomicsTransformation::CreateQtPartControl(QWidget *parent) { if (m_Controls == nullptr) { m_Controls = new Ui::QmitkRadiomicsTransformationViewControls; m_Controls->setupUi(parent); QLabel * label1 = new QLabel("Image: "); QmitkDataStorageComboBox * cb_inputimage = new QmitkDataStorageComboBox(this->GetDataStorage(), mitk::TNodePredicateDataType::New()); m_Controls->m_InputImageGroup->layout()->addWidget(label1); m_Controls->m_InputImageGroup->layout()->addWidget(cb_inputimage); this->CreateConnections(); } } void QmitkRadiomicsTransformation::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->buttonExecuteMultiresolution), SIGNAL(clicked() ), this, SLOT(executeButtonMultiResolutionPressed() ) ); connect((QObject*)(m_Controls->m_WaveletExecuteButton), SIGNAL(clicked()), this, SLOT(executeButtonWaveletPressed())); connect((QObject*)(m_Controls->m_ExecuteLOG), SIGNAL(clicked()), this, SLOT(executeButtonLoGPressed())); connect((QObject*)(m_Controls->buttonResampleImage), SIGNAL(clicked()), this, SLOT(executeButtonResamplingPressed())); + connect(m_Controls->buttonConvertToUChar, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(0); }); + //connect(m_Controls->buttonConvertToSChar, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(1); }); + connect(m_Controls->buttonConvertToChar, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(2); }); + connect(m_Controls->buttonConvertToUShort, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(3); }); + connect(m_Controls->buttonConvertToShort, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(4); }); + connect(m_Controls->buttonConvertToUInt, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(5); }); + connect(m_Controls->buttonConvertToInt, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(6); }); + //connect(m_Controls->buttonConvertToULong, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(7); }); + //connect(m_Controls->buttonConvertToLong, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(8); }); + connect(m_Controls->buttonConvertToFloat, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(9); }); + connect(m_Controls->buttonConvertToDouble, &QCommandLinkButton::clicked, this, [this] { executeConvertToButton(10); }); } } void QmitkRadiomicsTransformation::executeButtonMultiResolutionPressed() { QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls->m_InputImageGroup->layout()->itemAt(1)->widget()); mitk::BaseData* baseDataRawImage = NULL; mitk::Image::Pointer raw_image; std::string nodeName; if ((cb_image->GetSelectedNode().IsNotNull() ) ) { baseDataRawImage = (cb_image->GetSelectedNode()->GetData()); nodeName = cb_image->GetSelectedNode()->GetName(); } if ((baseDataRawImage != NULL)) { raw_image = dynamic_cast(baseDataRawImage); } else { QMessageBox msgBox; msgBox.setText("Please specify the images that shlould be used."); msgBox.exec(); return; } if (raw_image.IsNull()) { QMessageBox msgBox; msgBox.setText("Error during processing the specified images."); msgBox.exec(); return; } unsigned int numberOfLevels = m_Controls->m_NumberOfLevels->value(); bool resultAsDouble = m_Controls->m_resultAsDouble->isChecked(); auto results = mitk::TransformationOperation::MultiResolution(raw_image, numberOfLevels, resultAsDouble); unsigned int level = 1; for (auto image : results) { mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty("name", mitk::StringProperty::New(nodeName+"::MultiRes::Level-"+us::Any(numberOfLevels-level).ToString())); result->SetData(image); GetDataStorage()->Add(result, cb_image->GetSelectedNode()); ++level; } } void QmitkRadiomicsTransformation::executeButtonWaveletPressed() { QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls->m_InputImageGroup->layout()->itemAt(1)->widget()); mitk::BaseData* baseDataRawImage = NULL; mitk::Image::Pointer raw_image; std::string nodeName; if ((cb_image->GetSelectedNode().IsNotNull())) { baseDataRawImage = (cb_image->GetSelectedNode()->GetData()); nodeName = cb_image->GetSelectedNode()->GetName(); } if ((baseDataRawImage != NULL)) { raw_image = dynamic_cast(baseDataRawImage); } else { QMessageBox msgBox; msgBox.setText("Please specify the images that shlould be used."); msgBox.exec(); return; } if (raw_image.IsNull()) { QMessageBox msgBox; msgBox.setText("Error during processing the specified images."); msgBox.exec(); return; } unsigned int numberOfLevels = m_Controls->m_WaveletNumberOfLevels->value(); unsigned int numberOfBands = m_Controls->m_WaveletNumberOfBands->value(); mitk::BorderCondition condition = mitk::BorderCondition::Constant; mitk::WaveletType waveletType = mitk::WaveletType::Held; std::string waveletStr = m_Controls->m_WaveletWavelet->currentText().toStdString(); if (waveletStr == "Shannon") { waveletType = mitk::WaveletType::Shannon; } if (waveletStr == "Simoncelli") { waveletType = mitk::WaveletType::Simoncelli; } if (waveletStr == "Vow") { waveletType = mitk::WaveletType::Vow; } if (waveletStr == "Held") { waveletType = mitk::WaveletType::Held; } std::string conditionStr = m_Controls->m_WaveletBorderCondition->currentText().toStdString(); if (conditionStr == "Constant") { condition = mitk::BorderCondition::Constant; } if (conditionStr == "Periodic") { condition = mitk::BorderCondition::Periodic; } if (conditionStr == "Zero Flux Neumann") { condition = mitk::BorderCondition::ZeroFluxNeumann; } auto results = mitk::TransformationOperation::WaveletForward(raw_image, numberOfLevels, numberOfBands, condition, waveletType); unsigned int level = 0; for (auto image : results) { mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty("name", mitk::StringProperty::New(nodeName + "::Wavelet::"+waveletStr+"-"+conditionStr+"::Level-" + us::Any(level).ToString())); result->SetData(image); GetDataStorage()->Add(result, cb_image->GetSelectedNode()); ++level; } } void QmitkRadiomicsTransformation::executeButtonLoGPressed() { QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls->m_InputImageGroup->layout()->itemAt(1)->widget()); mitk::BaseData* baseDataRawImage = NULL; mitk::Image::Pointer raw_image; std::string nodeName; if ((cb_image->GetSelectedNode().IsNotNull())) { baseDataRawImage = (cb_image->GetSelectedNode()->GetData()); nodeName = cb_image->GetSelectedNode()->GetName(); } if ((baseDataRawImage != NULL)) { raw_image = dynamic_cast(baseDataRawImage); } else { QMessageBox msgBox; msgBox.setText("Please specify the images that shlould be used."); msgBox.exec(); return; } if (raw_image.IsNull()) { QMessageBox msgBox; msgBox.setText("Error during processing the specified images."); msgBox.exec(); return; } double sigma = m_Controls->m_LoGSigma->value(); bool resultAsDouble = m_Controls->m_LogResultAsDouble->isChecked(); auto results = mitk::TransformationOperation::LaplacianOfGaussian(raw_image, sigma, resultAsDouble); mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty("name", mitk::StringProperty::New(nodeName + "::LoG::Sigma-" + us::Any(sigma).ToString())); result->SetData(results); GetDataStorage()->Add(result, cb_image->GetSelectedNode()); } void QmitkRadiomicsTransformation::executeButtonResamplingPressed() { QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls->m_InputImageGroup->layout()->itemAt(1)->widget()); mitk::BaseData* baseDataRawImage = NULL; mitk::Image::Pointer raw_image; std::string nodeName; if ((cb_image->GetSelectedNode().IsNotNull())) { baseDataRawImage = (cb_image->GetSelectedNode()->GetData()); nodeName = cb_image->GetSelectedNode()->GetName(); } if ((baseDataRawImage != NULL)) { raw_image = dynamic_cast(baseDataRawImage); } else { QMessageBox msgBox; msgBox.setText("Please specify the images that shlould be used."); msgBox.exec(); return; } if (raw_image.IsNull()) { QMessageBox msgBox; msgBox.setText("Error during processing the specified images."); msgBox.exec(); return; } mitk::ImageMappingInterpolator::Type interpolatorType; switch (m_Controls->comboInterpolationMode->currentIndex()) { case 0: interpolatorType = mitk::ImageMappingInterpolator::Linear; break; case 1: interpolatorType = mitk::ImageMappingInterpolator::BSpline_3; break; case 2: interpolatorType = mitk::ImageMappingInterpolator::NearestNeighbor; break; case 3: interpolatorType = mitk::ImageMappingInterpolator::WSinc_Hamming; break; case 4: interpolatorType = mitk::ImageMappingInterpolator::WSinc_Welch; break; default: interpolatorType = mitk::ImageMappingInterpolator::Linear; } mitk::GridInterpolationPositionType gridPosition; switch (m_Controls->comboAxisAlignment->currentIndex()) { case 0: gridPosition = mitk::GridInterpolationPositionType::OriginAligned; break; case 1: gridPosition = mitk::GridInterpolationPositionType::CenterAligned; break; case 2: gridPosition = mitk::GridInterpolationPositionType::SameSize; break; default: gridPosition = mitk::GridInterpolationPositionType::OriginAligned; } bool resultAsDouble = m_Controls->checkResamplingOutputAsDouble->isChecked(); bool roundResult = m_Controls->checkResamplingRoundOutput->isChecked(); mitk::Vector3D spacing; spacing.Fill(-1); if (m_Controls->checkResampleX->isChecked()) { spacing[0] = m_Controls->doubleSpinDimensionX->value(); } if (m_Controls->checkResampleY->isChecked()) { spacing[1] = m_Controls->doubleSpinDimensionY->value(); } if (m_Controls->checkResampleZ->isChecked()) { spacing[2] = m_Controls->doubleSpinDimensionZ->value(); } mitk::Image::Pointer results; if (m_Controls->checkResampleAsMask->isChecked()) { results = mitk::TransformationOperation::ResampleMask(raw_image, spacing, interpolatorType, gridPosition); mitk::LabelSetImage::Pointer oldLabelImage = dynamic_cast (raw_image.GetPointer()); if (oldLabelImage.IsNotNull()) { mitk::LabelSetImage::Pointer labelResult = mitk::LabelSetImage::New(); labelResult->InitializeByLabeledImage(results); labelResult->AddLabelSetToLayer(labelResult->GetActiveLayer(), oldLabelImage->GetLabelSet()); results = dynamic_cast(labelResult.GetPointer()); } } else { results = mitk::TransformationOperation::ResampleImage(raw_image, spacing, interpolatorType, gridPosition, resultAsDouble, roundResult); } mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty("name", mitk::StringProperty::New(nodeName + "::Resampled" )); result->SetData(results); GetDataStorage()->Add(result, cb_image->GetSelectedNode()); } + +void QmitkRadiomicsTransformation::executeConvertToButton(int button) +{ + QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls->m_InputImageGroup->layout()->itemAt(1)->widget()); + mitk::BaseData* baseDataRawImage = NULL; + + mitk::Image::Pointer raw_image; + std::string nodeName; + if ((cb_image->GetSelectedNode().IsNotNull())) + { + baseDataRawImage = (cb_image->GetSelectedNode()->GetData()); + nodeName = cb_image->GetSelectedNode()->GetName(); + } + if ((baseDataRawImage != NULL)) + { + raw_image = dynamic_cast(baseDataRawImage); + } + else { + QMessageBox msgBox; + msgBox.setText("Please specify the images that shlould be used."); + msgBox.exec(); + return; + } + if (raw_image.IsNull()) + { + QMessageBox msgBox; + msgBox.setText("Error during processing the specified images."); + msgBox.exec(); + return; + } + + mitk::Image::Pointer result; + std::string typeString = ""; + int successful = 1; + + switch (button) + { + case 0: + result = mitk::TransformationOperation::CastToUnsignedChar(raw_image, successful); + typeString = "uchar"; + break; + case 1: + result = mitk::TransformationOperation::CastToSignedChar(raw_image, successful); + typeString = "schar"; + break; + case 2: + result = mitk::TransformationOperation::CastToChar(raw_image, successful); + typeString = "char"; + break; + case 3: + result = mitk::TransformationOperation::CastToUnsignedShort(raw_image, successful); + typeString = "ushort"; + break; + case 4: + result = mitk::TransformationOperation::CastToShort(raw_image, successful); + typeString = "short"; + break; + case 5: + result = mitk::TransformationOperation::CastToUnsignedInt(raw_image, successful); + typeString = "uint"; + break; + case 6: + result = mitk::TransformationOperation::CastToInt(raw_image, successful); + typeString = "int"; + break; + case 7: + result = mitk::TransformationOperation::CastToUnsignedLong(raw_image, successful); + typeString = "ulong"; + break; + case 8: + result = mitk::TransformationOperation::CastToLong(raw_image, successful); + typeString = "long"; + break; + case 9: + result = mitk::TransformationOperation::CastToFloat(raw_image, successful); + typeString = "float"; + break; + case 10: + result = mitk::TransformationOperation::CastToDouble(raw_image, successful); + typeString = "double"; + break; + } + + if (successful == 0) + { + mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); + resultNode->SetProperty("name", mitk::StringProperty::New(nodeName + "::Type-" + typeString)); + resultNode->SetData(result); + GetDataStorage()->Add(resultNode, cb_image->GetSelectedNode()); + } + else if (successful == 5) + { + QMessageBox msgBox; + msgBox.setText("Original Image has an unsupported image type."); + msgBox.exec(); + return; + } + else { + QMessageBox msgBox; + msgBox.setText("An unknown error occured. This could be caused by unsuported data types."); + msgBox.exec(); + MITK_INFO << "Unknown error. Return value is " << successful; + return; + } +} + void QmitkRadiomicsTransformation::SetFocus() { } //datamanager selection changed void QmitkRadiomicsTransformation::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList& nodes) { //any nodes there? if (!nodes.empty()) { } } diff --git a/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationView.h b/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationView.h index 68ae5b0e14..2c8fd725b9 100644 --- a/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationView.h +++ b/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationView.h @@ -1,99 +1,101 @@ /*=================================================================== 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. ===================================================================*/ #if !defined(QmitkRadiomicsTransformationView_H__INCLUDED) #define QmitkRadiomicsTransformationView_H__INCLUDED #include #include #include "ui_QmitkRadiomicsTransformationViewControls.h" #include "QmitkStepperAdapter.h" #include #include /*! \brief This module allows to use some basic image processing filters for preprocessing, image enhancement and testing purposes Several basic ITK image processing filters, like denoising, morphological and edge detection are encapsulated in this module and can be selected via a list and an intuitive parameter input. The selected filter will be applied on the image, and a new image showing the output is displayed as result. Also, some image arithmetic operations are available. Images can be 3D or 4D. In the 4D case, the filters work on the 3D image selected via the time slider. The result is also a 3D image. \class QmitkRadiomicsTransformation \author Tobias Schwarz \version 1.0 (3M3) \date 2009-05-10 \ingroup Bundles */ class RADIOMICS_EXPORT QmitkRadiomicsTransformation : public QmitkAbstractView { Q_OBJECT public: /*! \brief default constructor */ QmitkRadiomicsTransformation(); /*! \brief default destructor */ virtual ~QmitkRadiomicsTransformation(); /*! \brief method for creating the widget containing the application controls, like sliders, buttons etc. */ virtual void CreateQtPartControl(QWidget *parent) override; virtual void SetFocus() override; /*! \brief method for creating the connections of main and control widget */ virtual void CreateConnections(); /*! \brief Invoked when the DataManager selection changed */ virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override; protected slots: void executeButtonMultiResolutionPressed(); void executeButtonWaveletPressed(); void executeButtonLoGPressed(); void executeButtonResamplingPressed(); + void executeConvertToButton(int button); + private: /*! * controls containing sliders for scrolling through the slices */ Ui::QmitkRadiomicsTransformationViewControls *m_Controls; }; #endif // !defined(QmitkRadiomicsTransformation_H__INCLUDED) diff --git a/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationViewControls.ui b/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationViewControls.ui index 4dcd715d4f..a910aeec23 100644 --- a/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationViewControls.ui +++ b/Plugins/org.mitk.gui.qt.radiomics/src/internal/QmitkRadiomicsTransformationViewControls.ui @@ -1,506 +1,594 @@ QmitkRadiomicsTransformationViewControls 0 0 448 980 Form QFrame::NoFrame QFrame::Raised - 0 + 4 0 0 430 - 846 + 819 Multi-Resolution Pyramid Number of Levels: 1 Return result as double: true true Execute Multi-Resolution Pyramid Qt::Vertical 20 40 + + + 0 + 0 + 430 + 819 + + Resample Image Dimension X true Dimension Y true Dimension Z true 7 40000000.000000000000000 7 40000000.000000000000000 7 40000000.000000000000000 Interpolation mode Grid alignment method Linear B-Spline Nearest Neighbour WSinc Hamming WSinc Welch Origin aligned Center aligned Same size (adapts final dimension) Output as double Resample as mask Round output Resample Image Qt::Vertical 20 40 0 0 430 - 846 + 819 Wavelet Transformation Number of Levels: 1 20000 Number of Bands: 1 2000 Border Condition: Wavelet: Constant Periodic Zero Flux Neumann Shannon Simoncelli Vow Held Execute Wavelet Transformation Qt::Vertical 20 40 0 0 430 - 846 + 819 Laplacian of Gaussian 4 1.000000000000000 1000000000000.000000000000000 Gaussian Sigma: Return result as double: true Execute Laplacian of Gaussian Qt::Vertical 20 40 + + + Transform Data Type + + + + + + + + Convert to Unsigned Char + + + + + + + Convert to Char + + + + + + + Convert to Unsigned Short + + + + + + + Convert to Short + + + + + + + Convert to Unsigned Int + + + + + + + Convert to Int + + + + + + + Convert to Float + + + + + + + Convert to Double + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + diff --git a/Wrapping/CMakeLists.txt b/Wrapping/CMakeLists.txt index c757046536..022aa5d433 100644 --- a/Wrapping/CMakeLists.txt +++ b/Wrapping/CMakeLists.txt @@ -1,70 +1,70 @@ find_package(SWIG QUIET) if(SWIG_FOUND) include(mitkLanguageOptions) include(UseSWIG) include(mitkSwigAddLibraryDependencies) include(mitkSwigPrepareFiles) # Path to common files set(MITK_WRAPPING_COMMON_DIR ${MITK_SOURCE_DIR}/Wrapping/Common) # make a manual list of dependencies for the Swig.i files - list( APPEND SWIG_EXTRA_DEPS - "${MITK_WRAPPING_COMMON_DIR}/MITK_Common.i" - ) +# list( APPEND SWIG_EXTRA_DEPS +# "${MITK_WRAPPING_COMMON_DIR}/MITK_Common.i" +# ) # A general packaging target, not built by default, to build packages for each # language. This should depend on all language specific targets. add_custom_target( dist ${CMAKE_COMMAND} -E echo "Finished generating wrapped packages for distribution..." ) # # lua SWIG configuration # #if ( WRAP_LUA ) # add_subdirectory ( Lua ) #endif() # # python SWIG configuration # if ( WRAP_PYTHON ) add_subdirectory ( Python ) endif() # # ruby SWIG configuration # #if ( WRAP_RUBY ) # add_subdirectory ( Ruby ) #endif() # # JAVA SWIG configuration # #if ( WRAP_JAVA ) # add_subdirectory( Java ) #endif() # # C# SWIG configuration # #if ( WRAP_CSHARP ) # add_subdirectory ( CSharp ) #endif() # # TCL SWIG configuration # #if ( WRAP_TCL ) # add_subdirectory ( Tcl ) #endif() # # R SWIG configuration # #if ( WRAP_R ) # add_subdirectory( R ) #endif() endif() diff --git a/Wrapping/Common/mitk_swig_classes.i b/Wrapping/Common/mitk_swig_classes.i index 89bfc0fad8..784530af17 100644 --- a/Wrapping/Common/mitk_swig_classes.i +++ b/Wrapping/Common/mitk_swig_classes.i @@ -1,157 +1,202 @@ // // Defining some Macros that make problems with SWIG as the // corresponding definitions are not included by default. // Luckely, these includes are not necessary for SWIG. // #define ITK_NOEXCEPT #define ITKCommon_EXPORT #define ITK_OVERRIDE #define MITKCORE_EXPORT #define MITKCLCORE_EXPORT #define MITKCLUTILITIES_EXPORT #define ITKCommon_EXPORT #define MITKMATCHPOINTREGISTRATION_EXPORT #define MAPDeployment_EXPORT #define MAPAlgorithms_EXPORT #define MITKSEGMENTATION_EXPORT #define MITKMULTILABEL_EXPORT +#define MITKBASICIMAGEPROCESSING_EXPORT + +#define VCL_TEMPLATE_EXPORT #define ITKCommon_EXPORT #define ITK_FORWARD_EXPORT #define ITK_OVERRIDE #define ITK_NOEXCEPT %include %include %include %include %include %include #define DEPRECATED(func) func #undef ITK_DISALLOW_COPY_AND_ASSIGN #define ITK_DISALLOW_COPY_AND_ASSIGN(TypeName) +typedef double ScalarType; +typedef Vector3D mitk::Vector3D; + + %pythoncode %{ convertion_list = {} %} SWIG_ADD_NONOBJECT_CLASS(Indent, itkIndent.h, itk) SWIG_ADD_MITK_CLASS(LightObject, itkLightObject.h, itk) SWIG_ADD_MITK_CLASS(Object, itkObject.h, itk) SWIG_ADD_MITK_CLASS(DataObject, itkDataObject.h, itk) SWIG_ADD_MITK_CLASS(TimeGeometry, mitkTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(ArbitraryTimeGeometry, mitkArbitraryTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(ProportionalTimeGeometry, mitkProportionalTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(BaseGeometry, mitkBaseGeometry.h, mitk) SWIG_ADD_MITK_CLASS(Geometry3D, mitkGeometry3D.h, mitk) SWIG_ADD_MITK_CLASS(SlicedGeometry3D, mitkSlicedGeometry3D.h, mitk) SWIG_ADD_MITK_CLASS(PlaneGeometry , mitkPlaneGeometry.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(BoundingBox, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(TimeBounds, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(FixedArrayType, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point2D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point3D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point4D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point2I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point3I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point4I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(VnlVector, mitkVector.h, mitk) -SWIG_ADD_NONOBJECT_CLASS(Vector2D, mitkVector.h, mitk) -SWIG_ADD_NONOBJECT_CLASS(Vector3D, mitkVector.h, mitk) -SWIG_ADD_NONOBJECT_CLASS(Vector4D, mitkVector.h, mitk) +%ignore rBegin() const; +%ignore rEnd() const; +%ignore rBegin(); +%ignore rEnd(); +%ignore itk::Vector::GetVnlVector; +%ignore itk::Vector::Get_vnl_vector; +%ignore itk::Vector::Get_vnl_vector const; + +%{ + #include + #include + #include + typedef vnl_vector_ref VnlVectorRef; +%} +//%include +//MITKSWIG_ADD_CLASS(VnlVectorRef, mitkVector.h,) +//typedef ::VnlVectorRef VnlVectorRef; +class VnlVectorRef; +%template(VectorVnlVectorRefPointer) std::vector<::VnlVectorRef * >; +//SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(VnlVectorRef, mitkVector.h, ) + +%include +%include +class itk::FixedArray::ReverseIterator; +//%template(VnlVectorRef) vnl_vector_ref; +%template(itkFixedArray3D) itk::FixedArray; +%template(itkVector2D) itk::Vector; +%template(itkVector3D) itk::Vector; +%template(itkVector4D) itk::Vector; + + +SWIG_ADD_NONOBJECT_TEMPLATE_CLASS(Vector2D, mitkVector.h, mitk) +%template(Vector2D) mitk::Vector; +SWIG_ADD_NONOBJECT_TEMPLATE_CLASS(Vector3D, mitkVector.h, mitk) +%template(Vector3D) mitk::Vector; +SWIG_ADD_NONOBJECT_TEMPLATE_CLASS(Vector4D, mitkVector.h, mitk) +%template(Vector4D) mitk::Vector; SWIG_ADD_MITK_CLASS(BaseData, mitkBaseData.h, mitk) SWIG_ADD_MITK_CLASS(SlicedData, mitkSlicedData.h, mitk) SWIG_ADD_MITK_CLASS(Image, mitkImage.h, mitk) SWIG_ADD_MITK_CLASS(LabelSetImage, mitkLabelSetImage.h, mitk) SWIG_ADD_MITK_CLASS(PointSet, mitkPointSet.h, mitk) %{ using mitk::Message; %} // // Phenotyping Related Classes // SWIG_ADD_MITK_CLASS(AbstractGlobalImageFeature, mitkAbstractGlobalImageFeature.h, mitk) SWIG_ADD_MITK_CLASS(GIFImageDescriptionFeatures, mitkGIFImageDescriptionFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderStatistics, mitkGIFFirstOrderStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderHistogramStatistics, mitkGIFFirstOrderHistogramStatistics.h, mitk) +SWIG_ADD_MITK_CLASS(GIFFirstOrderNumericStatistics, mitkGIFFirstOrderNumericStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFVolumetricStatistics, mitkGIFVolumetricStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFVolumetricDensityStatistics, mitkGIFVolumetricDensityStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFCooccurenceMatrix2, mitkGIFCooccurenceMatrix2.h, mitk) SWIG_ADD_MITK_CLASS(GIFNeighbouringGreyLevelDependenceFeature, mitkGIFNeighbouringGreyLevelDependenceFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelRunLength, mitkGIFGreyLevelRunLength.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelSizeZone, mitkGIFGreyLevelSizeZone.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelDistanceZone, mitkGIFGreyLevelDistanceZone.h, mitk) SWIG_ADD_MITK_CLASS(GIFLocalIntensity, mitkGIFLocalIntensity.h, mitk) SWIG_ADD_MITK_CLASS(GIFIntensityVolumeHistogramFeatures, mitkGIFIntensityVolumeHistogramFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFNeighbourhoodGreyToneDifferenceFeatures, mitkGIFNeighbourhoodGreyToneDifferenceFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFCurvatureStatistic, mitkGIFCurvatureStatistic.h, mitk) // // Conversion and Segmentation based Classes // SWIG_ADD_MITK_CLASS(ContourModelSetToImageFilter, mitkContourModelSetToImageFilter.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(BooleanOperation, mitkBooleanOperation.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(MorphologicalOperations, mitkMorphologicalOperations.h, mitk) +SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(MaskCleaningOperation, mitkMaskCleaningOperation.h, mitk) +SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(TransformationOperation, mitkTransformationOperation.h, mitk) +SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(ArithmeticOperation, mitkArithmeticOperation.h, mitk) %{ #include typedef itk::DataObject::DataObjectIdentifierType DataObjectIdentifierType; typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType; %} // // MatchPoint Related Classes // %ignore DLLHandle::LibraryHandleType; %{ #include namespace core { typedef std::string String; } typedef map::deployment::DLLHandle::LibraryHandleType LibraryHandleType; typedef map::deployment::DLLHandle DLLHandle; %} namespace core { typedef std::string String; } %nodefaultctor LibraryHandleType; struct LibraryHandleType {}; %include SWIG_ADD_MITK_CLASS(UID,mapUID.h, map::algorithm) SWIG_ADD_MITK_CLASS(DLLInfo, mapDeploymentDLLInfo.h, map::deployment) //SWIG_ADD_MITK_CLASS_VECTORFREE(DLLHandle, mapDeploymentDLLHandle.h, map::deployment) SWIG_ADD_MITK_CLASS_VECTORFREE(DLLDirectoryBrowser, mapDeploymentDLLDirectoryBrowser.h, ::map::deployment) MITKSWIG_ADD_HEADERFILE(mapDeploymentDLLAccess.h) %{ DLLHandle const * ConvertDLLHandleSmartPointerToPointer(itk::SmartPointer p) { return p.GetPointer(); } %} DLLHandle const * ConvertDLLHandleSmartPointerToPointer(DLLHandle::Pointer p); MITKSWIG_ADD_CLASS(MITKAlgorithmHelper, mitkAlgorithmHelper.h, mitk) MITKSWIG_ADD_CLASS(RegistrationType, mitkImageMappingHelper.h, mitk::ImageMappingHelper) MITKSWIG_ADD_CLASS(MITKRegistrationType, mitkImageMappingHelper.h, mitk::ImageMappingHelper) // SWIG_ADD_MITK_CLASS(FastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm, mitkFastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(LevelSetMotionMultiResDefaultRegistrationAlgorithm, mitkLevelSetMotionMultiResDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalAffineDefaultRegistrationAlgorithm, mitkMultiModalAffineDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalRigidDefaultRegistrationAlgorithm, mitkMultiModalRigidDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalTransDefaultRegistrationAlgorithm, mitkMultiModalTransDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(RigidClosedFormPointsDefaultRegistrationAlgorithm, mitkRigidClosedFormPointsDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(RigidICPDefaultRegistrationAlgorithm, mitkRigidICPDefaultRegistrationAlgorithm.h, mitk) \ No newline at end of file diff --git a/Wrapping/Common/mitk_swig_macros.i b/Wrapping/Common/mitk_swig_macros.i index f3f8c589a5..8a9938ac96 100644 --- a/Wrapping/Common/mitk_swig_macros.i +++ b/Wrapping/Common/mitk_swig_macros.i @@ -1,232 +1,257 @@ // // This file contains macros for swig. // // // MITKSWIG_ADD_HEADERFILE includes a header-file into SWIG // %define MITKSWIG_ADD_HEADERFILE( classinclude ) // Include the given header, where the class definition is found %include < ## classinclude ## > // Include the include file in the generated cpp file %{ #include < ## classinclude ## > %} %enddef // // MITKSWIG_ADD_CLASS is a helper macro in order to do // all important stuff in order to wrap an existing // class // %define MITKSWIG_ADD_CLASS(classname, classinclude, nspace) MITKSWIG_ADD_HEADERFILE( classinclude ) // Using class name in order to remove ambigiouties %{ typedef nspace ## :: ## classname classname ## ; using nspace ## :: ## classname ; %} using nspace ##:: ## classname ; // Typedef is necessary to overcome ambigiouties resulting in the fact that SWIG // ignores namespaces. This can lead to some problems with templates. typedef nspace ## :: ## classname classname ## ; %enddef // // MITKSWIG_AUTOMATED_CASTING is a helper macro in order to // provide a convinience interface for up/downcasting of // classes // %define MITKSWIG_AUTOMATED_CASTING(classname, classinclude, nspace) // Define a conversion method to convert from and to types %template(ConvertTo ## classname) ConvertTo< nspace ##:: ## classname ## >; // This extend is necessary to have the automatic cast methods available %extend itk::SmartPointer< nspace ## :: ## classname ## ::Self> { %pythoncode %{ def _GetListOfValidItems(self): - return [str(k) for k in self.GetClassHierarchy() if str(k) in convertion_list.keys() ] + return [str(k).replace("class itk::","") for k in self.GetClassHierarchy() if str(k).replace("class itk::","") in convertion_list.keys() ] %} %pythoncode %{ def __getattr__(self, item): if type(item)==str: if (len(item) > 9) and ('ConvertTo' in item): searchString=item[9:] if searchString in self._GetListOfValidItems(): def func_t(): return convertion_list[searchString](self) return func_t %} %pythoncode %{ def __dir__(self): return super().__dir__() + ['ConvertTo'+k for k in self._GetListOfValidItems()] %} } %extend std::vector< nspace ## :: ## classname *>::value_type { %pythoncode %{ def _GetListOfValidItems(self): return [str(k) for k in self.GetClassHierarchy() if str(k) in convertion_list.keys() ] %} %pythoncode %{ def __getattr__(self, item): if type(item)==str: if (len(item) > 9) and ('ConvertTo' in item): searchString=item[9:] if searchString in self._GetListOfValidItems(): def func_t(): return convertion_list[searchString](self) return func_t %} %pythoncode %{ def __dir__(self): return super().__dir__() + ['ConvertTo'+k for k in self._GetListOfValidItems()] %} } %pythoncode %{ convertion_list['classname'] = ConvertTo ## classname %} %enddef // // MITKSWIG_SMARTPOINTERVECTOR : Wrapper for Vectors of Smartpointer-Classes // %define MITKSWIG_SMARTPOINTERVECTOR(classname, classinclude, nspace) // Initianziation of std. vectors containing pointers to these classes. This allows to use // vectors of these types as target language arrays. %template(Vector ## classname ## Pointer) std::vector< nspace ## :: ## classname ## ::Pointer >; %template(Vector ## classname) std::vector< nspace ## :: ## classname ## ::Self *>; %enddef // // MITKSWIG_POINTERVECTOR : Wrapper for Vectors of Classes // %define MITKSWIG_POINTERVECTOR(classname, classinclude, nspace) // Initianziation of std. vectors containing pointers to these classes. This allows to use // vectors of these types as target language arrays. %template(Vector ## classname ## Pointer) std::vector< nspace ## :: ## classname * >; %template(Vector ## classname) std::vector< nspace ## :: ## classname >; %enddef // // MITKSWIG_MITKSMARTPOINTER_INITIALIZATION : Wrapper for Vectors of Smartpointer-Classes // %define MITKSWIG_MITKSMARTPOINTER_INITIALIZATION(classname, classinclude, nspace) // Declaring that this class is a smart-pointer class, in order to handle // online upcasting where necessary (for example python) + %feature("smartptr", noblock=1) classname { classname ## ::Pointer } + %feature("smartptr", noblock=1) nspace ##:: ## classname { nspace ## :: ## classname ## ::Pointer } + %feature("smartptr", noblock=1) nspace ##:: ## classname { classname ## ::Pointer } %feature("smartptr", noblock=1) nspace ##:: ## classname { itk::SmartPointer } %enddef // // MITKSWIG_MITKSMARTPOINTER_TEMPLATE : Wrapper for Vectors of Smartpointer-Classes // %define MITKSWIG_MITKSMARTPOINTER_TEMPLATE(classname, classinclude, nspace) // Defining the Smartpointer, allows easy access in target language %template(classname ## Pointer) itk::SmartPointer; %enddef // // SWIG_ADD_MITK_CLASS is a helper macro in order to do // all important stuff before an mitk::Class is included. // Requires the name of the class as it is in c++ as classname // and the include file, in which the class is defined. // It is assumed that the class is somehow inherited from // mitk::BaseData, and supports smartpointers. // %define SWIG_ADD_MITK_CLASS_VECTORFREE(classname, classinclude, nspace) %include < ## classinclude ## > MITKSWIG_MITKSMARTPOINTER_INITIALIZATION(classname, classinclude, nspace) MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) + //class classname ## ; + //class classname ## ::Pointer; + class nspace ## :: ## classname ## ; class nspace ## :: ## classname ## ::Pointer; MITKSWIG_MITKSMARTPOINTER_TEMPLATE(classname, classinclude, nspace) MITKSWIG_AUTOMATED_CASTING(classname, classinclude, nspace) %enddef // // SWIG_ADD_MITK_CLASS is a helper macro in order to do // all important stuff before an mitk::Class is included. // Requires the name of the class as it is in c++ as classname // and the include file, in which the class is defined. // It is assumed that the class is somehow inherited from // mitk::BaseData, and supports smartpointers. // %define SWIG_ADD_MITK_CLASS(classname, classinclude, nspace) %include < ## classinclude ## > MITKSWIG_MITKSMARTPOINTER_INITIALIZATION(classname, classinclude, nspace) MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) - + // Defining only the original classname + // If the ::Pointer is also defined, smartpointer won't work class nspace ## :: ## classname ## ; - class nspace ## :: ## classname ## ::Pointer; + //class nspace ## :: ## classname ## ::Pointer; // It is important to first define the Vectors and // then define the Smartpointer. Otherwise a SWIG-bug ... MITKSWIG_SMARTPOINTERVECTOR(classname, classinclude, nspace) MITKSWIG_MITKSMARTPOINTER_TEMPLATE(classname, classinclude, nspace) MITKSWIG_AUTOMATED_CASTING(classname, classinclude, nspace) %enddef // // SWIG_ADD_NONOBJECT_CLASS is a helper macro in order to do // all important stuff before an mitk::Class is included. // Requires the name of the class as it is in c++ as classname // and the include file, in which the class is defined. // It is assumed that the class is somehow inherited from // mitk::BaseData, and supports smartpointers. // %define SWIG_ADD_NONOBJECT_CLASS(classname, classinclude, nspace) %include < ## classinclude ## > MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) // Typedef is necessary to overcome ambigiouties resulting in the fact that SWIG // ignores namespaces. This can lead to some problems with templates. typedef nspace ## :: ## classname classname ## ; class nspace ## :: ## classname ## ; MITKSWIG_POINTERVECTOR(classname, classinclude, nspace) %enddef +// +// SWIG_ADD_NONOBJECT_CLASS is a helper macro in order to do +// all important stuff before an mitk::Class is included. +// Requires the name of the class as it is in c++ as classname +// and the include file, in which the class is defined. +// It is assumed that the class is somehow inherited from +// mitk::BaseData, and supports smartpointers. +// +%define SWIG_ADD_NONOBJECT_TEMPLATE_CLASS(classname, classinclude, nspace) + %include < ## classinclude ## > + MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) + + //%template(classname) templateArgs; + //class nspace ## :: ## classname ## ; + + MITKSWIG_POINTERVECTOR(classname, classinclude, nspace) +%enddef + // // SWIG_ADD_NONOBJECT_CLASS is a helper macro in order to do // all important stuff before an mitk::Class is included. // Requires the name of the class as it is in c++ as classname // and the include file, in which the class is defined. // It is assumed that the class is somehow inherited from // mitk::BaseData, and supports smartpointers. // %define SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(classname, classinclude, nspace) %include < ## classinclude ## > MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) // Typedef is necessary to overcome ambigiouties resulting in the fact that SWIG // ignores namespaces. This can lead to some problems with templates. typedef nspace ## :: ## classname classname ## ; // Initianziation of std. vectors containing pointers to these classes. This allows to use // vectors of these types as target language arrays. %template(Vector ## classname ## Pointer) std::vector< nspace ## :: ## classname * >; %enddef diff --git a/Wrapping/Python/CMakeLists.txt b/Wrapping/Python/CMakeLists.txt index cb9327dc76..724d6cdca1 100644 --- a/Wrapping/Python/CMakeLists.txt +++ b/Wrapping/Python/CMakeLists.txt @@ -1,77 +1,77 @@ # Version 2.8.1 is the minium requirement for this script. # this is lower than the general minimum requirement. #cmake_minimum_required ( VERSION 2.8.1 FATAL_ERROR ) include(mitkTargetLinkLibrariesWithDynamicLookup) project( MITK_Python ) set(CMAKE_SHARED_LINKER_FLAGS "" CACHE INTERNAL "" FORCE) set(CMAKE_MODULE_LINKER_FLAGS "" CACHE INTERNAL "" FORCE) mitk_check_dynamic_lookup(MODULE SHARED MITK_UNDEFINED_SYMBOLS_ALLOWED ) # # Find the necessary libraries etc.. # if ( MITK_UNDEFINED_SYMBOLS_ALLOWED ) set( _QUIET_LIBRARY "QUIET" ) else() set( _QUIET_LIBRARY "REQUIRED" ) endif() find_package ( PythonInterp REQUIRED ) find_package ( PythonLibs ${_QUIET_LIBRARY} ) include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) # # Options # option ( MITK_PYTHON_THREADS "Enable threaded python usage by unlocking the GIL." ON ) mark_as_advanced( MITK_PYTHON_THREADS ) option ( MITK_PYTHON_EGG "Add building of python eggs to the dist target." OFF ) mark_as_advanced( MITK_PYTHON_EGG ) option ( MITK_PYTHON_WHEEL "Add building of python wheels to the dist target." ON ) mark_as_advanced( MITK_PYTHON_WHEEL ) # Prepare the SWIG-File, i.e. especially add necessary include folders -mitkSwigPrepareFiles(pyMITK MITK.i "MitkCore;MitkCLCore;MitkCLUtilities;ITKCommon;MitkMatchPointRegistration;MitkSegmentation;MitkMultilabel;MitkDICOMReader;MitkDICOMReaderServices;MitkDicomRT") +mitkSwigPrepareFiles(pyMITK MITK.i "MitkCore;MitkCLCore;MitkCLUtilities;MitkBasicImageProcessing;ITKCommon;MitkMatchPointRegistration;MitkSegmentation;MitkMultilabel;MitkDICOMReader;MitkDICOMReaderServices;MitkDicomRT") # Add additional SWIG Parameters # These parameters depend on the target language set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_GLOBAL_FLAGS} -features autodoc=1 -keyword ) if( MITK_PYTHON_THREADS ) set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_FLAGS} -threads) endif() set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}) # Create the actual SWIG project swig_add_module(pyMITK python MITK.i ) -mitkSwigAddLibraryDependencies(pyMITK "MitkCore;MitkCLCore;MitkCLUtilities;ITKCommon;MitkMatchPointRegistration;MitkSegmentation;MitkMultilabel;MitkDICOMReader;MitkDICOMReaderServices;MitkDicomRT") +mitkSwigAddLibraryDependencies(pyMITK "MitkCore;MitkCLCore;MitkCLUtilities;MitkBasicImageProcessing;ITKCommon;MitkMatchPointRegistration;MitkSegmentation;MitkMultilabel;MitkDICOMReader;MitkDICOMReaderServices;MitkDicomRT") mitk_target_link_libraries_with_dynamic_lookup(${SWIG_MODULE_pyMITK_REAL_NAME} ${PYTHON_LIBRARIES}) if(DEFINED SKBUILD) message(WARNING "SKBuild exists") # Currently this installation install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pyMITK.py ${CMAKE_CURRENT_SOURCE_DIR}/Packaging/__init__.py # ${MITK_DOC_FILES} DESTINATION pyMITK COMPONENT Runtime ) install(TARGETS ${SWIG_MODULE_pyMITK_REAL_NAME} RUNTIME DESTINATION pyMITK LIBRARY DESTINATION pyMITK COMPONENT Runtime ) else() message(WARNING "SKBuild missing") include(LegacyPackaging.cmake) endif() diff --git a/Wrapping/Python/PackageUtility/Dockerfile-x86_64 b/Wrapping/Python/PackageUtility/Dockerfile-x86_64 index 79739e4515..bfcb58e978 100644 --- a/Wrapping/Python/PackageUtility/Dockerfile-x86_64 +++ b/Wrapping/Python/PackageUtility/Dockerfile-x86_64 @@ -1,36 +1,36 @@ FROM quay.io/pypa/manylinux1_x86_64 MAINTAINER Insight Software Consortium ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ -ADD https://cmake.org/files/v3.7/cmake-3.7.2.tar.gz \ +ADD https://cmake.org/files/v3.11/cmake-3.11.4.tar.gz \ https://www.openssl.org/source/openssl-1.0.2h.tar.gz \ /tmp/ ADD http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz \ https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ http://www.mpfr.org/mpfr-3.1.3/mpfr-3.1.3.tar.bz2 \ https://ftp.gnu.org/gnu/mpc/mpc-1.0.2.tar.gz \ http://bugseng.com/products/ppl/download/ftp/releases/1.1/ppl-1.1.tar.bz2 \ http://www.bastoul.net/cloog/pages/download/cloog-0.18.1.tar.gz \ http://ftp.gnu.org/gnu/gcc/gcc-4.9.4/gcc-4.9.4.tar.bz2 \ http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2 \ http://download.osgeo.org/libtiff/tiff-4.0.9.tar.gz \ /tmp/archives/ RUN yum -y install nano libXt-devel tcp_wrappers WORKDIR /tmp/ COPY ./imagefiles/install.sh ./ COPY ./imagefiles/install-gcc.sh ./ COPY ./imagefiles/install-libtiff.sh ./ RUN bash -v install-gcc.sh /usr/local && \ bash -v install-libtiff.sh && \ bash -v install.sh && \ rm -rf /tmp/* # User is expected to mount directory to "/work" ENTRYPOINT ["bash", "-c", "groupadd -o -g $_GROUPID $_USER && useradd -m -o -g $_GROUPID $_USER -u $_USERID && su $_USER /work/io/imagefiles/cmd.sh" ] diff --git a/Wrapping/Python/PackageUtility/HAFFeatureCalculation/calculate_3d_features.py b/Wrapping/Python/PackageUtility/HAFFeatureCalculation/calculate_3d_features.py new file mode 100644 index 0000000000..1296c8de71 --- /dev/null +++ b/Wrapping/Python/PackageUtility/HAFFeatureCalculation/calculate_3d_features.py @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jan 17 12:46:55 2019 + +@author: goetzm +""" +import pyMITK as mitk +import pandas as pd +import data_conversion as dc +import sys + +def print_status(status, add_whitespace=True): + sys.stdout.write('\r') + if add_whitespace: + sys.stdout.write(status+' ') + else: + sys.stdout.write(status) + sys.stdout.flush() + +def calculate_3d_features(initial_image, image, initial_mask, interpolated_mask, mask, + set_bins_normal, set_bins_onedistance, set_bins_ivh): + #return image, mask, image_resampled, mask_resampled + df = pd.DataFrame(columns=['Position','Name','Value']) + + ###### Pure Image Description Features + print_status('Diagnostic') + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(initial_image, initial_mask) + features1=dc.convert_features_into_dict(features_d) + next_idx = dc.add_image_description_features_to_df(df, features1, 0, name="Diagnostics-initial image") + + # No interpolation, thus using orignal image... + print_status('Image Description') + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(image, interpolated_mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_image_description_features_to_df(df, features, next_idx, name="Diagnostics-interpolated image") + #Mask Related Problems + next_idx = dc.add_mask_description_features_to_df(df, features1, next_idx, name="Diagnostics-initial ROI") + #Mask Related Problems + next_idx = dc.add_mask_description_features_to_df(df, features, next_idx, name="Diagnostics-interpolated ROI") + + ###### Cleaned Mask Description Features + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(image, mask) + features_2=dc.convert_features_into_dict(features_d) + next_idx = dc.add_mask_description_features_to_df(df, features_2, next_idx, name="Diagnostics-resegmented ROI", features_morph=features) + + ###### Calculate Volumetrics + print_status('Volumetrics') + calculator = mitk.GIFVolumetricStatistics_New() + features_d = calculator.CalculateFeatures(image, interpolated_mask) + features=dc.convert_features_into_dict(features_d) + calculator = mitk.GIFVolumetricStatistics_New() + features_d = calculator.CalculateFeatures(image, mask) + features2=dc.convert_features_into_dict(features_d) + next_idx = dc.add_volumetric_features_to_df(df, features, next_idx, features_intensity=features2) + + #calculator = mitk.GIFVolumetricDensityStatistics_New() + #calculator.SetMorphMask(interpolated_mask.GetPointer()) + #features_d = calculator.CalculateFeatures(image, mask) + #features=dc.convert_features_into_dict(features_d) + #next_idx = dc.add_volumetric_density_features_to_df(df, features, next_idx) + + ###### Calculate Local Intensities + print_status('Loci') + calculator = mitk.GIFLocalIntensity_New() + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_local_intensity_features_to_df(df, features, 91) + + ###### Calculate First Order Statistics + print_status('First order') + calculator = mitk.GIFFirstOrderNumericStatistics_New() + set_bins_onedistance(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_first_order_numeric_features_to_df(df, features, next_idx) + + ###### Calculate First Oder Histogram Statistics + print_status('First order Histogram') + calculator = mitk.GIFFirstOrderHistogramStatistics_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_intensity_histogram_features_to_df(df, features, next_idx) + + ###### Calculate intensity volume histogram + print_status('Intensity Volume') + calculator = mitk.GIFIntensityVolumeHistogramFeatures_New() + set_bins_ivh(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_intensity_volume_histogram_features_to_df(df, features, next_idx) + + ###### Calculate Co-occurence Matrix 3D + print_status('Cooc') + calculator = mitk.GIFCooccurenceMatrix2_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_cooccurence_3d_features_to_df(df, features, next_idx) + + ###### Calculate Run length matrix 3D + print_status('Run length') + calculator = mitk.GIFGreyLevelRunLength_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_runlength_3d_features_to_df(df, features, next_idx) + + ###### Calculate Size Zone 3D + print_status('Grey Level Size Zone') + calculator = mitk.GIFGreyLevelSizeZone_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_size_zone_3d_features_to_df(df, features, next_idx) + + ###### Calculate Distance Zone 3D + print_status('Distance Zone ') + calculator = mitk.GIFGreyLevelDistanceZone_New() + set_bins_normal(calculator) + calculator.SetMorphMask(interpolated_mask.GetPointer()) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_distance_zone_3d_features_to_df(df, features, next_idx) + + ###### Calculate Neighbourhood grey tone difference 3D + print_status('Grey tone difference') + calculator = mitk.GIFNeighbourhoodGreyToneDifferenceFeatures_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_neighbourhood_grey_tone_difference_3d_features_to_df(df, features, next_idx) + + ###### Calculate Neighbouring grey level dependence 3D + print_status('Grey Level Dependency') + calculator = mitk.GIFNeighbouringGreyLevelDependenceFeature_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_neighbouring_grey_level_dependence_3d_features_to_df(df, features, next_idx) + print_status("", False) + + return df + diff --git a/Wrapping/Python/PackageUtility/HAFFeatureCalculation/data_conversion.py b/Wrapping/Python/PackageUtility/HAFFeatureCalculation/data_conversion.py new file mode 100644 index 0000000000..2fe88e43a6 --- /dev/null +++ b/Wrapping/Python/PackageUtility/HAFFeatureCalculation/data_conversion.py @@ -0,0 +1,652 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 11 10:14:34 2019 + +@author: goetzm +""" +import math + +""" +Simple callable class. Will return an incremented number, starting with the given start_idx +""" +class IncrementalIndex: + def __init__(self, start_idx): + self.idx=start_idx-1 + def __call__(self): + self.idx = self.idx+1 + return self.idx + +""" +Converts a list of feature pairs (Feature name, Feature Value) into a dict +with Feature name as key and Feature Value as Value. Only the last feature will +be kept if more than one feature with the same name exists. +""" +def convert_features_into_dict(features_d): + features={} + for k in features_d: + features[k[0]]=k[1] + return features + + + +def add_volumetric_features_to_df(df, features, idx, features_intensity=None): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Morphology;Volume',features['Volumetric Features::Volume (mesh based)']] + else: + df.loc[df.index.max() + 1] = [idx,'Morphology;Volume',features['Volumetric Features::Volume (mesh based)']] + df.loc[df.index.max() + 1] = [idx+1,'Morphology;Approximate volume',features['Volumetric Features::Volume (voxel based)']] + df.loc[df.index.max() + 1] = [idx+2,'Morphology;Surface area',features['Volumetric Features::Surface (mesh based)']] + df.loc[df.index.max() + 1] = [idx+3,'Morphology;Surface to volume ratio',features['Volumetric Features::Surface to volume ratio (mesh based)']] + df.loc[df.index.max() + 1] = [idx+4,'Morphology;Compactness 1',features['Volumetric Features::Compactness 1 (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+5,'Morphology;Compactness 2',features['Volumetric Features::Compactness 2 (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+6,'Morphology;Spherical disproportion',features['Volumetric Features::Spherical disproportion (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+7,'Morphology;Sphericity',features['Volumetric Features::Sphericity (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+8,'Morphology;Asphericity',features['Volumetric Features::Asphericity (mesh, mesh based)']] + if features_intensity is None: + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Centre of mass shift',features['Volumetric Features::Centre of mass shift']] + else: + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Centre of mass shift',features_intensity['Volumetric Features::Centre of mass shift']] + df.loc[df.index.max() + 1] = [idx+10,'Morphology;Maximum 3D diameter',features['Volumetric Features::Maximum 3D diameter (mesh based)']] + df.loc[df.index.max() + 1] = [idx+11,'Morphology;Major axis length',features['Volumetric Features::PCA Major axis length']] + df.loc[df.index.max() + 1] = [idx+12,'Morphology;Minor axis length',features['Volumetric Features::PCA Minor axis length']] + df.loc[df.index.max() + 1] = [idx+13,'Morphology;Least axis length',features['Volumetric Features::PCA Least axis length']] + df.loc[df.index.max() + 1] = [idx+14,'Morphology;Elongation',features['Volumetric Features::PCA Elongation']] + df.loc[df.index.max() + 1] = [idx+15,'Morphology;Flatness',features['Volumetric Features::PCA Flatness']] + return idx+16 + +def add_volumetric_density_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Morphology;Volume density (AABB)',features['Morphological Density::Volume density axis-aligned bounding box']] + else: + df.loc[df.index.max() + 1] = [idx,'Morphology;Volume density (AABB)',features['Morphological Density::Volume density axis-aligned bounding box']] + df.loc[df.index.max() + 1] = [idx+1,'Morphology;Area density (AABB)',features['Morphological Density::Surface density axis-aligned bounding box']] + #df.loc[df.index.max() + 1] = [idx+2,'Morphology;Volume density (OMBB)',features['Morphological Density::Volume density oriented minimum bounding box']] + #df.loc[df.index.max() + 1] = [idx+3,'Morphology;Area density (OMBB)',features['Morphological Density::Surface density oriented minimum bounding box']] + df.loc[df.index.max() + 1] = [idx+2,'Morphology;Volume density (OMBB)',None] + df.loc[df.index.max() + 1] = [idx+3,'Morphology;Area density (OMBB)',None] + df.loc[df.index.max() + 1] = [idx+4,'Morphology;Volume density (AEE)',features['Morphological Density::Volume density approx. enclosing ellipsoid']] + df.loc[df.index.max() + 1] = [idx+5,'Morphology;Area density (AEE)',features['Morphological Density::Surface density approx. enclosing ellipsoid']] + #df.loc[df.index.max() + 1] = [idx+6,'Morphology;Volume density (MVEE)',features['Morphological Density::Volume density approx. minimum volume enclosing ellipsoid']] + #df.loc[df.index.max() + 1] = [idx+7,'Morphology;Area density (MVEE)',features['Morphological Density::Surface density approx. minimum volume enclosing ellipsoid']] + df.loc[df.index.max() + 1] = [idx+6,'Morphology;Volume density (MVEE)',None] + df.loc[df.index.max() + 1] = [idx+7,'Morphology;Area density (MVEE)',None] + df.loc[df.index.max() + 1] = [idx+8,'Morphology;Volume density (convex hull)',features['Morphological Density::Volume density convex hull']] + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Area density (convex hull)',features['Morphological Density::Surface density convex hull']] + df.loc[df.index.max() + 1] = [idx+10,'Morphology;Integrated intensity',features['Morphological Density::Volume integrated intensity']] + df.loc[df.index.max() + 1] = [idx+11,"digital phantom;Morphology;Moran's I index",features["Morphological Density::Volume Moran's I index"]] + df.loc[df.index.max() + 1] = [idx+12,"digital phantom;Morphology;Geary's C measure",features["Morphological Density::Volume Geary's C measure"]] + return idx+13 + +def add_local_intensity_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Local intensity;Local intensity peak',features['Local Intensity::2. Local Intensity Peak']] + else: + df.loc[df.index.max() + 1] = [idx,'Local intensity;Local intensity peak',features['Local Intensity::2. Local Intensity Peak']] + df.loc[df.index.max() + 1] = [idx+1,'Local intensity;Global intensity peak',features['Local Intensity::2. Global Intensity Peak']] + return idx+2 + +def add_first_order_numeric_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Statistics;Mean',features['First Order Numeric::Mean']] + else: + df.loc[df.index.max() + 1] = [idx,'Statistics;Mean',features['First Order Numeric::Mean']] + df.loc[df.index.max() + 1] = [idx+1,'Statistics;Variance',features['First Order Numeric::Variance']] + df.loc[df.index.max() + 1] = [idx+2,'Statistics;Skewness',features['First Order Numeric::Skewness']] + df.loc[df.index.max() + 1] = [idx+3,'Statistics;Kurtosis',features['First Order Numeric::Excess kurtosis']] + df.loc[df.index.max() + 1] = [idx+4,'Statistics;Median',features['First Order Numeric::Median']] + df.loc[df.index.max() + 1] = [idx+5,'Statistics;Minimum',features['First Order Numeric::Minimum']] + df.loc[df.index.max() + 1] = [idx+6,'Statistics;10th percentile',features['First Order Numeric::10th Percentile']] + df.loc[df.index.max() + 1] = [idx+7,'Statistics;90th percentile',features['First Order Numeric::90th Percentile']] + df.loc[df.index.max() + 1] = [idx+8,'Statistics;Maximum',features['First Order Numeric::Maximum']] + df.loc[df.index.max() + 1] = [idx+9,'Statistics;Interquartile range',features['First Order Numeric::Interquantile range']] + df.loc[df.index.max() + 1] = [idx+10,'Statistics;Range',features['First Order Numeric::Range']] + df.loc[df.index.max() + 1] = [idx+11,'Statistics;Mean absolute deviation',features['First Order Numeric::Mean absolute deviation']] + df.loc[df.index.max() + 1] = [idx+12,'Statistics;Robust mean absolute deviation',features['First Order Numeric::Robust mean absolute deviation']] + df.loc[df.index.max() + 1] = [idx+13,'Statistics;Median absolute deviation',features['First Order Numeric::Median absolute deviation']] + df.loc[df.index.max() + 1] = [idx+14,'Statistics;Coefficient of variation',features['First Order Numeric::Coefficient of variation']] + df.loc[df.index.max() + 1] = [idx+15,'Statistics;Quartile coefficient of dispersion',features['First Order Numeric::Quantile coefficient of dispersion']] + df.loc[df.index.max() + 1] = [idx+16,'Statistics;Energy',features['First Order Numeric::Energy']] + df.loc[df.index.max() + 1] = [idx+17,'Statistics;Root mean square',features['First Order Numeric::Root mean square']] + return idx+18 + +def add_intensity_histogram_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Intensity histogram;Mean',features['First Order Histogram::Mean Index']] + else: + df.loc[df.index.max() + 1] = [idx,'Intensity histogram;Mean',features['First Order Histogram::Mean Index']] + df.loc[df.index.max() + 1] = [idx+1,'Intensity histogram;Variance',features['First Order Histogram::Variance Index']] + df.loc[df.index.max() + 1] = [idx+2,'Intensity histogram;Skewness',features['First Order Histogram::Skewness Index']] + df.loc[df.index.max() + 1] = [idx+3,'Intensity histogram;Kurtosis',features['First Order Histogram::Excess Kurtosis Index']] + df.loc[df.index.max() + 1] = [idx+4,'Intensity histogram;Median',features['First Order Histogram::Median Index']] + df.loc[df.index.max() + 1] = [idx+5,'Intensity histogram;Minimum',features['First Order Histogram::Minimum Index']] + df.loc[df.index.max() + 1] = [idx+6,'Intensity histogram;10th percentile',features['First Order Histogram::Percentile 10 Index']] + df.loc[df.index.max() + 1] = [idx+7,'Intensity histogram;90th percentile',features['First Order Histogram::Percentile 90 Index']] + df.loc[df.index.max() + 1] = [idx+8,'Intensity histogram;Maximum',features['First Order Histogram::Maximum Index']] + df.loc[df.index.max() + 1] = [idx+9,'Intensity histogram;Mode',features['First Order Histogram::Mode Index']] + df.loc[df.index.max() + 1] = [idx+10,'Intensity histogram;Interquartile range',features['First Order Histogram::Interquantile Range Index']] + df.loc[df.index.max() + 1] = [idx+11,'Intensity histogram;Range',features['First Order Histogram::Range Index']] + df.loc[df.index.max() + 1] = [idx+12,'Intensity histogram;Mean absolute deviation',features['First Order Histogram::Mean Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+13,'Intensity histogram;Robust mean absolute deviation',features['First Order Histogram::Robust Mean Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+14,'Intensity histogram;Median absolute deviation',features['First Order Histogram::Median Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+15,'Intensity histogram;Coefficient of variation',features['First Order Histogram::Coefficient of Variation Index']] + df.loc[df.index.max() + 1] = [idx+16,'Intensity histogram;Quartile coefficient of dispersion',features['First Order Histogram::Quantile coefficient of Dispersion Index']] + df.loc[df.index.max() + 1] = [idx+17,'Intensity histogram;Entropy',features['First Order Histogram::Entropy Index']] + df.loc[df.index.max() + 1] = [idx+18,'Intensity histogram;Uniformity',features['First Order Histogram::Uniformity Index']] + df.loc[df.index.max() + 1] = [idx+19,'Intensity histogram;Maximum histogram gradient',features['First Order Histogram::Maximum Gradient']] + df.loc[df.index.max() + 1] = [idx+20,'Intensity histogram;Maximum gradient grey level',features['First Order Histogram::Maximum Gradient Index']] + df.loc[df.index.max() + 1] = [idx+21,'Intensity histogram;Minimum histogram gradient',features['First Order Histogram::Minimum Gradient']] + df.loc[df.index.max() + 1] = [idx+22,'Intensity histogram;Minimum gradient grey level',features['First Order Histogram::Minimum Gradient Index']] + return idx+23 + +def add_intensity_volume_histogram_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Intensity volume histogram;Volume fraction at 10% intensity',features['Intensity Volume Histogram::Volume fraction at 0.10 intensity']] + else: + df.loc[df.index.max() + 1] = [idx,'Intensity volume histogram;Volume fraction at 10% intensity',features['Intensity Volume Histogram::Volume fraction at 0.10 intensity']] + df.loc[df.index.max() + 1] = [idx+1,'Intensity volume histogram;Volume fraction at 90% intensity',features['Intensity Volume Histogram::Volume fraction at 0.90 intensity']] + df.loc[df.index.max() + 1] = [idx+2,'Intensity volume histogram;Intensity at 10% volume',features['Intensity Volume Histogram::Intensity at 0.10 volume']] + df.loc[df.index.max() + 1] = [idx+3,'Intensity volume histogram;Intensity at 90% volume',features['Intensity Volume Histogram::Intensity at 0.90 volume']] + df.loc[df.index.max() + 1] = [idx+4,'Intensity volume histogram;Volume fraction difference between 10% and 90% intensity',features['Intensity Volume Histogram::Difference volume fraction at 0.10 and 0.90 intensity']] + df.loc[df.index.max() + 1] = [idx+5,'Intensity volume histogram;Intensity difference between 10% and 90% volume',features['Intensity Volume Histogram::Difference intensity at 0.10 and 0.90 volume']] + df.loc[df.index.max() + 1] = [idx+6,'Intensity volume histogram;Area under the IVH curve',features['Intensity Volume Histogram::Area under IVH curve']] + return idx+7 + +def add_cooccurence_2d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (2D, averaged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (2D, averaged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (2D, averaged);Joint average',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (2D, averaged);Joint variance',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (2D, averaged);Joint entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (2D, averaged);Difference average',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (2D, averaged);Difference variance',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (2D, averaged);Difference entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (2D, averaged);Sum average',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (2D, averaged);Sum variance',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (2D, averaged);Sum entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (2D, averaged);Angular second moment',features['SliceWise Mean Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (2D, averaged);Contrast',features['SliceWise Mean Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (2D, averaged);Dissimilarity',features['SliceWise Mean Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (2D, averaged);Inverse difference',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (2D, averaged);Inverse difference normalised',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (2D, averaged);Inverse difference moment',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (2D, averaged);Inverse difference moment normalised',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (2D, averaged);Inverse variance',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (2D, averaged);Correlation',features['SliceWise Mean Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (2D, averaged);Autocorrelation',features['SliceWise Mean Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (2D, averaged);Cluster tendency',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (2D, averaged);Cluster shade',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (2D, averaged);Cluster prominence',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (2D, averaged);Information correlation 1',features['SliceWise Mean Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (2D, averaged);Information correlation 2',features['SliceWise Mean Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (2D, slice-merged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (2D, slice-merged);Joint average',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (2D, slice-merged);Joint variance',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (2D, slice-merged);Joint entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (2D, slice-merged);Difference average',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (2D, slice-merged);Difference variance',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (2D, slice-merged);Difference entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (2D, slice-merged);Sum average',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (2D, slice-merged);Sum variance',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (2D, slice-merged);Sum entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (2D, slice-merged);Angular second moment',features['SliceWise Mean Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (2D, slice-merged);Contrast',features['SliceWise Mean Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (2D, slice-merged);Dissimilarity',features['SliceWise Mean Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (2D, slice-merged);Inverse difference',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (2D, slice-merged);Inverse difference normalised',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (2D, slice-merged);Inverse difference moment',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (2D, slice-merged);Inverse difference moment normalised',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (2D, slice-merged);Inverse variance',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (2D, slice-merged);Correlation',features['SliceWise Mean Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (2D, slice-merged);Autocorrelation',features['SliceWise Mean Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (2D, slice-merged);Cluster tendency',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (2D, slice-merged);Cluster shade',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (2D, slice-merged);Cluster prominence',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (2D, slice-merged);Information correlation 1',features['SliceWise Mean Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (2D, slice-merged);Information correlation 2',features['SliceWise Mean Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + + +def add_cooccurence_2_5d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (2.5D, direction-merged);Joint average',features['Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (2.5D, direction-merged);Joint variance',features['Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (2.5D, direction-merged);Joint entropy',features['Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (2.5D, direction-merged);Difference average',features['Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (2.5D, direction-merged);Difference variance',features['Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (2.5D, direction-merged);Difference entropy',features['Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (2.5D, direction-merged);Sum average',features['Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (2.5D, direction-merged);Sum variance',features['Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (2.5D, direction-merged);Sum entropy',features['Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (2.5D, direction-merged);Angular second moment',features['Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (2.5D, direction-merged);Contrast',features['Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (2.5D, direction-merged);Dissimilarity',features['Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference',features['Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference normalised',features['Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment',features['Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (2.5D, direction-merged);Inverse variance',features['Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (2.5D, direction-merged);Correlation',features['Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (2.5D, direction-merged);Autocorrelation',features['Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (2.5D, direction-merged);Cluster tendency',features['Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (2.5D, direction-merged);Cluster shade',features['Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (2.5D, direction-merged);Cluster prominence',features['Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 1',features['Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 2',features['Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (2.5D, direction-merged);Joint average',features['Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (2.5D, direction-merged);Joint variance',features['Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (2.5D, direction-merged);Joint entropy',features['Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (2.5D, direction-merged);Difference average',features['Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (2.5D, direction-merged);Difference variance',features['Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (2.5D, direction-merged);Difference entropy',features['Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (2.5D, direction-merged);Sum average',features['Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (2.5D, direction-merged);Sum variance',features['Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (2.5D, direction-merged);Sum entropy',features['Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (2.5D, direction-merged);Angular second moment',features['Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (2.5D, direction-merged);Contrast',features['Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (2.5D, direction-merged);Dissimilarity',features['Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference',features['Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference normalised',features['Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment',features['Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (2.5D, direction-merged);Inverse variance',features['Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (2.5D, direction-merged);Correlation',features['Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (2.5D, direction-merged);Autocorrelation',features['Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (2.5D, direction-merged);Cluster tendency',features['Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (2.5D, direction-merged);Cluster shade',features['Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (2.5D, direction-merged);Cluster prominence',features['Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 1',features['Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 2',features['Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + +def add_cooccurence_3d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (3D, averaged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (3D, averaged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (3D, averaged);Joint average',features['Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (3D, averaged);Joint variance',features['Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (3D, averaged);Joint entropy',features['Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (3D, averaged);Difference average',features['Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (3D, averaged);Difference variance',features['Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (3D, averaged);Difference entropy',features['Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (3D, averaged);Sum average',features['Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (3D, averaged);Sum variance',features['Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (3D, averaged);Sum entropy',features['Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (3D, averaged);Angular second moment',features['Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (3D, averaged);Contrast',features['Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (3D, averaged);Dissimilarity',features['Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (3D, averaged);Inverse difference',features['Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (3D, averaged);Inverse difference normalised',features['Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (3D, averaged);Inverse difference moment',features['Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (3D, averaged);Inverse difference moment normalised',features['Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (3D, averaged);Inverse variance',features['Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (3D, averaged);Correlation',features['Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (3D, averaged);Autocorrelation',features['Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (3D, averaged);Cluster tendency',features['Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (3D, averaged);Cluster shade',features['Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (3D, averaged);Cluster prominence',features['Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (3D, averaged);Information correlation 1',features['Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (3D, averaged);Information correlation 2',features['Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (3D, merged);Joint maximum',features['Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (3D, merged);Joint average',features['Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (3D, merged);Joint variance',features['Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (3D, merged);Joint entropy',features['Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (3D, merged);Difference average',features['Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (3D, merged);Difference variance',features['Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (3D, merged);Difference entropy',features['Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (3D, merged);Sum average',features['Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (3D, merged);Sum variance',features['Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (3D, merged);Sum entropy',features['Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (3D, merged);Angular second moment',features['Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (3D, merged);Contrast',features['Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (3D, merged);Dissimilarity',features['Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (3D, merged);Inverse difference',features['Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (3D, merged);Inverse difference normalised',features['Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (3D, merged);Inverse difference moment',features['Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (3D, merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (3D, merged);Inverse variance',features['Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (3D, merged);Correlation',features['Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (3D, merged);Autocorrelation',features['Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (3D, merged);Cluster tendency',features['Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (3D, merged);Cluster shade',features['Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (3D, merged);Cluster prominence',features['Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (3D, merged);Information correlation 1',features['Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (3D, merged);Information correlation 2',features['Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + +def add_runlength_2d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (2D, averaged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (2D, averaged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (2D, averaged);Long runs emphasis',features['SliceWise Mean Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (2D, averaged);Low grey level run emphasis',features['SliceWise Mean Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (2D, averaged);High grey level run emphasis',features['SliceWise Mean Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (2D, averaged);Short run low grey level emphasis',features['SliceWise Mean Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (2D, averaged);Short run high grey level emphasis',features['SliceWise Mean Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (2D, averaged);Long run low grey level emphasis',features['SliceWise Mean Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (2D, averaged);Long run high grey level emphasis',features['SliceWise Mean Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (2D, averaged);Grey level non-uniformity',features['SliceWise Mean Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (2D, averaged);Grey level non-uniformity normalised',features['SliceWise Mean Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (2D, averaged);Run length non-uniformity',features['SliceWise Mean Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (2D, averaged);Run length non-uniformity normalised',features['SliceWise Mean Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (2D, averaged);Run percentage',features['SliceWise Mean Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (2D, averaged);Grey level variance',features['SliceWise Mean Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (2D, averaged);Run length variance',features['SliceWise Mean Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (2D, averaged);Run entropy',features['SliceWise Mean Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (2D, slice-merged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (2D, slice-merged);Long runs emphasis',features['SliceWise Mean Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (2D, slice-merged);Low grey level run emphasis',features['SliceWise Mean Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (2D, slice-merged);High grey level run emphasis',features['SliceWise Mean Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (2D, slice-merged);Short run low grey level emphasis',features['SliceWise Mean Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (2D, slice-merged);Short run high grey level emphasis',features['SliceWise Mean Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (2D, slice-merged);Long run low grey level emphasis',features['SliceWise Mean Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (2D, slice-merged);Long run high grey level emphasis',features['SliceWise Mean Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (2D, slice-merged);Grey level non-uniformity',features['SliceWise Mean Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (2D, slice-merged);Grey level non-uniformity normalised',features['SliceWise Mean Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (2D, slice-merged);Run length non-uniformity',features['SliceWise Mean Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (2D, slice-merged);Run length non-uniformity normalised',features['SliceWise Mean Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (2D, slice-merged);Run percentage',features['SliceWise Mean Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (2D, slice-merged);Grey level variance',features['SliceWise Mean Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (2D, slice-merged);Run length variance',features['SliceWise Mean Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (2D, slice-merged);Run entropy',features['SliceWise Mean Run Length::Run length entropy Comb.']] + return idx+32 + +def add_runlength_2_5d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (2.5D, direction-merged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (2.5D, direction-merged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (2.5D, direction-merged);Long runs emphasis',features['Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (2.5D, direction-merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (2.5D, direction-merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (2.5D, direction-merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (2.5D, direction-merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (2.5D, direction-merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (2.5D, direction-merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (2.5D, direction-merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (2.5D, direction-merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (2.5D, direction-merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (2.5D, direction-merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (2.5D, direction-merged);Run percentage',features['Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (2.5D, direction-merged);Grey level variance',features['Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (2.5D, direction-merged);Run length variance',features['Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (2.5D, direction-merged);Run entropy',features['Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (2.5D, merged);Short runs emphasis',features['Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (2.5D, merged);Long runs emphasis',features['Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (2.5D, merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (2.5D, merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (2.5D, merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (2.5D, merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (2.5D, merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (2.5D, merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (2.5D, merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (2.5D, merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (2.5D, merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (2.5D, merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (2.5D, merged);Run percentage',features['Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (2.5D, merged);Grey level variance',features['Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (2.5D, merged);Run length variance',features['Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (2.5D, merged);Run entropy',features['Run Length::Run length entropy Comb.']] + return idx+32 + +def add_runlength_3d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (3D, averaged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (3D, averaged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (3D, averaged);Long runs emphasis',features['Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (3D, averaged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (3D, averaged);High grey level run emphasis',features['Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (3D, averaged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (3D, averaged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (3D, averaged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (3D, averaged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (3D, averaged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (3D, averaged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (3D, averaged);Run length non-uniformity',features['Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (3D, averaged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (3D, averaged);Run percentage',features['Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (3D, averaged);Grey level variance',features['Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (3D, averaged);Run length variance',features['Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (3D, averaged);Run entropy',features['Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (3D, merged);Short runs emphasis',features['Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (3D, merged);Long runs emphasis',features['Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (3D, merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (3D, merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (3D, merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (3D, merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (3D, merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (3D, merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (3D, merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (3D, merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (3D, merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (3D, merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (3D, merged);Run percentage',features['Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (3D, merged);Grey level variance',features['Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (3D, merged);Run length variance',features['Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (3D, merged);Run entropy',features['Run Length::Run length entropy Comb.']] + return idx+32 + +def add_size_zone_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Size zone matrix (2D);Small zone emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);High grey level emphasis',features['SliceWise Mean Grey Level Size Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone high grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone high grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level non-uniformity',features['SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level non uniformity normalised',features['SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size non-uniformity',features['SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size non-uniformity normalised',features['SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone percentage',features['SliceWise Mean Grey Level Size Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level variance',features['SliceWise Mean Grey Level Size Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size variance',features['SliceWise Mean Grey Level Size Zone::Zone Size Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size entropy',features['SliceWise Mean Grey Level Size Zone::Zone Size Entropy']] + return cidx() + +def add_size_zone_3d_features_to_df(df, features, idx, feature_name="Distance zone matrix (2D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Small zone emphasis',features['Grey Level Size Zone::Small Zone Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone emphasis',features['Grey Level Size Zone::Small Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone emphasis',features['Grey Level Size Zone::Large Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level emphasis',features['Grey Level Size Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level emphasis',features['Grey Level Size Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone low grey level emphasis',features['Grey Level Size Zone::Small Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone high grey level emphasis',features['Grey Level Size Zone::Small Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone low grey level emphasis',features['Grey Level Size Zone::Large Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone high grey level emphasis',features['Grey Level Size Zone::Large Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Grey Level Size Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non uniformity normalised',features['Grey Level Size Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size non-uniformity',features['Grey Level Size Zone::Zone Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size non-uniformity normalised',features['Grey Level Size Zone::Zone Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone percentage',features['Grey Level Size Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Grey Level Size Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size variance',features['Grey Level Size Zone::Zone Size Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size entropy',features['Grey Level Size Zone::Zone Size Entropy']] + return cidx() + +def add_distance_zone_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Distance zone matrix (2D);Small distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);High grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance high grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance high grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level non-uniformity',features['SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level non-uniformity normalised',features['SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance non-uniformity',features['SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance non-uniformity normalised',features['SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone percentage',features['SliceWise Mean Grey Level Distance Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level variance',features['SliceWise Mean Grey Level Distance Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance variance',features['SliceWise Mean Grey Level Distance Zone::Zone Distance Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance entropy',features['SliceWise Mean Grey Level Distance Zone::Zone Distance Entropy']] + return cidx() + +def add_distance_zone_3d_features_to_df(df, features, idx, feature_name="Distance zone matrix (3D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Small distance emphasis',features['Grey Level Distance Zone::Small Distance Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance emphasis',features['Grey Level Distance Zone::Small Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance emphasis',features['Grey Level Distance Zone::Large Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level emphasis',features['Grey Level Distance Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level emphasis',features['Grey Level Distance Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance low grey level emphasis',features['Grey Level Distance Zone::Small Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance high grey level emphasis',features['Grey Level Distance Zone::Small Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance low grey level emphasis',features['Grey Level Distance Zone::Large Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance high grey level emphasis',features['Grey Level Distance Zone::Large Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Grey Level Distance Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity normalised',features['Grey Level Distance Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance non-uniformity',features['Grey Level Distance Zone::Distance Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance non-uniformity normalised',features['Grey Level Distance Zone::Distance Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone percentage',features['Grey Level Distance Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Grey Level Distance Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance variance',features['Grey Level Distance Zone::Zone Distance Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance entropy',features['Grey Level Distance Zone::Zone Distance Entropy']] + return cidx() + +def add_neighbourhood_grey_tone_difference_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Coarseness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Coarsness']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Coarseness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Coarsness']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Contrast',features['SliceWise Mean Neighbourhood Grey Tone Difference::Contrast']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Busyness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Busyness']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Complexity',features['SliceWise Mean Neighbourhood Grey Tone Difference::Complexity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Strength',features['SliceWise Mean Neighbourhood Grey Tone Difference::Strength']] + return cidx() + +def add_neighbourhood_grey_tone_difference_3d_features_to_df(df, features, idx, feature_name="Neighbourhood grey tone difference matrix (3D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Coarseness',features['Neighbourhood Grey Tone Difference::Coarsness']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Coarseness',features['Neighbourhood Grey Tone Difference::Coarsness']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Contrast',features['Neighbourhood Grey Tone Difference::Contrast']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Busyness',features['Neighbourhood Grey Tone Difference::Busyness']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Complexity',features['Neighbourhood Grey Tone Difference::Complexity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Strength',features['Neighbourhood Grey Tone Difference::Strength']] + return cidx() + +def add_neighbouring_grey_level_dependence_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low grey level count emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High grey level count emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence low grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence high grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence low grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence high grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level non-uniformity',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level non-uniformity normalised',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count non-uniformity',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count non-uniformity normalised',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count percentage',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level variance',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count variance',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count entropy',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Entropy']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count energy',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Energy']] + return cidx() + +def add_neighbouring_grey_level_dependence_3d_features_to_df(df, features, idx, feature_name='Neighbouring grey level dependence matrix (3D)'): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Low dependence emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence emphasis',features['Neighbouring Grey Level Dependence::High Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level count emphasis',features['Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level count emphasis',features['Neighbouring Grey Level Dependence::High Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence low grey level emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence high grey level emphasis',features['Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence low grey level emphasis',features['Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence high grey level emphasis',features['Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Neighbouring Grey Level Dependence::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity normalised',features['Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count non-uniformity',features['Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count non-uniformity normalised',features['Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count percentage',features['Neighbouring Grey Level Dependence::Dependence Count Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Neighbouring Grey Level Dependence::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count variance',features['Neighbouring Grey Level Dependence::Dependence Count Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count entropy',features['Neighbouring Grey Level Dependence::Dependence Count Entropy']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count energy',features['Neighbouring Grey Level Dependence::Dependence Count Energy']] + return cidx() + + + +def add_image_description_features_to_df(df, features, idx, name="Diagnostics"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),name+';Image dimension x',features['Diagnostic::Image Dimension X']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension x',features['Diagnostic::Image Dimension X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension y',features['Diagnostic::Image Dimension Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension z',features['Diagnostic::Image Dimension Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension x',features['Diagnostic::Image Spacing X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension y',features['Diagnostic::Image Spacing Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension z',features['Diagnostic::Image Spacing Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Mean intensity',features['Diagnostic::Image Mean intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Minimum intensity',features['Diagnostic::Image Minimum intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Maximum intensity',features['Diagnostic::Image Maximum intensity']] + return cidx() + +def add_mask_description_features_to_df(df, features, idx, name="Diagnostics", features_morph=None): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),name+';Int. mask dimension x',features['Diagnostic::Mask Dimension X']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension x',features['Diagnostic::Mask Dimension X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension y',features['Diagnostic::Mask Dimension Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension z',features['Diagnostic::Mask Dimension Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension x',features['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension y',features['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension z',features['Diagnostic::Mask bounding box Z']] + if features_morph is None: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension x',features['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension y',features['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension z',features['Diagnostic::Mask bounding box Z']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension x',features_morph['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension y',features_morph['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension z',features_morph['Diagnostic::Mask bounding box Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask voxel count',features['Diagnostic::Mask Voxel Count']] + if features_morph is None: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask voxel count',features['Diagnostic::Mask Voxel Count']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask voxel count',features_morph['Diagnostic::Mask Voxel Count']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask mean intensity',features['Diagnostic::Mask Mean intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask minimum intensity',features['Diagnostic::Mask Minimum intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask maximum intensity',features['Diagnostic::Mask Maximum intensity']] + return cidx() diff --git a/Wrapping/Python/PackageUtility/HAFFeatureCalculation/folderProcessing.py b/Wrapping/Python/PackageUtility/HAFFeatureCalculation/folderProcessing.py new file mode 100644 index 0000000000..c8da79e69c --- /dev/null +++ b/Wrapping/Python/PackageUtility/HAFFeatureCalculation/folderProcessing.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jan 9 10:30:20 2019 +@author: goetzm +""" + +import os +import pyMITK as mitk +import calculate_3d_features as c3df +import glob +import pandas as pd +import math + + +base_path=r"E:\Projects\HAF\demodata\radiomics_for_dkfz" + +def set_bins_normal(calculator): + calculator.SetBins(32) + calculator.SetUseBins(True) + +def set_bins_onedistance(calculator): + calculator.SetBinsize(1) + calculator.SetUseBinsize(True) + calculator.SetCorrectForBinsize(True) + +if True: + for t1_image_path in glob.iglob(os.path.join(base_path,"**","*T1w.nii.gz"), recursive=True): + print(t1_image_path) + image_dir = os.path.dirname(t1_image_path) + + list_t1_images = mitk.IOUtil.Load(t1_image_path) + t1_image = list_t1_images[0].ConvertToImage() + # Segments: + atlas_image_path = glob.glob(os.path.join(image_dir, "*Schaefer2018_100*.nii.gz"))[0] + list_atlas_images = mitk.IOUtil.Load(atlas_image_path) + atlas_image = list_atlas_images[0].ConvertToImage() + list_atlas_images2 = mitk.IOUtil.Load(atlas_image_path) + atlas_image1 = list_atlas_images2[0].ConvertToImage() + + atlas_mask_image=mitk.ArithmeticOperation.Divide(atlas_image, atlas_image1) + + list_of_dfs=[] + for i in range(100): + print("Working on Atlas ID",i+1) + current_mask=mitk.MaskCleaningOperation.RangeBasedMasking(atlas_image, atlas_mask_image, True, i+0.5, True, i+1.5) + cdf=c3df.calculate_3d_features(t1_image, t1_image, + current_mask, current_mask, current_mask, + set_bins_normal, set_bins_onedistance, set_bins_onedistance) + list_of_dfs.append(cdf) + + if True: + col_names=cdf['Name'].values.tolist() + col_names.append('SegmentID') + final_df=pd.DataFrame(columns=col_names) + for cdf,i in zip(list_of_dfs,range(100)): + cvalues=cdf['Value'].values.tolist() + cvalues.append(i+1) + if math.isnan(final_df.index.max()): + final_df.loc[0] = cvalues + else: + final_df.loc[final_df.index.max() + 1] = cvalues + final_df.to_csv(os.path.join(image_dir, "radiomics_values.csv"),sep=";") diff --git a/Wrapping/Python/PackageUtility/Dockerfile-Python b/Wrapping/Python/PackageUtility/PythonWheelDocker/Dockerfile-Python similarity index 100% rename from Wrapping/Python/PackageUtility/Dockerfile-Python rename to Wrapping/Python/PackageUtility/PythonWheelDocker/Dockerfile-Python diff --git a/Wrapping/Python/PackageUtility/PythonWheelDocker/Dockerfile-x86_64 b/Wrapping/Python/PackageUtility/PythonWheelDocker/Dockerfile-x86_64 new file mode 100644 index 0000000000..dfc52a68b8 --- /dev/null +++ b/Wrapping/Python/PackageUtility/PythonWheelDocker/Dockerfile-x86_64 @@ -0,0 +1,63 @@ +FROM quay.io/pypa/manylinux1_x86_64 +MAINTAINER Insight Software Consortium + +#ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV http_proxy http://www-int2.dkfz-heidelberg.de:80/ +#ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:80/ + +ENV QT_VERSION_A=5.11 +ENV QT_VERSION_B=5.11.2 + +ENV CMAKE_VERSION_A=3.11 +ENV CMAKE_VERSION_B=3.11.4 + +ADD https://cmake.org/files/v${CMAKE_VERSION_A}/cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh \ + https://www.openssl.org/source/openssl-1.0.2h.tar.gz \ + /tmp/ + +ADD http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz \ + https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ + http://www.mpfr.org/mpfr-3.1.3/mpfr-3.1.3.tar.bz2 \ + https://ftp.gnu.org/gnu/mpc/mpc-1.0.2.tar.gz \ + http://bugseng.com/products/ppl/download/ftp/releases/1.1/ppl-1.1.tar.bz2 \ + http://www.bastoul.net/cloog/pages/download/cloog-0.18.1.tar.gz \ + http://ftp.gnu.org/gnu/gcc/gcc-4.9.4/gcc-4.9.4.tar.bz2 \ + http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2 \ + http://download.osgeo.org/libtiff/tiff-4.0.9.tar.gz \ + /tmp/archives/ + +RUN yum -y install nano libXt-devel tcp_wrappers + +########################################################## Install CMAKE #################################################### +RUN cd /tmp \ + && mkdir /opt/cmake \ + && chmod +x cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh \ + && sh ./cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh --prefix=/opt/cmake --skip-license \ + && ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake \ + && cmake --version + +WORKDIR /tmp/ + +########################################################## Install GCC ###################################################### +########################################################## Install libTiff ################################################## +########################################################## Install OpenSSL ################################################## +COPY ./imagefiles/install-openssl.sh ./ +COPY ./imagefiles/install-gcc.sh ./ +COPY ./imagefiles/install-libtiff.sh ./ + +RUN bash -v install-gcc.sh /usr/local && \ + bash -v install-libtiff.sh && \ + bash -v install.sh && \ + rm -rf /tmp/* + +########################################################## Install QT ####################################################### +COPY imagefiles/qt-noninteractive.qs /opt/qt-noninteractive.qs +RUN wget https://download.qt.io/archive/qt/${QT_VERSION_A}/${QT_VERSION_B}/qt-opensource-linux-x64-${QT_VERSION_B}.run \ + && chmod +x qt-opensource-linux-x64-${QT_VERSION_B}.run \ + && ./qt-opensource-linux-x64-${QT_VERSION_B}.run --script /opt/qt-noninteractive.qs -platform minimal --proxy --verbose \ + && rm qt-opensource-linux-x64-${QT_VERSION_B}.run + +# User is expected to mount directory to "/work" +ENTRYPOINT ["bash", "-c", "groupadd -o -g $_GROUPID $_USER && useradd -m -o -g $_GROUPID $_USER -u $_USERID && su $_USER /work/io/imagefiles/cmd.sh" ] + diff --git a/Wrapping/Python/PackageUtility/Dockerfile-x86_64_2 b/Wrapping/Python/PackageUtility/PythonWheelDocker/Dockerfile-x86_64_2 similarity index 100% rename from Wrapping/Python/PackageUtility/Dockerfile-x86_64_2 rename to Wrapping/Python/PackageUtility/PythonWheelDocker/Dockerfile-x86_64_2 diff --git a/Wrapping/Python/PackageUtility/PythonWheelDocker/df2 b/Wrapping/Python/PackageUtility/PythonWheelDocker/df2 new file mode 100644 index 0000000000..2f1d4ca716 --- /dev/null +++ b/Wrapping/Python/PackageUtility/PythonWheelDocker/df2 @@ -0,0 +1,14 @@ +FROM quay.io/pypa/manylinux1_x86_64 +MAINTAINER Insight Software Consortium + +#ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV http_proxy http://www-int2.dkfz-heidelberg.de:80/ +#ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:80/ + +ENV QT_VERSION_A=5.11 +ENV QT_VERSION_B=5.11.2 + +ENV CMAKE_VERSION_A=3.11 +ENV CMAKE_VERSION_B=3.11.4 + diff --git a/Wrapping/Python/PackageUtility/imagefiles/cmd.sh b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/cmd.sh similarity index 82% rename from Wrapping/Python/PackageUtility/imagefiles/cmd.sh rename to Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/cmd.sh index d876ad6cfc..9c7ea56121 100755 --- a/Wrapping/Python/PackageUtility/imagefiles/cmd.sh +++ b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/cmd.sh @@ -1,66 +1,70 @@ #!/bin/sh set -x export SRC_DIR="/tmp/mitk" export BLD_DIR="/tmp/bin" export OUT_DIR="/var/io" -MITK_GIT_TAG=T24046-SwigBasedPythonWrapping +MITK_GIT_TAG=T25826-RadiomicsGUIUpdate PYTHON_VERSIONS=${PYTHON_VERSIONS:-$(ls /opt/python | sed -e 's/cp2[0-6][^ ]\+ \?//g')} NPROC=$(grep -c processor /proc/cpuinfo) export MAKEFLAGS="-j ${NPROC}" function build_mitk { echo "MITK_GIT_TAG: ${MITK_GIT_TAG}" git clone https://phabricator.mitk.org/source/mitk.git ${SRC_DIR} && (cd ${SRC_DIR} && git checkout ${MITK_GIT_TAG} ) && rm -rf ${BLD_DIR} && mkdir -p ${BLD_DIR} && cd ${BLD_DIR} && cmake \ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DQt5_DIR:PATH=/qt/${QT_VERSION_B}/gcc_64/lib/cmake/Qt5/ \ + -DMITK_USE_HDF5:BOOL=ON \ -DBUILD_TESTING:BOOL=OFF \ -DMITK_USE_SWIG:BOOL=ON \ - -DMITK_USE_Qt5:BOOL=OFF \ - -DMITK_USE_CTK:BOOL=OFF \ - -DMITK_USE_BLUEBERRY:BOOL=OFF \ + -DMITK_USE_MatchPoint=ON\ + -DMITK_USE_Vigra=ON\ + -DMITK_USE_Qt5:BOOL=ON \ + -DMITK_USE_CTK:BOOL=ON \ + -DMITK_USE_BLUEBERRY:BOOL=ON \ -DCMAKE_C_COMPILER:FILEPATH=/usr/local/bin/gcc \ -DCMAKE_CXX_COMPILER:FILEPATH=/usr/local/bin/g++ \ - -DMITK_WHITELIST:STRING=Wrapping \ -DCMAKE_BUILD_TYPE:STRING=Release \ ${SRC_DIR} && make -j8 } function build_mitk_python { PYTHON_EXECUTABLE=/opt/python/${PYTHON}/bin/python PYTHON_INCLUDE_DIR="$( find -L /opt/python/${PYTHON}/include/ -name Python.h -exec dirname {} \; )" echo "" echo "PYTHON_EXECUTABLE:${PYTHON_EXECUTABLE}" echo "PYTHON_INCLUDE_DIR:${PYTHON_INCLUDE_DIR}" echo "PYTHON_LIBRARY:${PYTHON_LIBRARY}" cd ${BLD_DIR}/MITK-build && cmake \ -DWRAP_PYTHON:BOOL=ON \ -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} \ -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} \ . make dist -B } build_mitk || exit 1 for PYTHON in ${PYTHON_VERSIONS}; do build_mitk_python && auditwheel repair $(find ${BLD_DIR}/MITK-build/Wrapping/Python/dist -name pyMITK*.whl) -w ${OUT_DIR}/wheelhouse/ rm $(find ${BLD_DIR}/MITK-build/Wrapping/Python/dist/ -name pyMITK*.whl) done diff --git a/Wrapping/Python/PackageUtility/imagefiles/imagefiles/install-gcc.sh b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install-gcc.sh similarity index 100% rename from Wrapping/Python/PackageUtility/imagefiles/imagefiles/install-gcc.sh rename to Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install-gcc.sh diff --git a/Wrapping/Python/PackageUtility/imagefiles/imagefiles/install-libtiff.sh b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install-libtiff.sh similarity index 100% rename from Wrapping/Python/PackageUtility/imagefiles/imagefiles/install-libtiff.sh rename to Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install-libtiff.sh diff --git a/Wrapping/Python/PackageUtility/imagefiles/imagefiles/install.sh b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install-openssl.sh old mode 100755 new mode 100644 similarity index 85% rename from Wrapping/Python/PackageUtility/imagefiles/imagefiles/install.sh rename to Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install-openssl.sh index f01d53b9db..1fc16e7152 --- a/Wrapping/Python/PackageUtility/imagefiles/imagefiles/install.sh +++ b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install-openssl.sh @@ -1,70 +1,58 @@ NPROC=$(grep -c processor /proc/cpuinfo) export MAKEFLAGS="-j ${NPROC}" OPENSSL_ROOT=openssl-1.0.2h OPENSSL_HASH=1d4007e53aad94a5b2002fe045ee7bb0b3d98f1a47f8b2bc851dcd1c74332919 -CMAKE_ROOT=cmake-3.7.2 function check_var { if [ -z "$1" ]; then echo "required variable not defined" exit 1 fi } function do_openssl_build { ./config no-ssl2 no-shared -fPIC --prefix=/usr/local/ssl && MAKEFLAGS="" make && MAKEFLAGS="" make install } function check_sha256sum { local fname=$1 check_var ${fname} local sha256=$2 check_var ${sha256} echo "${sha256} ${fname}" > ${fname}.sha256 sha256sum -c ${fname}.sha256 rm -f ${fname}.sha256 } function build_openssl { local openssl_fname=$1 check_var ${openssl_fname} local openssl_sha256=$2 check_var ${openssl_sha256} && check_sha256sum ${openssl_fname}.tar.gz ${openssl_sha256} && tar -xzf ${openssl_fname}.tar.gz && (cd ${openssl_fname} && do_openssl_build) && rm -rf ${openssl_fname} ${openssl_fname}.tar.gz } build_openssl $OPENSSL_ROOT $OPENSSL_HASH || exit 1 -tar xvzf ${CMAKE_ROOT}.tar.gz && -mkdir /tmp/cmake-build && -(cd /tmp/cmake-build && - ../${CMAKE_ROOT}/bootstrap --parallel=${NPROC} -- \ - -DCMAKE_BUILD_TYPE:STRING=Release \ - -DCMAKE_USE_OPENSSL:BOOL=ON \ - -DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl \ - -DCMAKE_USE_SYSTEM_CURL:BOOL=OFF && - make && - make install) || -exit 1 rm -rf /usr/local/ssl sed -i -e 's/3.4.8"/3.4.8","3.4.9"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.10"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.11"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.12"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.13"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.14"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.15"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.16"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.17"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json diff --git a/Wrapping/Python/PackageUtility/imagefiles/install.sh b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install.sh similarity index 85% rename from Wrapping/Python/PackageUtility/imagefiles/install.sh rename to Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install.sh index f01d53b9db..1fc16e7152 100755 --- a/Wrapping/Python/PackageUtility/imagefiles/install.sh +++ b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/install.sh @@ -1,70 +1,58 @@ NPROC=$(grep -c processor /proc/cpuinfo) export MAKEFLAGS="-j ${NPROC}" OPENSSL_ROOT=openssl-1.0.2h OPENSSL_HASH=1d4007e53aad94a5b2002fe045ee7bb0b3d98f1a47f8b2bc851dcd1c74332919 -CMAKE_ROOT=cmake-3.7.2 function check_var { if [ -z "$1" ]; then echo "required variable not defined" exit 1 fi } function do_openssl_build { ./config no-ssl2 no-shared -fPIC --prefix=/usr/local/ssl && MAKEFLAGS="" make && MAKEFLAGS="" make install } function check_sha256sum { local fname=$1 check_var ${fname} local sha256=$2 check_var ${sha256} echo "${sha256} ${fname}" > ${fname}.sha256 sha256sum -c ${fname}.sha256 rm -f ${fname}.sha256 } function build_openssl { local openssl_fname=$1 check_var ${openssl_fname} local openssl_sha256=$2 check_var ${openssl_sha256} && check_sha256sum ${openssl_fname}.tar.gz ${openssl_sha256} && tar -xzf ${openssl_fname}.tar.gz && (cd ${openssl_fname} && do_openssl_build) && rm -rf ${openssl_fname} ${openssl_fname}.tar.gz } build_openssl $OPENSSL_ROOT $OPENSSL_HASH || exit 1 -tar xvzf ${CMAKE_ROOT}.tar.gz && -mkdir /tmp/cmake-build && -(cd /tmp/cmake-build && - ../${CMAKE_ROOT}/bootstrap --parallel=${NPROC} -- \ - -DCMAKE_BUILD_TYPE:STRING=Release \ - -DCMAKE_USE_OPENSSL:BOOL=ON \ - -DOPENSSL_ROOT_DIR:PATH=/usr/local/ssl \ - -DCMAKE_USE_SYSTEM_CURL:BOOL=OFF && - make && - make install) || -exit 1 rm -rf /usr/local/ssl sed -i -e 's/3.4.8"/3.4.8","3.4.9"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.10"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.11"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.12"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.13"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.14"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.15"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.16"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json sed -i -e 's/3.4.8"/3.4.8","3.4.17"/g' /opt/_internal/cpython-3.6.4/lib/python3.6/site-packages/auditwheel/policy/policy.json diff --git a/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/qt-noninteractive.qs b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/qt-noninteractive.qs new file mode 100644 index 0000000000..d2564f41ad --- /dev/null +++ b/Wrapping/Python/PackageUtility/PythonWheelDocker/imagefiles/qt-noninteractive.qs @@ -0,0 +1,83 @@ +function Controller() { + installer.autoRejectMessageBoxes(); + installer.installationFinished.connect(function() { + gui.clickButton(buttons.NextButton); + }) +} + +Controller.prototype.WelcomePageCallback = function() { + gui.clickButton(buttons.NextButton, 510000); +} + +Controller.prototype.CredentialsPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.TargetDirectoryPageCallback = function() +{ + gui.currentPageWidget().TargetDirectoryLineEdit.setText("/qt"); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() { + var widget = gui.currentPageWidget(); + + widget.selectAll(); + widget.deselectComponent('qt.5112.src'); + widget.deselectComponent('qt.qt5.5112.qtvirtualkeyboard'); + widget.deselectComponent('qt.qt5.5112.android_x86'); + + + // widget.deselectAll(); + // widget.selectComponent("qt.594.gcc_64") + // // widget.selectComponent("qt.594.doc") + // // widget.selectComponent("qt.594.examples") + // widget.selectComponent("qt.594.qtcharts") + // widget.selectComponent("qt.594.qtcharts.gcc_64") + // widget.selectComponent("qt.594.qtdatavis3d") + // widget.selectComponent("qt.594.qtdatavis3d.gcc_64") + // widget.selectComponent("qt.594.qtnetworkauth") + // widget.selectComponent("qt.594.qtnetworkauth.gcc_64") + // widget.selectComponent("qt.594.qtpurchasing") + // widget.selectComponent("qt.594.qtpurchasing.gcc_64") + // widget.selectComponent("qt.594.qtremoteobjects") + // widget.selectComponent("qt.594.qtremoteobjects.gcc_64") + // widget.selectComponent("qt.594.qtscript") + // widget.selectComponent("qt.594.qtspeech") + // widget.selectComponent("qt.594.qtspeech.gcc_64") + // widget.selectComponent("qt.594.qtvirtualkeyboard") + // widget.selectComponent("qt.594.qtvirtualkeyboard.gcc_64") + // widget.selectComponent("qt.594.qtwebengine") + // widget.selectComponent("qt.594.qtwebengine.gcc_64") + // // widget.selectComponent("qt.594.src") + // widget.selectComponent("qt.tools.qtcreator") + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.LicenseAgreementPageCallback = function() { + gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.StartMenuDirectoryPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ReadyForInstallationPageCallback = function() +{ + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.FinishedPageCallback = function() { +var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm +if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) { + checkBoxForm.launchQtCreatorCheckBox.checked = false; +} + gui.clickButton(buttons.FinishButton); +} + diff --git a/Wrapping/Python/PackageUtility/run.sh b/Wrapping/Python/PackageUtility/PythonWheelDocker/run.sh similarity index 70% rename from Wrapping/Python/PackageUtility/run.sh rename to Wrapping/Python/PackageUtility/PythonWheelDocker/run.sh index 81c8549417..abc2e5115d 100755 --- a/Wrapping/Python/PackageUtility/run.sh +++ b/Wrapping/Python/PackageUtility/PythonWheelDocker/run.sh @@ -1,26 +1,27 @@ #!/bin/sh if [ -n "$ExternalData_OBJECT_STORES" -a -d "$ExternalData_OBJECT_STORES" ] ; then extra_args="-v ${ExternalData_OBJECT_STORES}:/var/io/.ExternalData -e ExternalData_OBJECT_STORES=/var/io/.ExternalData" fi if [ ! -z "${MITK_GIT_TAG}" ] ; then extra_args="${extra_args} -e MITK_GIT_TAG=${MITK_GIT_TAG}" fi # example versions: "cp27-cp27m cp27-cp27mu cp36-cp36m" if [ ! -z "${PYTHON_VERSIONS}" ] ; then extra_args="${extra_args} -e PYTHON_VERSIONS=${PYTHON_VERSIONS}" fi for ARCH in x86_64; do - # Docker container is build for a specific target plattfrom. - docker build --pull=true --rm=true -t mitk_manylinux_${ARCH} -f Dockerfile-${ARCH} . + # Docker container is build for a specific target plattfrom. + # docker build --pull=true --rm=true -t mitk_manylinux_${ARCH} -f Dockerfile-${ARCH} . + docker build --pull=true -t mitk_manylinux_${ARCH} -f Dockerfile-${ARCH} . - # Docker file is ran in order to generate the python wheels in it. - docker run --storage-opt size=150G --rm -e _USER=$(id -un) -e _USERID=$(id -u) -e_GROUPID=$(id -g) $extra_args -v $(pwd):/work/io -t pymitk_manylinux_${ARCH} + # Docker file is ran in order to generate the python wheels in it. + # docker run --storage-opt size=150G --rm -e _USER=$(id -un) -e _USERID=$(id -u) -e_GROUPID=$(id -g) $extra_args -v $(pwd):/work/io -t pymitk_manylinux_${ARCH} # use this command to get an interactive prompt to debug behavior #docker run --rm -i -t --entrypoint=/bin/bash -u=root $extra_args -v $(pwd):/var/io mitk_manylinux_${ARCH} done diff --git a/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/Dockerfile b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/Dockerfile new file mode 100644 index 0000000000..303b791cff --- /dev/null +++ b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/Dockerfile @@ -0,0 +1,183 @@ +FROM ubuntu:16.04 as builder +MAINTAINER Michael +WORKDIR /opt + +# Define the target software versions +ENV QT_VERSION_A=5.11 +ENV QT_VERSION_B=5.11.2 + +ENV CMAKE_VERSION_A=3.11 +ENV CMAKE_VERSION_B=3.11.4 + +ENV MITK_HASH T25826-RadiomicsGUIUpdate + + +# These lines are necessary in order to be able to updates the packages from within the DKFZ Network +ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ + +# Basic development tools +RUN apt-get -y update && apt-get -y install \ + build-essential \ + git \ + libfontconfig1-dev \ + libwrap0-dev \ + libglu1-mesa-dev \ + wget \ + libxt-dev \ + libtiff5-dev \ + libdbus-1-3 \ + libwrap0-dev \ + patchelf + +# Python development tools +RUN apt-get -y update && apt-get -y install \ + cython \ + python-pip \ + unzip \ + libsundials-serial-dev \ + python3-pip + +RUN mkdir /opt/mitk-bin \ + && mkdir /opt/bin + +#ENV QT_VERSION_SCRIPT=594 +COPY files/qt-noninteractive.qs /opt/qt-noninteractive.qs +RUN wget https://download.qt.io/archive/qt/${QT_VERSION_A}/${QT_VERSION_B}/qt-opensource-linux-x64-${QT_VERSION_B}.run \ + && chmod +x qt-opensource-linux-x64-${QT_VERSION_B}.run \ + && ./qt-opensource-linux-x64-${QT_VERSION_B}.run --script /opt/qt-noninteractive.qs -platform minimal --proxy --verbose \ + && rm qt-opensource-linux-x64-${QT_VERSION_B}.run + +#COPY files/cmake-3.10.3-Linux-x86_64.sh /cmake-3.10.3-Linux-x86_64.sh +RUN wget https://cmake.org/files/v${CMAKE_VERSION_A}/cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh \ + && mkdir /opt/cmake \ + && chmod +x cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh \ + && sh ./cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh --prefix=/opt/cmake --skip-license \ + && ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake \ + && cmake --version \ + && rm cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh + +RUN git clone -n https://phabricator.mitk.org/source/mitk.git mitk-src && cd mitk-src && git checkout $MITK_HASH \ + && cd /opt/mitk-bin \ + && cmake \ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DQt5_DIR:PATH=/qt/${QT_VERSION_B}/gcc_64/lib/cmake/Qt5/ \ + -DMITK_USE_BLUEBERRY:BOOL=ON \ + -DMITK_USE_CTK:BOOL=ON \ + -DMITK_USE_Qt5:BOOL=ON \ + -DMITK_USE_Vigra:BOOL=ON \ + -DMITK_USE_HDF5:BOOL=ON \ + -DMITK_USE_OpenCV:BOOL=ON \ + -DBUILD_TESTING:BOOL=OFF \ + -DMITK_USE_SWIG:BOOL=ON \ + -DMITK_USE_MatchPoint=ON\ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DGIT_EXECUTABLE:PATH=/usr/bin/git \ + ../mitk-src \ + && make -j"$(nproc)" MITK-Configure + +# Disabled Option +# -DCMAKE_INSTALL_PREFIX=/opt/install \ + + +RUN cd mitk-bin/MITK-build \ + && cmake \ + -DBUILD_ClassificationMiniApps:Bool=ON . \ + -DBUILD_BasicImageProcessingMiniApps:Bool=ON . \ + -DPYTHON_EXECUTABLE:PATH=/usr/bin/python3.5m \ + -DPYTHON_INCLUDE_DIR:PATH=/usr/include/python3.5m \ + -DPYTHON_LIBRARY:PATH=/usr/lib/x86_64-linux-gnu/libpython3.5m.so \ + -DWRAP_PYTHON=ON . \ + && make -j"$(nproc)" \ + && make dist \ + && ldd /opt/mitk-bin/MITK-build/bin/MitkFileConverter | awk 'BEGIN{ORS=" "}$1~/^\//{print $1}$3~/^\//{print $3}' | xargs -i -n 1 -d ' ' cp {} /opt/bin \ + && cp /opt/mitk-bin/MITK-build/bin/MitkFileConverter /opt/bin + +RUN cd /opt/bin/ && patchelf --set-rpath /opt/bin/ MitkFileConverter + #&& cd /opt/ \ + #&& rm -rf /opt/mitk-* + +ENV LD_LIBRARY_PATH /opt/bin/ + +RUN apt-get -y update && apt-get -y install \ + bison \ + docbook-xsl-ns \ + flex \ + gperf \ + gyp \ + libasound2-dev \ + libbz2-dev \ + libcap-dev \ + libcups2-dev \ + libdrm-dev \ + libegl1-mesa-dev \ + libfontconfig1-dev \ + libgcrypt11-dev \ + libglu1-mesa-dev \ + libnss3-dev \ + libpci-dev \ + libpulse-dev \ + libssl-dev \ + libtiff5-dev \ + libudev-dev \ + libwrap0-dev \ + libxcb-xinerama0-dev \ + libxcomposite-dev \ + libxcursor-dev \ + libxdamage-dev \ + libxrandr-dev \ + libxss-dev \ + libxt-dev \ + libxtst-dev \ + ninja-build \ + ruby \ + xvfb \ + xz-utils + +RUN cd mitk-bin/MITK-build \ + && make package +RUN echo $(find /opt/mitk-bin/MITK-build/ -name MITK-*.tar.gz -maxdepth 1) + +RUN mkdir /opt/mitk-inst \ + && tar -xzvf $(find /opt/mitk-bin/MITK-build/ -name MITK-*.tar.gz -maxdepth 1) -C /opt/mitk-inst \ + && mv $(find /opt/mitk-inst/ -name MITK-* -maxdepth 1) /opt/mitk-inst/mitk + +################################################################################################################################ +################################## Final Container ############################################################################# +################################################################################################################################ +FROM ubuntu:16.04 as final +MAINTAINER Michael +WORKDIR /opt + +# These lines are necessary in order to be able to updates the packages from within the DKFZ Network +ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ + +# Basic development tools +RUN apt-get -y update && apt-get -y install \ + libglib2.0-0 \ + libjpeg-turbo8 \ + libfontconfig1 \ + libtiff5 \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /opt/mitk-inst/mitk /opt/mitk +RUN printf '%s\n' '/opt/mitk/bin' '/opt/mitk/bin/plugins' > /etc/ld.so.conf.d/mitklibs.conf \ + && ldconfig + +COPY --from=builder /opt/mitk-bin/MITK-build/Wrapping/Python/dist/pyMITK-2016.11.99-cp35-cp35m-linux_x86_64.whl /opt/pyMITK-2016.11.99-cp35-cp35m-linux_x86_64.whl +RUN pip3 install --no-cache-dir pyMITK-2016.11.99-cp35-cp35m-linux_x86_64.whl \ + && pip3 install --no-cache-dir pandas \ + && python3 -c 'import pyMITK' +COPY ./scripts /opt/scripts + + +############## For testing purpose only ################# +#COPY flair.nii.gz flair.nii.gz +#COPY image.dcm image.dcm +#RUN (echo "import pyMITK as mitk\nimage=mitk.IOUtil.Load('/opt/image.dcm')") | python3 + +####### Execution Command ######### +# docker run --rm -it -v /home/mgoetz/drives/E130-Personal/Goetz/Datenkollektive/HAF-demodata/subjects:/data simple_pymitk2 python3 /opt/scripts/folderProcessing.py + diff --git a/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/PythonDockerfile b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/PythonDockerfile new file mode 100644 index 0000000000..b103b9732e --- /dev/null +++ b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/PythonDockerfile @@ -0,0 +1,32 @@ +FROM ubuntu:16.04 as builder +MAINTAINER Michael +WORKDIR /opt + +# These lines are necessary in order to be able to updates the packages from within the DKFZ Network +ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ + +# Basic development tools +RUN apt-get -y update && apt-get -y install \ + git \ + wget \ + libdbus-1-3 \ + patchelf + +# Python development tools +RUN apt-get -y update && apt-get -y install \ + cython \ + python-pip \ + unzip \ + libsundials-serial-dev \ + python3-pip + + +#ENV QT_VERSION_SCRIPT=594 +#COPY files/qt-noninteractive.qs /opt/qt-noninteractive.qs +#RUN wget https://download.qt.io/archive/qt/${QT_VERSION_A}/${QT_VERSION_B}/qt-opensource-linux-x64-${QT_VERSION_B}.run \ +# && chmod +x qt-opensource-linux-x64-${QT_VERSION_B}.run \ +# && ./qt-opensource-linux-x64-${QT_VERSION_B}.run --script /opt/qt-noninteractive.qs -platform minimal --proxy --verbose + +COPY pyMITK.whl /opt/pyMITK.whl +COPY pyMITK2.whl /opt/pyMITK2.whl diff --git a/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/df2 b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/df2 new file mode 100644 index 0000000000..1a0256f716 --- /dev/null +++ b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/df2 @@ -0,0 +1,27 @@ +FROM ubuntu:16.04 as builder +MAINTAINER Michael +WORKDIR /opt + +# Define the target software versions +ENV QT_VERSION_A=5.11 +ENV QT_VERSION_B=5.11.2 + +ENV CMAKE_VERSION_A=3.11 +ENV CMAKE_VERSION_B=3.11.4 + +ENV MITK_HASH T25826-RadiomicsGUIUpdate + + +# These lines are necessary in order to be able to updates the packages from within the DKFZ Network +ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ + +# Python development tools +RUN apt-get -y update && apt-get -y install \ + nano \ + cython \ + python-pip \ + unzip \ + libsundials-serial-dev \ + python3-pip + diff --git a/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/files/qt-noninteractive.qs b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/files/qt-noninteractive.qs new file mode 100644 index 0000000000..d2564f41ad --- /dev/null +++ b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/files/qt-noninteractive.qs @@ -0,0 +1,83 @@ +function Controller() { + installer.autoRejectMessageBoxes(); + installer.installationFinished.connect(function() { + gui.clickButton(buttons.NextButton); + }) +} + +Controller.prototype.WelcomePageCallback = function() { + gui.clickButton(buttons.NextButton, 510000); +} + +Controller.prototype.CredentialsPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.TargetDirectoryPageCallback = function() +{ + gui.currentPageWidget().TargetDirectoryLineEdit.setText("/qt"); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() { + var widget = gui.currentPageWidget(); + + widget.selectAll(); + widget.deselectComponent('qt.5112.src'); + widget.deselectComponent('qt.qt5.5112.qtvirtualkeyboard'); + widget.deselectComponent('qt.qt5.5112.android_x86'); + + + // widget.deselectAll(); + // widget.selectComponent("qt.594.gcc_64") + // // widget.selectComponent("qt.594.doc") + // // widget.selectComponent("qt.594.examples") + // widget.selectComponent("qt.594.qtcharts") + // widget.selectComponent("qt.594.qtcharts.gcc_64") + // widget.selectComponent("qt.594.qtdatavis3d") + // widget.selectComponent("qt.594.qtdatavis3d.gcc_64") + // widget.selectComponent("qt.594.qtnetworkauth") + // widget.selectComponent("qt.594.qtnetworkauth.gcc_64") + // widget.selectComponent("qt.594.qtpurchasing") + // widget.selectComponent("qt.594.qtpurchasing.gcc_64") + // widget.selectComponent("qt.594.qtremoteobjects") + // widget.selectComponent("qt.594.qtremoteobjects.gcc_64") + // widget.selectComponent("qt.594.qtscript") + // widget.selectComponent("qt.594.qtspeech") + // widget.selectComponent("qt.594.qtspeech.gcc_64") + // widget.selectComponent("qt.594.qtvirtualkeyboard") + // widget.selectComponent("qt.594.qtvirtualkeyboard.gcc_64") + // widget.selectComponent("qt.594.qtwebengine") + // widget.selectComponent("qt.594.qtwebengine.gcc_64") + // // widget.selectComponent("qt.594.src") + // widget.selectComponent("qt.tools.qtcreator") + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.LicenseAgreementPageCallback = function() { + gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.StartMenuDirectoryPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ReadyForInstallationPageCallback = function() +{ + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.FinishedPageCallback = function() { +var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm +if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) { + checkBoxForm.launchQtCreatorCheckBox.checked = false; +} + gui.clickButton(buttons.FinishButton); +} + diff --git a/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/calculate_3d_features.py b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/calculate_3d_features.py new file mode 100644 index 0000000000..1296c8de71 --- /dev/null +++ b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/calculate_3d_features.py @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jan 17 12:46:55 2019 + +@author: goetzm +""" +import pyMITK as mitk +import pandas as pd +import data_conversion as dc +import sys + +def print_status(status, add_whitespace=True): + sys.stdout.write('\r') + if add_whitespace: + sys.stdout.write(status+' ') + else: + sys.stdout.write(status) + sys.stdout.flush() + +def calculate_3d_features(initial_image, image, initial_mask, interpolated_mask, mask, + set_bins_normal, set_bins_onedistance, set_bins_ivh): + #return image, mask, image_resampled, mask_resampled + df = pd.DataFrame(columns=['Position','Name','Value']) + + ###### Pure Image Description Features + print_status('Diagnostic') + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(initial_image, initial_mask) + features1=dc.convert_features_into_dict(features_d) + next_idx = dc.add_image_description_features_to_df(df, features1, 0, name="Diagnostics-initial image") + + # No interpolation, thus using orignal image... + print_status('Image Description') + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(image, interpolated_mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_image_description_features_to_df(df, features, next_idx, name="Diagnostics-interpolated image") + #Mask Related Problems + next_idx = dc.add_mask_description_features_to_df(df, features1, next_idx, name="Diagnostics-initial ROI") + #Mask Related Problems + next_idx = dc.add_mask_description_features_to_df(df, features, next_idx, name="Diagnostics-interpolated ROI") + + ###### Cleaned Mask Description Features + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(image, mask) + features_2=dc.convert_features_into_dict(features_d) + next_idx = dc.add_mask_description_features_to_df(df, features_2, next_idx, name="Diagnostics-resegmented ROI", features_morph=features) + + ###### Calculate Volumetrics + print_status('Volumetrics') + calculator = mitk.GIFVolumetricStatistics_New() + features_d = calculator.CalculateFeatures(image, interpolated_mask) + features=dc.convert_features_into_dict(features_d) + calculator = mitk.GIFVolumetricStatistics_New() + features_d = calculator.CalculateFeatures(image, mask) + features2=dc.convert_features_into_dict(features_d) + next_idx = dc.add_volumetric_features_to_df(df, features, next_idx, features_intensity=features2) + + #calculator = mitk.GIFVolumetricDensityStatistics_New() + #calculator.SetMorphMask(interpolated_mask.GetPointer()) + #features_d = calculator.CalculateFeatures(image, mask) + #features=dc.convert_features_into_dict(features_d) + #next_idx = dc.add_volumetric_density_features_to_df(df, features, next_idx) + + ###### Calculate Local Intensities + print_status('Loci') + calculator = mitk.GIFLocalIntensity_New() + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_local_intensity_features_to_df(df, features, 91) + + ###### Calculate First Order Statistics + print_status('First order') + calculator = mitk.GIFFirstOrderNumericStatistics_New() + set_bins_onedistance(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_first_order_numeric_features_to_df(df, features, next_idx) + + ###### Calculate First Oder Histogram Statistics + print_status('First order Histogram') + calculator = mitk.GIFFirstOrderHistogramStatistics_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_intensity_histogram_features_to_df(df, features, next_idx) + + ###### Calculate intensity volume histogram + print_status('Intensity Volume') + calculator = mitk.GIFIntensityVolumeHistogramFeatures_New() + set_bins_ivh(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_intensity_volume_histogram_features_to_df(df, features, next_idx) + + ###### Calculate Co-occurence Matrix 3D + print_status('Cooc') + calculator = mitk.GIFCooccurenceMatrix2_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_cooccurence_3d_features_to_df(df, features, next_idx) + + ###### Calculate Run length matrix 3D + print_status('Run length') + calculator = mitk.GIFGreyLevelRunLength_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_runlength_3d_features_to_df(df, features, next_idx) + + ###### Calculate Size Zone 3D + print_status('Grey Level Size Zone') + calculator = mitk.GIFGreyLevelSizeZone_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_size_zone_3d_features_to_df(df, features, next_idx) + + ###### Calculate Distance Zone 3D + print_status('Distance Zone ') + calculator = mitk.GIFGreyLevelDistanceZone_New() + set_bins_normal(calculator) + calculator.SetMorphMask(interpolated_mask.GetPointer()) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_distance_zone_3d_features_to_df(df, features, next_idx) + + ###### Calculate Neighbourhood grey tone difference 3D + print_status('Grey tone difference') + calculator = mitk.GIFNeighbourhoodGreyToneDifferenceFeatures_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_neighbourhood_grey_tone_difference_3d_features_to_df(df, features, next_idx) + + ###### Calculate Neighbouring grey level dependence 3D + print_status('Grey Level Dependency') + calculator = mitk.GIFNeighbouringGreyLevelDependenceFeature_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_neighbouring_grey_level_dependence_3d_features_to_df(df, features, next_idx) + print_status("", False) + + return df + diff --git a/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/data_conversion.py b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/data_conversion.py new file mode 100644 index 0000000000..2fe88e43a6 --- /dev/null +++ b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/data_conversion.py @@ -0,0 +1,652 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 11 10:14:34 2019 + +@author: goetzm +""" +import math + +""" +Simple callable class. Will return an incremented number, starting with the given start_idx +""" +class IncrementalIndex: + def __init__(self, start_idx): + self.idx=start_idx-1 + def __call__(self): + self.idx = self.idx+1 + return self.idx + +""" +Converts a list of feature pairs (Feature name, Feature Value) into a dict +with Feature name as key and Feature Value as Value. Only the last feature will +be kept if more than one feature with the same name exists. +""" +def convert_features_into_dict(features_d): + features={} + for k in features_d: + features[k[0]]=k[1] + return features + + + +def add_volumetric_features_to_df(df, features, idx, features_intensity=None): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Morphology;Volume',features['Volumetric Features::Volume (mesh based)']] + else: + df.loc[df.index.max() + 1] = [idx,'Morphology;Volume',features['Volumetric Features::Volume (mesh based)']] + df.loc[df.index.max() + 1] = [idx+1,'Morphology;Approximate volume',features['Volumetric Features::Volume (voxel based)']] + df.loc[df.index.max() + 1] = [idx+2,'Morphology;Surface area',features['Volumetric Features::Surface (mesh based)']] + df.loc[df.index.max() + 1] = [idx+3,'Morphology;Surface to volume ratio',features['Volumetric Features::Surface to volume ratio (mesh based)']] + df.loc[df.index.max() + 1] = [idx+4,'Morphology;Compactness 1',features['Volumetric Features::Compactness 1 (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+5,'Morphology;Compactness 2',features['Volumetric Features::Compactness 2 (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+6,'Morphology;Spherical disproportion',features['Volumetric Features::Spherical disproportion (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+7,'Morphology;Sphericity',features['Volumetric Features::Sphericity (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+8,'Morphology;Asphericity',features['Volumetric Features::Asphericity (mesh, mesh based)']] + if features_intensity is None: + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Centre of mass shift',features['Volumetric Features::Centre of mass shift']] + else: + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Centre of mass shift',features_intensity['Volumetric Features::Centre of mass shift']] + df.loc[df.index.max() + 1] = [idx+10,'Morphology;Maximum 3D diameter',features['Volumetric Features::Maximum 3D diameter (mesh based)']] + df.loc[df.index.max() + 1] = [idx+11,'Morphology;Major axis length',features['Volumetric Features::PCA Major axis length']] + df.loc[df.index.max() + 1] = [idx+12,'Morphology;Minor axis length',features['Volumetric Features::PCA Minor axis length']] + df.loc[df.index.max() + 1] = [idx+13,'Morphology;Least axis length',features['Volumetric Features::PCA Least axis length']] + df.loc[df.index.max() + 1] = [idx+14,'Morphology;Elongation',features['Volumetric Features::PCA Elongation']] + df.loc[df.index.max() + 1] = [idx+15,'Morphology;Flatness',features['Volumetric Features::PCA Flatness']] + return idx+16 + +def add_volumetric_density_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Morphology;Volume density (AABB)',features['Morphological Density::Volume density axis-aligned bounding box']] + else: + df.loc[df.index.max() + 1] = [idx,'Morphology;Volume density (AABB)',features['Morphological Density::Volume density axis-aligned bounding box']] + df.loc[df.index.max() + 1] = [idx+1,'Morphology;Area density (AABB)',features['Morphological Density::Surface density axis-aligned bounding box']] + #df.loc[df.index.max() + 1] = [idx+2,'Morphology;Volume density (OMBB)',features['Morphological Density::Volume density oriented minimum bounding box']] + #df.loc[df.index.max() + 1] = [idx+3,'Morphology;Area density (OMBB)',features['Morphological Density::Surface density oriented minimum bounding box']] + df.loc[df.index.max() + 1] = [idx+2,'Morphology;Volume density (OMBB)',None] + df.loc[df.index.max() + 1] = [idx+3,'Morphology;Area density (OMBB)',None] + df.loc[df.index.max() + 1] = [idx+4,'Morphology;Volume density (AEE)',features['Morphological Density::Volume density approx. enclosing ellipsoid']] + df.loc[df.index.max() + 1] = [idx+5,'Morphology;Area density (AEE)',features['Morphological Density::Surface density approx. enclosing ellipsoid']] + #df.loc[df.index.max() + 1] = [idx+6,'Morphology;Volume density (MVEE)',features['Morphological Density::Volume density approx. minimum volume enclosing ellipsoid']] + #df.loc[df.index.max() + 1] = [idx+7,'Morphology;Area density (MVEE)',features['Morphological Density::Surface density approx. minimum volume enclosing ellipsoid']] + df.loc[df.index.max() + 1] = [idx+6,'Morphology;Volume density (MVEE)',None] + df.loc[df.index.max() + 1] = [idx+7,'Morphology;Area density (MVEE)',None] + df.loc[df.index.max() + 1] = [idx+8,'Morphology;Volume density (convex hull)',features['Morphological Density::Volume density convex hull']] + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Area density (convex hull)',features['Morphological Density::Surface density convex hull']] + df.loc[df.index.max() + 1] = [idx+10,'Morphology;Integrated intensity',features['Morphological Density::Volume integrated intensity']] + df.loc[df.index.max() + 1] = [idx+11,"digital phantom;Morphology;Moran's I index",features["Morphological Density::Volume Moran's I index"]] + df.loc[df.index.max() + 1] = [idx+12,"digital phantom;Morphology;Geary's C measure",features["Morphological Density::Volume Geary's C measure"]] + return idx+13 + +def add_local_intensity_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Local intensity;Local intensity peak',features['Local Intensity::2. Local Intensity Peak']] + else: + df.loc[df.index.max() + 1] = [idx,'Local intensity;Local intensity peak',features['Local Intensity::2. Local Intensity Peak']] + df.loc[df.index.max() + 1] = [idx+1,'Local intensity;Global intensity peak',features['Local Intensity::2. Global Intensity Peak']] + return idx+2 + +def add_first_order_numeric_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Statistics;Mean',features['First Order Numeric::Mean']] + else: + df.loc[df.index.max() + 1] = [idx,'Statistics;Mean',features['First Order Numeric::Mean']] + df.loc[df.index.max() + 1] = [idx+1,'Statistics;Variance',features['First Order Numeric::Variance']] + df.loc[df.index.max() + 1] = [idx+2,'Statistics;Skewness',features['First Order Numeric::Skewness']] + df.loc[df.index.max() + 1] = [idx+3,'Statistics;Kurtosis',features['First Order Numeric::Excess kurtosis']] + df.loc[df.index.max() + 1] = [idx+4,'Statistics;Median',features['First Order Numeric::Median']] + df.loc[df.index.max() + 1] = [idx+5,'Statistics;Minimum',features['First Order Numeric::Minimum']] + df.loc[df.index.max() + 1] = [idx+6,'Statistics;10th percentile',features['First Order Numeric::10th Percentile']] + df.loc[df.index.max() + 1] = [idx+7,'Statistics;90th percentile',features['First Order Numeric::90th Percentile']] + df.loc[df.index.max() + 1] = [idx+8,'Statistics;Maximum',features['First Order Numeric::Maximum']] + df.loc[df.index.max() + 1] = [idx+9,'Statistics;Interquartile range',features['First Order Numeric::Interquantile range']] + df.loc[df.index.max() + 1] = [idx+10,'Statistics;Range',features['First Order Numeric::Range']] + df.loc[df.index.max() + 1] = [idx+11,'Statistics;Mean absolute deviation',features['First Order Numeric::Mean absolute deviation']] + df.loc[df.index.max() + 1] = [idx+12,'Statistics;Robust mean absolute deviation',features['First Order Numeric::Robust mean absolute deviation']] + df.loc[df.index.max() + 1] = [idx+13,'Statistics;Median absolute deviation',features['First Order Numeric::Median absolute deviation']] + df.loc[df.index.max() + 1] = [idx+14,'Statistics;Coefficient of variation',features['First Order Numeric::Coefficient of variation']] + df.loc[df.index.max() + 1] = [idx+15,'Statistics;Quartile coefficient of dispersion',features['First Order Numeric::Quantile coefficient of dispersion']] + df.loc[df.index.max() + 1] = [idx+16,'Statistics;Energy',features['First Order Numeric::Energy']] + df.loc[df.index.max() + 1] = [idx+17,'Statistics;Root mean square',features['First Order Numeric::Root mean square']] + return idx+18 + +def add_intensity_histogram_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Intensity histogram;Mean',features['First Order Histogram::Mean Index']] + else: + df.loc[df.index.max() + 1] = [idx,'Intensity histogram;Mean',features['First Order Histogram::Mean Index']] + df.loc[df.index.max() + 1] = [idx+1,'Intensity histogram;Variance',features['First Order Histogram::Variance Index']] + df.loc[df.index.max() + 1] = [idx+2,'Intensity histogram;Skewness',features['First Order Histogram::Skewness Index']] + df.loc[df.index.max() + 1] = [idx+3,'Intensity histogram;Kurtosis',features['First Order Histogram::Excess Kurtosis Index']] + df.loc[df.index.max() + 1] = [idx+4,'Intensity histogram;Median',features['First Order Histogram::Median Index']] + df.loc[df.index.max() + 1] = [idx+5,'Intensity histogram;Minimum',features['First Order Histogram::Minimum Index']] + df.loc[df.index.max() + 1] = [idx+6,'Intensity histogram;10th percentile',features['First Order Histogram::Percentile 10 Index']] + df.loc[df.index.max() + 1] = [idx+7,'Intensity histogram;90th percentile',features['First Order Histogram::Percentile 90 Index']] + df.loc[df.index.max() + 1] = [idx+8,'Intensity histogram;Maximum',features['First Order Histogram::Maximum Index']] + df.loc[df.index.max() + 1] = [idx+9,'Intensity histogram;Mode',features['First Order Histogram::Mode Index']] + df.loc[df.index.max() + 1] = [idx+10,'Intensity histogram;Interquartile range',features['First Order Histogram::Interquantile Range Index']] + df.loc[df.index.max() + 1] = [idx+11,'Intensity histogram;Range',features['First Order Histogram::Range Index']] + df.loc[df.index.max() + 1] = [idx+12,'Intensity histogram;Mean absolute deviation',features['First Order Histogram::Mean Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+13,'Intensity histogram;Robust mean absolute deviation',features['First Order Histogram::Robust Mean Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+14,'Intensity histogram;Median absolute deviation',features['First Order Histogram::Median Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+15,'Intensity histogram;Coefficient of variation',features['First Order Histogram::Coefficient of Variation Index']] + df.loc[df.index.max() + 1] = [idx+16,'Intensity histogram;Quartile coefficient of dispersion',features['First Order Histogram::Quantile coefficient of Dispersion Index']] + df.loc[df.index.max() + 1] = [idx+17,'Intensity histogram;Entropy',features['First Order Histogram::Entropy Index']] + df.loc[df.index.max() + 1] = [idx+18,'Intensity histogram;Uniformity',features['First Order Histogram::Uniformity Index']] + df.loc[df.index.max() + 1] = [idx+19,'Intensity histogram;Maximum histogram gradient',features['First Order Histogram::Maximum Gradient']] + df.loc[df.index.max() + 1] = [idx+20,'Intensity histogram;Maximum gradient grey level',features['First Order Histogram::Maximum Gradient Index']] + df.loc[df.index.max() + 1] = [idx+21,'Intensity histogram;Minimum histogram gradient',features['First Order Histogram::Minimum Gradient']] + df.loc[df.index.max() + 1] = [idx+22,'Intensity histogram;Minimum gradient grey level',features['First Order Histogram::Minimum Gradient Index']] + return idx+23 + +def add_intensity_volume_histogram_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Intensity volume histogram;Volume fraction at 10% intensity',features['Intensity Volume Histogram::Volume fraction at 0.10 intensity']] + else: + df.loc[df.index.max() + 1] = [idx,'Intensity volume histogram;Volume fraction at 10% intensity',features['Intensity Volume Histogram::Volume fraction at 0.10 intensity']] + df.loc[df.index.max() + 1] = [idx+1,'Intensity volume histogram;Volume fraction at 90% intensity',features['Intensity Volume Histogram::Volume fraction at 0.90 intensity']] + df.loc[df.index.max() + 1] = [idx+2,'Intensity volume histogram;Intensity at 10% volume',features['Intensity Volume Histogram::Intensity at 0.10 volume']] + df.loc[df.index.max() + 1] = [idx+3,'Intensity volume histogram;Intensity at 90% volume',features['Intensity Volume Histogram::Intensity at 0.90 volume']] + df.loc[df.index.max() + 1] = [idx+4,'Intensity volume histogram;Volume fraction difference between 10% and 90% intensity',features['Intensity Volume Histogram::Difference volume fraction at 0.10 and 0.90 intensity']] + df.loc[df.index.max() + 1] = [idx+5,'Intensity volume histogram;Intensity difference between 10% and 90% volume',features['Intensity Volume Histogram::Difference intensity at 0.10 and 0.90 volume']] + df.loc[df.index.max() + 1] = [idx+6,'Intensity volume histogram;Area under the IVH curve',features['Intensity Volume Histogram::Area under IVH curve']] + return idx+7 + +def add_cooccurence_2d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (2D, averaged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (2D, averaged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (2D, averaged);Joint average',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (2D, averaged);Joint variance',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (2D, averaged);Joint entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (2D, averaged);Difference average',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (2D, averaged);Difference variance',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (2D, averaged);Difference entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (2D, averaged);Sum average',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (2D, averaged);Sum variance',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (2D, averaged);Sum entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (2D, averaged);Angular second moment',features['SliceWise Mean Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (2D, averaged);Contrast',features['SliceWise Mean Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (2D, averaged);Dissimilarity',features['SliceWise Mean Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (2D, averaged);Inverse difference',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (2D, averaged);Inverse difference normalised',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (2D, averaged);Inverse difference moment',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (2D, averaged);Inverse difference moment normalised',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (2D, averaged);Inverse variance',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (2D, averaged);Correlation',features['SliceWise Mean Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (2D, averaged);Autocorrelation',features['SliceWise Mean Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (2D, averaged);Cluster tendency',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (2D, averaged);Cluster shade',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (2D, averaged);Cluster prominence',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (2D, averaged);Information correlation 1',features['SliceWise Mean Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (2D, averaged);Information correlation 2',features['SliceWise Mean Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (2D, slice-merged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (2D, slice-merged);Joint average',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (2D, slice-merged);Joint variance',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (2D, slice-merged);Joint entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (2D, slice-merged);Difference average',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (2D, slice-merged);Difference variance',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (2D, slice-merged);Difference entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (2D, slice-merged);Sum average',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (2D, slice-merged);Sum variance',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (2D, slice-merged);Sum entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (2D, slice-merged);Angular second moment',features['SliceWise Mean Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (2D, slice-merged);Contrast',features['SliceWise Mean Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (2D, slice-merged);Dissimilarity',features['SliceWise Mean Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (2D, slice-merged);Inverse difference',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (2D, slice-merged);Inverse difference normalised',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (2D, slice-merged);Inverse difference moment',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (2D, slice-merged);Inverse difference moment normalised',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (2D, slice-merged);Inverse variance',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (2D, slice-merged);Correlation',features['SliceWise Mean Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (2D, slice-merged);Autocorrelation',features['SliceWise Mean Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (2D, slice-merged);Cluster tendency',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (2D, slice-merged);Cluster shade',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (2D, slice-merged);Cluster prominence',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (2D, slice-merged);Information correlation 1',features['SliceWise Mean Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (2D, slice-merged);Information correlation 2',features['SliceWise Mean Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + + +def add_cooccurence_2_5d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (2.5D, direction-merged);Joint average',features['Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (2.5D, direction-merged);Joint variance',features['Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (2.5D, direction-merged);Joint entropy',features['Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (2.5D, direction-merged);Difference average',features['Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (2.5D, direction-merged);Difference variance',features['Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (2.5D, direction-merged);Difference entropy',features['Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (2.5D, direction-merged);Sum average',features['Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (2.5D, direction-merged);Sum variance',features['Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (2.5D, direction-merged);Sum entropy',features['Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (2.5D, direction-merged);Angular second moment',features['Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (2.5D, direction-merged);Contrast',features['Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (2.5D, direction-merged);Dissimilarity',features['Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference',features['Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference normalised',features['Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment',features['Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (2.5D, direction-merged);Inverse variance',features['Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (2.5D, direction-merged);Correlation',features['Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (2.5D, direction-merged);Autocorrelation',features['Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (2.5D, direction-merged);Cluster tendency',features['Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (2.5D, direction-merged);Cluster shade',features['Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (2.5D, direction-merged);Cluster prominence',features['Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 1',features['Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 2',features['Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (2.5D, direction-merged);Joint average',features['Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (2.5D, direction-merged);Joint variance',features['Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (2.5D, direction-merged);Joint entropy',features['Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (2.5D, direction-merged);Difference average',features['Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (2.5D, direction-merged);Difference variance',features['Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (2.5D, direction-merged);Difference entropy',features['Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (2.5D, direction-merged);Sum average',features['Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (2.5D, direction-merged);Sum variance',features['Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (2.5D, direction-merged);Sum entropy',features['Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (2.5D, direction-merged);Angular second moment',features['Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (2.5D, direction-merged);Contrast',features['Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (2.5D, direction-merged);Dissimilarity',features['Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference',features['Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference normalised',features['Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment',features['Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (2.5D, direction-merged);Inverse variance',features['Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (2.5D, direction-merged);Correlation',features['Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (2.5D, direction-merged);Autocorrelation',features['Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (2.5D, direction-merged);Cluster tendency',features['Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (2.5D, direction-merged);Cluster shade',features['Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (2.5D, direction-merged);Cluster prominence',features['Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 1',features['Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 2',features['Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + +def add_cooccurence_3d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (3D, averaged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (3D, averaged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (3D, averaged);Joint average',features['Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (3D, averaged);Joint variance',features['Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (3D, averaged);Joint entropy',features['Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (3D, averaged);Difference average',features['Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (3D, averaged);Difference variance',features['Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (3D, averaged);Difference entropy',features['Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (3D, averaged);Sum average',features['Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (3D, averaged);Sum variance',features['Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (3D, averaged);Sum entropy',features['Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (3D, averaged);Angular second moment',features['Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (3D, averaged);Contrast',features['Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (3D, averaged);Dissimilarity',features['Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (3D, averaged);Inverse difference',features['Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (3D, averaged);Inverse difference normalised',features['Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (3D, averaged);Inverse difference moment',features['Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (3D, averaged);Inverse difference moment normalised',features['Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (3D, averaged);Inverse variance',features['Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (3D, averaged);Correlation',features['Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (3D, averaged);Autocorrelation',features['Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (3D, averaged);Cluster tendency',features['Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (3D, averaged);Cluster shade',features['Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (3D, averaged);Cluster prominence',features['Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (3D, averaged);Information correlation 1',features['Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (3D, averaged);Information correlation 2',features['Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (3D, merged);Joint maximum',features['Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (3D, merged);Joint average',features['Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (3D, merged);Joint variance',features['Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (3D, merged);Joint entropy',features['Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (3D, merged);Difference average',features['Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (3D, merged);Difference variance',features['Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (3D, merged);Difference entropy',features['Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (3D, merged);Sum average',features['Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (3D, merged);Sum variance',features['Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (3D, merged);Sum entropy',features['Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (3D, merged);Angular second moment',features['Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (3D, merged);Contrast',features['Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (3D, merged);Dissimilarity',features['Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (3D, merged);Inverse difference',features['Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (3D, merged);Inverse difference normalised',features['Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (3D, merged);Inverse difference moment',features['Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (3D, merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (3D, merged);Inverse variance',features['Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (3D, merged);Correlation',features['Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (3D, merged);Autocorrelation',features['Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (3D, merged);Cluster tendency',features['Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (3D, merged);Cluster shade',features['Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (3D, merged);Cluster prominence',features['Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (3D, merged);Information correlation 1',features['Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (3D, merged);Information correlation 2',features['Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + +def add_runlength_2d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (2D, averaged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (2D, averaged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (2D, averaged);Long runs emphasis',features['SliceWise Mean Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (2D, averaged);Low grey level run emphasis',features['SliceWise Mean Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (2D, averaged);High grey level run emphasis',features['SliceWise Mean Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (2D, averaged);Short run low grey level emphasis',features['SliceWise Mean Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (2D, averaged);Short run high grey level emphasis',features['SliceWise Mean Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (2D, averaged);Long run low grey level emphasis',features['SliceWise Mean Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (2D, averaged);Long run high grey level emphasis',features['SliceWise Mean Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (2D, averaged);Grey level non-uniformity',features['SliceWise Mean Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (2D, averaged);Grey level non-uniformity normalised',features['SliceWise Mean Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (2D, averaged);Run length non-uniformity',features['SliceWise Mean Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (2D, averaged);Run length non-uniformity normalised',features['SliceWise Mean Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (2D, averaged);Run percentage',features['SliceWise Mean Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (2D, averaged);Grey level variance',features['SliceWise Mean Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (2D, averaged);Run length variance',features['SliceWise Mean Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (2D, averaged);Run entropy',features['SliceWise Mean Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (2D, slice-merged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (2D, slice-merged);Long runs emphasis',features['SliceWise Mean Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (2D, slice-merged);Low grey level run emphasis',features['SliceWise Mean Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (2D, slice-merged);High grey level run emphasis',features['SliceWise Mean Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (2D, slice-merged);Short run low grey level emphasis',features['SliceWise Mean Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (2D, slice-merged);Short run high grey level emphasis',features['SliceWise Mean Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (2D, slice-merged);Long run low grey level emphasis',features['SliceWise Mean Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (2D, slice-merged);Long run high grey level emphasis',features['SliceWise Mean Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (2D, slice-merged);Grey level non-uniformity',features['SliceWise Mean Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (2D, slice-merged);Grey level non-uniformity normalised',features['SliceWise Mean Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (2D, slice-merged);Run length non-uniformity',features['SliceWise Mean Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (2D, slice-merged);Run length non-uniformity normalised',features['SliceWise Mean Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (2D, slice-merged);Run percentage',features['SliceWise Mean Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (2D, slice-merged);Grey level variance',features['SliceWise Mean Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (2D, slice-merged);Run length variance',features['SliceWise Mean Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (2D, slice-merged);Run entropy',features['SliceWise Mean Run Length::Run length entropy Comb.']] + return idx+32 + +def add_runlength_2_5d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (2.5D, direction-merged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (2.5D, direction-merged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (2.5D, direction-merged);Long runs emphasis',features['Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (2.5D, direction-merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (2.5D, direction-merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (2.5D, direction-merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (2.5D, direction-merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (2.5D, direction-merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (2.5D, direction-merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (2.5D, direction-merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (2.5D, direction-merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (2.5D, direction-merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (2.5D, direction-merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (2.5D, direction-merged);Run percentage',features['Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (2.5D, direction-merged);Grey level variance',features['Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (2.5D, direction-merged);Run length variance',features['Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (2.5D, direction-merged);Run entropy',features['Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (2.5D, merged);Short runs emphasis',features['Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (2.5D, merged);Long runs emphasis',features['Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (2.5D, merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (2.5D, merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (2.5D, merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (2.5D, merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (2.5D, merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (2.5D, merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (2.5D, merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (2.5D, merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (2.5D, merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (2.5D, merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (2.5D, merged);Run percentage',features['Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (2.5D, merged);Grey level variance',features['Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (2.5D, merged);Run length variance',features['Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (2.5D, merged);Run entropy',features['Run Length::Run length entropy Comb.']] + return idx+32 + +def add_runlength_3d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (3D, averaged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (3D, averaged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (3D, averaged);Long runs emphasis',features['Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (3D, averaged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (3D, averaged);High grey level run emphasis',features['Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (3D, averaged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (3D, averaged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (3D, averaged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (3D, averaged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (3D, averaged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (3D, averaged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (3D, averaged);Run length non-uniformity',features['Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (3D, averaged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (3D, averaged);Run percentage',features['Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (3D, averaged);Grey level variance',features['Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (3D, averaged);Run length variance',features['Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (3D, averaged);Run entropy',features['Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (3D, merged);Short runs emphasis',features['Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (3D, merged);Long runs emphasis',features['Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (3D, merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (3D, merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (3D, merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (3D, merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (3D, merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (3D, merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (3D, merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (3D, merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (3D, merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (3D, merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (3D, merged);Run percentage',features['Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (3D, merged);Grey level variance',features['Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (3D, merged);Run length variance',features['Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (3D, merged);Run entropy',features['Run Length::Run length entropy Comb.']] + return idx+32 + +def add_size_zone_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Size zone matrix (2D);Small zone emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);High grey level emphasis',features['SliceWise Mean Grey Level Size Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone high grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone high grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level non-uniformity',features['SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level non uniformity normalised',features['SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size non-uniformity',features['SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size non-uniformity normalised',features['SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone percentage',features['SliceWise Mean Grey Level Size Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level variance',features['SliceWise Mean Grey Level Size Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size variance',features['SliceWise Mean Grey Level Size Zone::Zone Size Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size entropy',features['SliceWise Mean Grey Level Size Zone::Zone Size Entropy']] + return cidx() + +def add_size_zone_3d_features_to_df(df, features, idx, feature_name="Distance zone matrix (2D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Small zone emphasis',features['Grey Level Size Zone::Small Zone Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone emphasis',features['Grey Level Size Zone::Small Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone emphasis',features['Grey Level Size Zone::Large Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level emphasis',features['Grey Level Size Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level emphasis',features['Grey Level Size Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone low grey level emphasis',features['Grey Level Size Zone::Small Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone high grey level emphasis',features['Grey Level Size Zone::Small Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone low grey level emphasis',features['Grey Level Size Zone::Large Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone high grey level emphasis',features['Grey Level Size Zone::Large Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Grey Level Size Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non uniformity normalised',features['Grey Level Size Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size non-uniformity',features['Grey Level Size Zone::Zone Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size non-uniformity normalised',features['Grey Level Size Zone::Zone Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone percentage',features['Grey Level Size Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Grey Level Size Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size variance',features['Grey Level Size Zone::Zone Size Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size entropy',features['Grey Level Size Zone::Zone Size Entropy']] + return cidx() + +def add_distance_zone_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Distance zone matrix (2D);Small distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);High grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance high grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance high grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level non-uniformity',features['SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level non-uniformity normalised',features['SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance non-uniformity',features['SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance non-uniformity normalised',features['SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone percentage',features['SliceWise Mean Grey Level Distance Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level variance',features['SliceWise Mean Grey Level Distance Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance variance',features['SliceWise Mean Grey Level Distance Zone::Zone Distance Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance entropy',features['SliceWise Mean Grey Level Distance Zone::Zone Distance Entropy']] + return cidx() + +def add_distance_zone_3d_features_to_df(df, features, idx, feature_name="Distance zone matrix (3D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Small distance emphasis',features['Grey Level Distance Zone::Small Distance Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance emphasis',features['Grey Level Distance Zone::Small Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance emphasis',features['Grey Level Distance Zone::Large Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level emphasis',features['Grey Level Distance Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level emphasis',features['Grey Level Distance Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance low grey level emphasis',features['Grey Level Distance Zone::Small Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance high grey level emphasis',features['Grey Level Distance Zone::Small Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance low grey level emphasis',features['Grey Level Distance Zone::Large Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance high grey level emphasis',features['Grey Level Distance Zone::Large Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Grey Level Distance Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity normalised',features['Grey Level Distance Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance non-uniformity',features['Grey Level Distance Zone::Distance Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance non-uniformity normalised',features['Grey Level Distance Zone::Distance Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone percentage',features['Grey Level Distance Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Grey Level Distance Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance variance',features['Grey Level Distance Zone::Zone Distance Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance entropy',features['Grey Level Distance Zone::Zone Distance Entropy']] + return cidx() + +def add_neighbourhood_grey_tone_difference_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Coarseness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Coarsness']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Coarseness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Coarsness']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Contrast',features['SliceWise Mean Neighbourhood Grey Tone Difference::Contrast']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Busyness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Busyness']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Complexity',features['SliceWise Mean Neighbourhood Grey Tone Difference::Complexity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Strength',features['SliceWise Mean Neighbourhood Grey Tone Difference::Strength']] + return cidx() + +def add_neighbourhood_grey_tone_difference_3d_features_to_df(df, features, idx, feature_name="Neighbourhood grey tone difference matrix (3D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Coarseness',features['Neighbourhood Grey Tone Difference::Coarsness']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Coarseness',features['Neighbourhood Grey Tone Difference::Coarsness']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Contrast',features['Neighbourhood Grey Tone Difference::Contrast']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Busyness',features['Neighbourhood Grey Tone Difference::Busyness']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Complexity',features['Neighbourhood Grey Tone Difference::Complexity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Strength',features['Neighbourhood Grey Tone Difference::Strength']] + return cidx() + +def add_neighbouring_grey_level_dependence_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low grey level count emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High grey level count emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence low grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence high grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence low grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence high grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level non-uniformity',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level non-uniformity normalised',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count non-uniformity',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count non-uniformity normalised',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count percentage',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level variance',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count variance',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count entropy',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Entropy']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count energy',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Energy']] + return cidx() + +def add_neighbouring_grey_level_dependence_3d_features_to_df(df, features, idx, feature_name='Neighbouring grey level dependence matrix (3D)'): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Low dependence emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence emphasis',features['Neighbouring Grey Level Dependence::High Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level count emphasis',features['Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level count emphasis',features['Neighbouring Grey Level Dependence::High Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence low grey level emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence high grey level emphasis',features['Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence low grey level emphasis',features['Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence high grey level emphasis',features['Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Neighbouring Grey Level Dependence::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity normalised',features['Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count non-uniformity',features['Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count non-uniformity normalised',features['Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count percentage',features['Neighbouring Grey Level Dependence::Dependence Count Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Neighbouring Grey Level Dependence::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count variance',features['Neighbouring Grey Level Dependence::Dependence Count Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count entropy',features['Neighbouring Grey Level Dependence::Dependence Count Entropy']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count energy',features['Neighbouring Grey Level Dependence::Dependence Count Energy']] + return cidx() + + + +def add_image_description_features_to_df(df, features, idx, name="Diagnostics"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),name+';Image dimension x',features['Diagnostic::Image Dimension X']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension x',features['Diagnostic::Image Dimension X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension y',features['Diagnostic::Image Dimension Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension z',features['Diagnostic::Image Dimension Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension x',features['Diagnostic::Image Spacing X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension y',features['Diagnostic::Image Spacing Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension z',features['Diagnostic::Image Spacing Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Mean intensity',features['Diagnostic::Image Mean intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Minimum intensity',features['Diagnostic::Image Minimum intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Maximum intensity',features['Diagnostic::Image Maximum intensity']] + return cidx() + +def add_mask_description_features_to_df(df, features, idx, name="Diagnostics", features_morph=None): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),name+';Int. mask dimension x',features['Diagnostic::Mask Dimension X']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension x',features['Diagnostic::Mask Dimension X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension y',features['Diagnostic::Mask Dimension Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension z',features['Diagnostic::Mask Dimension Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension x',features['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension y',features['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension z',features['Diagnostic::Mask bounding box Z']] + if features_morph is None: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension x',features['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension y',features['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension z',features['Diagnostic::Mask bounding box Z']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension x',features_morph['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension y',features_morph['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension z',features_morph['Diagnostic::Mask bounding box Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask voxel count',features['Diagnostic::Mask Voxel Count']] + if features_morph is None: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask voxel count',features['Diagnostic::Mask Voxel Count']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask voxel count',features_morph['Diagnostic::Mask Voxel Count']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask mean intensity',features['Diagnostic::Mask Mean intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask minimum intensity',features['Diagnostic::Mask Minimum intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask maximum intensity',features['Diagnostic::Mask Maximum intensity']] + return cidx() diff --git a/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/folderProcessing.py b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/folderProcessing.py new file mode 100644 index 0000000000..0785765300 --- /dev/null +++ b/Wrapping/Python/PackageUtility/Ubuntu1404PackageDocker/scripts/folderProcessing.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jan 9 10:30:20 2019 +@author: goetzm +""" + +import os +import pyMITK as mitk +import calculate_3d_features as c3df +import glob +import pandas as pd +import math + + +base_path=r"/data" + +def set_bins_normal(calculator): + calculator.SetBins(32) + calculator.SetUseBins(True) + +def set_bins_onedistance(calculator): + calculator.SetBinsize(1) + calculator.SetUseBinsize(True) + calculator.SetCorrectForBinsize(True) + +if True: + for t1_image_path in glob.iglob(os.path.join(base_path,"**","*T1w.nii.gz"), recursive=True): + print(t1_image_path) + image_dir = os.path.dirname(t1_image_path) + + list_t1_images = mitk.IOUtil.Load(t1_image_path) + t1_image = list_t1_images[0].ConvertToImage() + # Segments: + atlas_image_path = glob.glob(os.path.join(image_dir, "*Schaefer2018_100*.nii.gz"))[0] + list_atlas_images = mitk.IOUtil.Load(atlas_image_path) + atlas_image = list_atlas_images[0].ConvertToImage() + list_atlas_images2 = mitk.IOUtil.Load(atlas_image_path) + atlas_image1 = list_atlas_images2[0].ConvertToImage() + + atlas_mask_image=mitk.ArithmeticOperation.Divide(atlas_image, atlas_image1) + + list_of_dfs=[] + for i in range(100): + print("Working on Atlas ID",i+1) + current_mask=mitk.MaskCleaningOperation.RangeBasedMasking(atlas_image, atlas_mask_image, True, i+0.5, True, i+1.5) + cdf=c3df.calculate_3d_features(t1_image, t1_image, + current_mask, current_mask, current_mask, + set_bins_normal, set_bins_onedistance, set_bins_onedistance) + list_of_dfs.append(cdf) + + if True: + col_names=cdf['Name'].values.tolist() + col_names.append('SegmentID') + final_df=pd.DataFrame(columns=col_names) + for cdf,i in zip(list_of_dfs,range(100)): + cvalues=cdf['Value'].values.tolist() + cvalues.append(i+1) + if math.isnan(final_df.index.max()): + final_df.loc[0] = cvalues + else: + final_df.loc[final_df.index.max() + 1] = cvalues + final_df.to_csv(os.path.join(image_dir, "radiomics_values.csv"),sep=";") diff --git a/Wrapping/Python/PackageUtility/UbuntuPackageDocker/Dockerfile b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/Dockerfile new file mode 100644 index 0000000000..303b791cff --- /dev/null +++ b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/Dockerfile @@ -0,0 +1,183 @@ +FROM ubuntu:16.04 as builder +MAINTAINER Michael +WORKDIR /opt + +# Define the target software versions +ENV QT_VERSION_A=5.11 +ENV QT_VERSION_B=5.11.2 + +ENV CMAKE_VERSION_A=3.11 +ENV CMAKE_VERSION_B=3.11.4 + +ENV MITK_HASH T25826-RadiomicsGUIUpdate + + +# These lines are necessary in order to be able to updates the packages from within the DKFZ Network +ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ + +# Basic development tools +RUN apt-get -y update && apt-get -y install \ + build-essential \ + git \ + libfontconfig1-dev \ + libwrap0-dev \ + libglu1-mesa-dev \ + wget \ + libxt-dev \ + libtiff5-dev \ + libdbus-1-3 \ + libwrap0-dev \ + patchelf + +# Python development tools +RUN apt-get -y update && apt-get -y install \ + cython \ + python-pip \ + unzip \ + libsundials-serial-dev \ + python3-pip + +RUN mkdir /opt/mitk-bin \ + && mkdir /opt/bin + +#ENV QT_VERSION_SCRIPT=594 +COPY files/qt-noninteractive.qs /opt/qt-noninteractive.qs +RUN wget https://download.qt.io/archive/qt/${QT_VERSION_A}/${QT_VERSION_B}/qt-opensource-linux-x64-${QT_VERSION_B}.run \ + && chmod +x qt-opensource-linux-x64-${QT_VERSION_B}.run \ + && ./qt-opensource-linux-x64-${QT_VERSION_B}.run --script /opt/qt-noninteractive.qs -platform minimal --proxy --verbose \ + && rm qt-opensource-linux-x64-${QT_VERSION_B}.run + +#COPY files/cmake-3.10.3-Linux-x86_64.sh /cmake-3.10.3-Linux-x86_64.sh +RUN wget https://cmake.org/files/v${CMAKE_VERSION_A}/cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh \ + && mkdir /opt/cmake \ + && chmod +x cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh \ + && sh ./cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh --prefix=/opt/cmake --skip-license \ + && ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake \ + && cmake --version \ + && rm cmake-${CMAKE_VERSION_B}-Linux-x86_64.sh + +RUN git clone -n https://phabricator.mitk.org/source/mitk.git mitk-src && cd mitk-src && git checkout $MITK_HASH \ + && cd /opt/mitk-bin \ + && cmake \ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DQt5_DIR:PATH=/qt/${QT_VERSION_B}/gcc_64/lib/cmake/Qt5/ \ + -DMITK_USE_BLUEBERRY:BOOL=ON \ + -DMITK_USE_CTK:BOOL=ON \ + -DMITK_USE_Qt5:BOOL=ON \ + -DMITK_USE_Vigra:BOOL=ON \ + -DMITK_USE_HDF5:BOOL=ON \ + -DMITK_USE_OpenCV:BOOL=ON \ + -DBUILD_TESTING:BOOL=OFF \ + -DMITK_USE_SWIG:BOOL=ON \ + -DMITK_USE_MatchPoint=ON\ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DGIT_EXECUTABLE:PATH=/usr/bin/git \ + ../mitk-src \ + && make -j"$(nproc)" MITK-Configure + +# Disabled Option +# -DCMAKE_INSTALL_PREFIX=/opt/install \ + + +RUN cd mitk-bin/MITK-build \ + && cmake \ + -DBUILD_ClassificationMiniApps:Bool=ON . \ + -DBUILD_BasicImageProcessingMiniApps:Bool=ON . \ + -DPYTHON_EXECUTABLE:PATH=/usr/bin/python3.5m \ + -DPYTHON_INCLUDE_DIR:PATH=/usr/include/python3.5m \ + -DPYTHON_LIBRARY:PATH=/usr/lib/x86_64-linux-gnu/libpython3.5m.so \ + -DWRAP_PYTHON=ON . \ + && make -j"$(nproc)" \ + && make dist \ + && ldd /opt/mitk-bin/MITK-build/bin/MitkFileConverter | awk 'BEGIN{ORS=" "}$1~/^\//{print $1}$3~/^\//{print $3}' | xargs -i -n 1 -d ' ' cp {} /opt/bin \ + && cp /opt/mitk-bin/MITK-build/bin/MitkFileConverter /opt/bin + +RUN cd /opt/bin/ && patchelf --set-rpath /opt/bin/ MitkFileConverter + #&& cd /opt/ \ + #&& rm -rf /opt/mitk-* + +ENV LD_LIBRARY_PATH /opt/bin/ + +RUN apt-get -y update && apt-get -y install \ + bison \ + docbook-xsl-ns \ + flex \ + gperf \ + gyp \ + libasound2-dev \ + libbz2-dev \ + libcap-dev \ + libcups2-dev \ + libdrm-dev \ + libegl1-mesa-dev \ + libfontconfig1-dev \ + libgcrypt11-dev \ + libglu1-mesa-dev \ + libnss3-dev \ + libpci-dev \ + libpulse-dev \ + libssl-dev \ + libtiff5-dev \ + libudev-dev \ + libwrap0-dev \ + libxcb-xinerama0-dev \ + libxcomposite-dev \ + libxcursor-dev \ + libxdamage-dev \ + libxrandr-dev \ + libxss-dev \ + libxt-dev \ + libxtst-dev \ + ninja-build \ + ruby \ + xvfb \ + xz-utils + +RUN cd mitk-bin/MITK-build \ + && make package +RUN echo $(find /opt/mitk-bin/MITK-build/ -name MITK-*.tar.gz -maxdepth 1) + +RUN mkdir /opt/mitk-inst \ + && tar -xzvf $(find /opt/mitk-bin/MITK-build/ -name MITK-*.tar.gz -maxdepth 1) -C /opt/mitk-inst \ + && mv $(find /opt/mitk-inst/ -name MITK-* -maxdepth 1) /opt/mitk-inst/mitk + +################################################################################################################################ +################################## Final Container ############################################################################# +################################################################################################################################ +FROM ubuntu:16.04 as final +MAINTAINER Michael +WORKDIR /opt + +# These lines are necessary in order to be able to updates the packages from within the DKFZ Network +ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ + +# Basic development tools +RUN apt-get -y update && apt-get -y install \ + libglib2.0-0 \ + libjpeg-turbo8 \ + libfontconfig1 \ + libtiff5 \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /opt/mitk-inst/mitk /opt/mitk +RUN printf '%s\n' '/opt/mitk/bin' '/opt/mitk/bin/plugins' > /etc/ld.so.conf.d/mitklibs.conf \ + && ldconfig + +COPY --from=builder /opt/mitk-bin/MITK-build/Wrapping/Python/dist/pyMITK-2016.11.99-cp35-cp35m-linux_x86_64.whl /opt/pyMITK-2016.11.99-cp35-cp35m-linux_x86_64.whl +RUN pip3 install --no-cache-dir pyMITK-2016.11.99-cp35-cp35m-linux_x86_64.whl \ + && pip3 install --no-cache-dir pandas \ + && python3 -c 'import pyMITK' +COPY ./scripts /opt/scripts + + +############## For testing purpose only ################# +#COPY flair.nii.gz flair.nii.gz +#COPY image.dcm image.dcm +#RUN (echo "import pyMITK as mitk\nimage=mitk.IOUtil.Load('/opt/image.dcm')") | python3 + +####### Execution Command ######### +# docker run --rm -it -v /home/mgoetz/drives/E130-Personal/Goetz/Datenkollektive/HAF-demodata/subjects:/data simple_pymitk2 python3 /opt/scripts/folderProcessing.py + diff --git a/Wrapping/Python/PackageUtility/UbuntuPackageDocker/PythonDockerfile b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/PythonDockerfile new file mode 100644 index 0000000000..b103b9732e --- /dev/null +++ b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/PythonDockerfile @@ -0,0 +1,32 @@ +FROM ubuntu:16.04 as builder +MAINTAINER Michael +WORKDIR /opt + +# These lines are necessary in order to be able to updates the packages from within the DKFZ Network +ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ + +# Basic development tools +RUN apt-get -y update && apt-get -y install \ + git \ + wget \ + libdbus-1-3 \ + patchelf + +# Python development tools +RUN apt-get -y update && apt-get -y install \ + cython \ + python-pip \ + unzip \ + libsundials-serial-dev \ + python3-pip + + +#ENV QT_VERSION_SCRIPT=594 +#COPY files/qt-noninteractive.qs /opt/qt-noninteractive.qs +#RUN wget https://download.qt.io/archive/qt/${QT_VERSION_A}/${QT_VERSION_B}/qt-opensource-linux-x64-${QT_VERSION_B}.run \ +# && chmod +x qt-opensource-linux-x64-${QT_VERSION_B}.run \ +# && ./qt-opensource-linux-x64-${QT_VERSION_B}.run --script /opt/qt-noninteractive.qs -platform minimal --proxy --verbose + +COPY pyMITK.whl /opt/pyMITK.whl +COPY pyMITK2.whl /opt/pyMITK2.whl diff --git a/Wrapping/Python/PackageUtility/UbuntuPackageDocker/df2 b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/df2 new file mode 100644 index 0000000000..1a0256f716 --- /dev/null +++ b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/df2 @@ -0,0 +1,27 @@ +FROM ubuntu:16.04 as builder +MAINTAINER Michael +WORKDIR /opt + +# Define the target software versions +ENV QT_VERSION_A=5.11 +ENV QT_VERSION_B=5.11.2 + +ENV CMAKE_VERSION_A=3.11 +ENV CMAKE_VERSION_B=3.11.4 + +ENV MITK_HASH T25826-RadiomicsGUIUpdate + + +# These lines are necessary in order to be able to updates the packages from within the DKFZ Network +ENV http_proxy http://www-int2.dkfz-heidelberg.de:3128/ +ENV https_proxy https://www-int2.dkfz-heidelberg.de:3128/ + +# Python development tools +RUN apt-get -y update && apt-get -y install \ + nano \ + cython \ + python-pip \ + unzip \ + libsundials-serial-dev \ + python3-pip + diff --git a/Wrapping/Python/PackageUtility/UbuntuPackageDocker/files/qt-noninteractive.qs b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/files/qt-noninteractive.qs new file mode 100644 index 0000000000..d2564f41ad --- /dev/null +++ b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/files/qt-noninteractive.qs @@ -0,0 +1,83 @@ +function Controller() { + installer.autoRejectMessageBoxes(); + installer.installationFinished.connect(function() { + gui.clickButton(buttons.NextButton); + }) +} + +Controller.prototype.WelcomePageCallback = function() { + gui.clickButton(buttons.NextButton, 510000); +} + +Controller.prototype.CredentialsPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.TargetDirectoryPageCallback = function() +{ + gui.currentPageWidget().TargetDirectoryLineEdit.setText("/qt"); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() { + var widget = gui.currentPageWidget(); + + widget.selectAll(); + widget.deselectComponent('qt.5112.src'); + widget.deselectComponent('qt.qt5.5112.qtvirtualkeyboard'); + widget.deselectComponent('qt.qt5.5112.android_x86'); + + + // widget.deselectAll(); + // widget.selectComponent("qt.594.gcc_64") + // // widget.selectComponent("qt.594.doc") + // // widget.selectComponent("qt.594.examples") + // widget.selectComponent("qt.594.qtcharts") + // widget.selectComponent("qt.594.qtcharts.gcc_64") + // widget.selectComponent("qt.594.qtdatavis3d") + // widget.selectComponent("qt.594.qtdatavis3d.gcc_64") + // widget.selectComponent("qt.594.qtnetworkauth") + // widget.selectComponent("qt.594.qtnetworkauth.gcc_64") + // widget.selectComponent("qt.594.qtpurchasing") + // widget.selectComponent("qt.594.qtpurchasing.gcc_64") + // widget.selectComponent("qt.594.qtremoteobjects") + // widget.selectComponent("qt.594.qtremoteobjects.gcc_64") + // widget.selectComponent("qt.594.qtscript") + // widget.selectComponent("qt.594.qtspeech") + // widget.selectComponent("qt.594.qtspeech.gcc_64") + // widget.selectComponent("qt.594.qtvirtualkeyboard") + // widget.selectComponent("qt.594.qtvirtualkeyboard.gcc_64") + // widget.selectComponent("qt.594.qtwebengine") + // widget.selectComponent("qt.594.qtwebengine.gcc_64") + // // widget.selectComponent("qt.594.src") + // widget.selectComponent("qt.tools.qtcreator") + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.LicenseAgreementPageCallback = function() { + gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.StartMenuDirectoryPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ReadyForInstallationPageCallback = function() +{ + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.FinishedPageCallback = function() { +var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm +if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) { + checkBoxForm.launchQtCreatorCheckBox.checked = false; +} + gui.clickButton(buttons.FinishButton); +} + diff --git a/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/calculate_3d_features.py b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/calculate_3d_features.py new file mode 100644 index 0000000000..1296c8de71 --- /dev/null +++ b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/calculate_3d_features.py @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jan 17 12:46:55 2019 + +@author: goetzm +""" +import pyMITK as mitk +import pandas as pd +import data_conversion as dc +import sys + +def print_status(status, add_whitespace=True): + sys.stdout.write('\r') + if add_whitespace: + sys.stdout.write(status+' ') + else: + sys.stdout.write(status) + sys.stdout.flush() + +def calculate_3d_features(initial_image, image, initial_mask, interpolated_mask, mask, + set_bins_normal, set_bins_onedistance, set_bins_ivh): + #return image, mask, image_resampled, mask_resampled + df = pd.DataFrame(columns=['Position','Name','Value']) + + ###### Pure Image Description Features + print_status('Diagnostic') + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(initial_image, initial_mask) + features1=dc.convert_features_into_dict(features_d) + next_idx = dc.add_image_description_features_to_df(df, features1, 0, name="Diagnostics-initial image") + + # No interpolation, thus using orignal image... + print_status('Image Description') + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(image, interpolated_mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_image_description_features_to_df(df, features, next_idx, name="Diagnostics-interpolated image") + #Mask Related Problems + next_idx = dc.add_mask_description_features_to_df(df, features1, next_idx, name="Diagnostics-initial ROI") + #Mask Related Problems + next_idx = dc.add_mask_description_features_to_df(df, features, next_idx, name="Diagnostics-interpolated ROI") + + ###### Cleaned Mask Description Features + calculator = mitk.GIFImageDescriptionFeatures_New() + features_d = calculator.CalculateFeatures(image, mask) + features_2=dc.convert_features_into_dict(features_d) + next_idx = dc.add_mask_description_features_to_df(df, features_2, next_idx, name="Diagnostics-resegmented ROI", features_morph=features) + + ###### Calculate Volumetrics + print_status('Volumetrics') + calculator = mitk.GIFVolumetricStatistics_New() + features_d = calculator.CalculateFeatures(image, interpolated_mask) + features=dc.convert_features_into_dict(features_d) + calculator = mitk.GIFVolumetricStatistics_New() + features_d = calculator.CalculateFeatures(image, mask) + features2=dc.convert_features_into_dict(features_d) + next_idx = dc.add_volumetric_features_to_df(df, features, next_idx, features_intensity=features2) + + #calculator = mitk.GIFVolumetricDensityStatistics_New() + #calculator.SetMorphMask(interpolated_mask.GetPointer()) + #features_d = calculator.CalculateFeatures(image, mask) + #features=dc.convert_features_into_dict(features_d) + #next_idx = dc.add_volumetric_density_features_to_df(df, features, next_idx) + + ###### Calculate Local Intensities + print_status('Loci') + calculator = mitk.GIFLocalIntensity_New() + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_local_intensity_features_to_df(df, features, 91) + + ###### Calculate First Order Statistics + print_status('First order') + calculator = mitk.GIFFirstOrderNumericStatistics_New() + set_bins_onedistance(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx = dc.add_first_order_numeric_features_to_df(df, features, next_idx) + + ###### Calculate First Oder Histogram Statistics + print_status('First order Histogram') + calculator = mitk.GIFFirstOrderHistogramStatistics_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_intensity_histogram_features_to_df(df, features, next_idx) + + ###### Calculate intensity volume histogram + print_status('Intensity Volume') + calculator = mitk.GIFIntensityVolumeHistogramFeatures_New() + set_bins_ivh(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_intensity_volume_histogram_features_to_df(df, features, next_idx) + + ###### Calculate Co-occurence Matrix 3D + print_status('Cooc') + calculator = mitk.GIFCooccurenceMatrix2_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_cooccurence_3d_features_to_df(df, features, next_idx) + + ###### Calculate Run length matrix 3D + print_status('Run length') + calculator = mitk.GIFGreyLevelRunLength_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_runlength_3d_features_to_df(df, features, next_idx) + + ###### Calculate Size Zone 3D + print_status('Grey Level Size Zone') + calculator = mitk.GIFGreyLevelSizeZone_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_size_zone_3d_features_to_df(df, features, next_idx) + + ###### Calculate Distance Zone 3D + print_status('Distance Zone ') + calculator = mitk.GIFGreyLevelDistanceZone_New() + set_bins_normal(calculator) + calculator.SetMorphMask(interpolated_mask.GetPointer()) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_distance_zone_3d_features_to_df(df, features, next_idx) + + ###### Calculate Neighbourhood grey tone difference 3D + print_status('Grey tone difference') + calculator = mitk.GIFNeighbourhoodGreyToneDifferenceFeatures_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_neighbourhood_grey_tone_difference_3d_features_to_df(df, features, next_idx) + + ###### Calculate Neighbouring grey level dependence 3D + print_status('Grey Level Dependency') + calculator = mitk.GIFNeighbouringGreyLevelDependenceFeature_New() + set_bins_normal(calculator) + features_d = calculator.CalculateFeatures(image, mask) + features=dc.convert_features_into_dict(features_d) + next_idx=dc.add_neighbouring_grey_level_dependence_3d_features_to_df(df, features, next_idx) + print_status("", False) + + return df + diff --git a/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/data_conversion.py b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/data_conversion.py new file mode 100644 index 0000000000..2fe88e43a6 --- /dev/null +++ b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/data_conversion.py @@ -0,0 +1,652 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 11 10:14:34 2019 + +@author: goetzm +""" +import math + +""" +Simple callable class. Will return an incremented number, starting with the given start_idx +""" +class IncrementalIndex: + def __init__(self, start_idx): + self.idx=start_idx-1 + def __call__(self): + self.idx = self.idx+1 + return self.idx + +""" +Converts a list of feature pairs (Feature name, Feature Value) into a dict +with Feature name as key and Feature Value as Value. Only the last feature will +be kept if more than one feature with the same name exists. +""" +def convert_features_into_dict(features_d): + features={} + for k in features_d: + features[k[0]]=k[1] + return features + + + +def add_volumetric_features_to_df(df, features, idx, features_intensity=None): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Morphology;Volume',features['Volumetric Features::Volume (mesh based)']] + else: + df.loc[df.index.max() + 1] = [idx,'Morphology;Volume',features['Volumetric Features::Volume (mesh based)']] + df.loc[df.index.max() + 1] = [idx+1,'Morphology;Approximate volume',features['Volumetric Features::Volume (voxel based)']] + df.loc[df.index.max() + 1] = [idx+2,'Morphology;Surface area',features['Volumetric Features::Surface (mesh based)']] + df.loc[df.index.max() + 1] = [idx+3,'Morphology;Surface to volume ratio',features['Volumetric Features::Surface to volume ratio (mesh based)']] + df.loc[df.index.max() + 1] = [idx+4,'Morphology;Compactness 1',features['Volumetric Features::Compactness 1 (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+5,'Morphology;Compactness 2',features['Volumetric Features::Compactness 2 (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+6,'Morphology;Spherical disproportion',features['Volumetric Features::Spherical disproportion (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+7,'Morphology;Sphericity',features['Volumetric Features::Sphericity (mesh, mesh based)']] + df.loc[df.index.max() + 1] = [idx+8,'Morphology;Asphericity',features['Volumetric Features::Asphericity (mesh, mesh based)']] + if features_intensity is None: + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Centre of mass shift',features['Volumetric Features::Centre of mass shift']] + else: + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Centre of mass shift',features_intensity['Volumetric Features::Centre of mass shift']] + df.loc[df.index.max() + 1] = [idx+10,'Morphology;Maximum 3D diameter',features['Volumetric Features::Maximum 3D diameter (mesh based)']] + df.loc[df.index.max() + 1] = [idx+11,'Morphology;Major axis length',features['Volumetric Features::PCA Major axis length']] + df.loc[df.index.max() + 1] = [idx+12,'Morphology;Minor axis length',features['Volumetric Features::PCA Minor axis length']] + df.loc[df.index.max() + 1] = [idx+13,'Morphology;Least axis length',features['Volumetric Features::PCA Least axis length']] + df.loc[df.index.max() + 1] = [idx+14,'Morphology;Elongation',features['Volumetric Features::PCA Elongation']] + df.loc[df.index.max() + 1] = [idx+15,'Morphology;Flatness',features['Volumetric Features::PCA Flatness']] + return idx+16 + +def add_volumetric_density_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Morphology;Volume density (AABB)',features['Morphological Density::Volume density axis-aligned bounding box']] + else: + df.loc[df.index.max() + 1] = [idx,'Morphology;Volume density (AABB)',features['Morphological Density::Volume density axis-aligned bounding box']] + df.loc[df.index.max() + 1] = [idx+1,'Morphology;Area density (AABB)',features['Morphological Density::Surface density axis-aligned bounding box']] + #df.loc[df.index.max() + 1] = [idx+2,'Morphology;Volume density (OMBB)',features['Morphological Density::Volume density oriented minimum bounding box']] + #df.loc[df.index.max() + 1] = [idx+3,'Morphology;Area density (OMBB)',features['Morphological Density::Surface density oriented minimum bounding box']] + df.loc[df.index.max() + 1] = [idx+2,'Morphology;Volume density (OMBB)',None] + df.loc[df.index.max() + 1] = [idx+3,'Morphology;Area density (OMBB)',None] + df.loc[df.index.max() + 1] = [idx+4,'Morphology;Volume density (AEE)',features['Morphological Density::Volume density approx. enclosing ellipsoid']] + df.loc[df.index.max() + 1] = [idx+5,'Morphology;Area density (AEE)',features['Morphological Density::Surface density approx. enclosing ellipsoid']] + #df.loc[df.index.max() + 1] = [idx+6,'Morphology;Volume density (MVEE)',features['Morphological Density::Volume density approx. minimum volume enclosing ellipsoid']] + #df.loc[df.index.max() + 1] = [idx+7,'Morphology;Area density (MVEE)',features['Morphological Density::Surface density approx. minimum volume enclosing ellipsoid']] + df.loc[df.index.max() + 1] = [idx+6,'Morphology;Volume density (MVEE)',None] + df.loc[df.index.max() + 1] = [idx+7,'Morphology;Area density (MVEE)',None] + df.loc[df.index.max() + 1] = [idx+8,'Morphology;Volume density (convex hull)',features['Morphological Density::Volume density convex hull']] + df.loc[df.index.max() + 1] = [idx+9,'Morphology;Area density (convex hull)',features['Morphological Density::Surface density convex hull']] + df.loc[df.index.max() + 1] = [idx+10,'Morphology;Integrated intensity',features['Morphological Density::Volume integrated intensity']] + df.loc[df.index.max() + 1] = [idx+11,"digital phantom;Morphology;Moran's I index",features["Morphological Density::Volume Moran's I index"]] + df.loc[df.index.max() + 1] = [idx+12,"digital phantom;Morphology;Geary's C measure",features["Morphological Density::Volume Geary's C measure"]] + return idx+13 + +def add_local_intensity_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Local intensity;Local intensity peak',features['Local Intensity::2. Local Intensity Peak']] + else: + df.loc[df.index.max() + 1] = [idx,'Local intensity;Local intensity peak',features['Local Intensity::2. Local Intensity Peak']] + df.loc[df.index.max() + 1] = [idx+1,'Local intensity;Global intensity peak',features['Local Intensity::2. Global Intensity Peak']] + return idx+2 + +def add_first_order_numeric_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Statistics;Mean',features['First Order Numeric::Mean']] + else: + df.loc[df.index.max() + 1] = [idx,'Statistics;Mean',features['First Order Numeric::Mean']] + df.loc[df.index.max() + 1] = [idx+1,'Statistics;Variance',features['First Order Numeric::Variance']] + df.loc[df.index.max() + 1] = [idx+2,'Statistics;Skewness',features['First Order Numeric::Skewness']] + df.loc[df.index.max() + 1] = [idx+3,'Statistics;Kurtosis',features['First Order Numeric::Excess kurtosis']] + df.loc[df.index.max() + 1] = [idx+4,'Statistics;Median',features['First Order Numeric::Median']] + df.loc[df.index.max() + 1] = [idx+5,'Statistics;Minimum',features['First Order Numeric::Minimum']] + df.loc[df.index.max() + 1] = [idx+6,'Statistics;10th percentile',features['First Order Numeric::10th Percentile']] + df.loc[df.index.max() + 1] = [idx+7,'Statistics;90th percentile',features['First Order Numeric::90th Percentile']] + df.loc[df.index.max() + 1] = [idx+8,'Statistics;Maximum',features['First Order Numeric::Maximum']] + df.loc[df.index.max() + 1] = [idx+9,'Statistics;Interquartile range',features['First Order Numeric::Interquantile range']] + df.loc[df.index.max() + 1] = [idx+10,'Statistics;Range',features['First Order Numeric::Range']] + df.loc[df.index.max() + 1] = [idx+11,'Statistics;Mean absolute deviation',features['First Order Numeric::Mean absolute deviation']] + df.loc[df.index.max() + 1] = [idx+12,'Statistics;Robust mean absolute deviation',features['First Order Numeric::Robust mean absolute deviation']] + df.loc[df.index.max() + 1] = [idx+13,'Statistics;Median absolute deviation',features['First Order Numeric::Median absolute deviation']] + df.loc[df.index.max() + 1] = [idx+14,'Statistics;Coefficient of variation',features['First Order Numeric::Coefficient of variation']] + df.loc[df.index.max() + 1] = [idx+15,'Statistics;Quartile coefficient of dispersion',features['First Order Numeric::Quantile coefficient of dispersion']] + df.loc[df.index.max() + 1] = [idx+16,'Statistics;Energy',features['First Order Numeric::Energy']] + df.loc[df.index.max() + 1] = [idx+17,'Statistics;Root mean square',features['First Order Numeric::Root mean square']] + return idx+18 + +def add_intensity_histogram_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Intensity histogram;Mean',features['First Order Histogram::Mean Index']] + else: + df.loc[df.index.max() + 1] = [idx,'Intensity histogram;Mean',features['First Order Histogram::Mean Index']] + df.loc[df.index.max() + 1] = [idx+1,'Intensity histogram;Variance',features['First Order Histogram::Variance Index']] + df.loc[df.index.max() + 1] = [idx+2,'Intensity histogram;Skewness',features['First Order Histogram::Skewness Index']] + df.loc[df.index.max() + 1] = [idx+3,'Intensity histogram;Kurtosis',features['First Order Histogram::Excess Kurtosis Index']] + df.loc[df.index.max() + 1] = [idx+4,'Intensity histogram;Median',features['First Order Histogram::Median Index']] + df.loc[df.index.max() + 1] = [idx+5,'Intensity histogram;Minimum',features['First Order Histogram::Minimum Index']] + df.loc[df.index.max() + 1] = [idx+6,'Intensity histogram;10th percentile',features['First Order Histogram::Percentile 10 Index']] + df.loc[df.index.max() + 1] = [idx+7,'Intensity histogram;90th percentile',features['First Order Histogram::Percentile 90 Index']] + df.loc[df.index.max() + 1] = [idx+8,'Intensity histogram;Maximum',features['First Order Histogram::Maximum Index']] + df.loc[df.index.max() + 1] = [idx+9,'Intensity histogram;Mode',features['First Order Histogram::Mode Index']] + df.loc[df.index.max() + 1] = [idx+10,'Intensity histogram;Interquartile range',features['First Order Histogram::Interquantile Range Index']] + df.loc[df.index.max() + 1] = [idx+11,'Intensity histogram;Range',features['First Order Histogram::Range Index']] + df.loc[df.index.max() + 1] = [idx+12,'Intensity histogram;Mean absolute deviation',features['First Order Histogram::Mean Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+13,'Intensity histogram;Robust mean absolute deviation',features['First Order Histogram::Robust Mean Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+14,'Intensity histogram;Median absolute deviation',features['First Order Histogram::Median Absolute Deviation Index']] + df.loc[df.index.max() + 1] = [idx+15,'Intensity histogram;Coefficient of variation',features['First Order Histogram::Coefficient of Variation Index']] + df.loc[df.index.max() + 1] = [idx+16,'Intensity histogram;Quartile coefficient of dispersion',features['First Order Histogram::Quantile coefficient of Dispersion Index']] + df.loc[df.index.max() + 1] = [idx+17,'Intensity histogram;Entropy',features['First Order Histogram::Entropy Index']] + df.loc[df.index.max() + 1] = [idx+18,'Intensity histogram;Uniformity',features['First Order Histogram::Uniformity Index']] + df.loc[df.index.max() + 1] = [idx+19,'Intensity histogram;Maximum histogram gradient',features['First Order Histogram::Maximum Gradient']] + df.loc[df.index.max() + 1] = [idx+20,'Intensity histogram;Maximum gradient grey level',features['First Order Histogram::Maximum Gradient Index']] + df.loc[df.index.max() + 1] = [idx+21,'Intensity histogram;Minimum histogram gradient',features['First Order Histogram::Minimum Gradient']] + df.loc[df.index.max() + 1] = [idx+22,'Intensity histogram;Minimum gradient grey level',features['First Order Histogram::Minimum Gradient Index']] + return idx+23 + +def add_intensity_volume_histogram_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Intensity volume histogram;Volume fraction at 10% intensity',features['Intensity Volume Histogram::Volume fraction at 0.10 intensity']] + else: + df.loc[df.index.max() + 1] = [idx,'Intensity volume histogram;Volume fraction at 10% intensity',features['Intensity Volume Histogram::Volume fraction at 0.10 intensity']] + df.loc[df.index.max() + 1] = [idx+1,'Intensity volume histogram;Volume fraction at 90% intensity',features['Intensity Volume Histogram::Volume fraction at 0.90 intensity']] + df.loc[df.index.max() + 1] = [idx+2,'Intensity volume histogram;Intensity at 10% volume',features['Intensity Volume Histogram::Intensity at 0.10 volume']] + df.loc[df.index.max() + 1] = [idx+3,'Intensity volume histogram;Intensity at 90% volume',features['Intensity Volume Histogram::Intensity at 0.90 volume']] + df.loc[df.index.max() + 1] = [idx+4,'Intensity volume histogram;Volume fraction difference between 10% and 90% intensity',features['Intensity Volume Histogram::Difference volume fraction at 0.10 and 0.90 intensity']] + df.loc[df.index.max() + 1] = [idx+5,'Intensity volume histogram;Intensity difference between 10% and 90% volume',features['Intensity Volume Histogram::Difference intensity at 0.10 and 0.90 volume']] + df.loc[df.index.max() + 1] = [idx+6,'Intensity volume histogram;Area under the IVH curve',features['Intensity Volume Histogram::Area under IVH curve']] + return idx+7 + +def add_cooccurence_2d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (2D, averaged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (2D, averaged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (2D, averaged);Joint average',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (2D, averaged);Joint variance',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (2D, averaged);Joint entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (2D, averaged);Difference average',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (2D, averaged);Difference variance',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (2D, averaged);Difference entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (2D, averaged);Sum average',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (2D, averaged);Sum variance',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (2D, averaged);Sum entropy',features['SliceWise Mean Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (2D, averaged);Angular second moment',features['SliceWise Mean Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (2D, averaged);Contrast',features['SliceWise Mean Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (2D, averaged);Dissimilarity',features['SliceWise Mean Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (2D, averaged);Inverse difference',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (2D, averaged);Inverse difference normalised',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (2D, averaged);Inverse difference moment',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (2D, averaged);Inverse difference moment normalised',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (2D, averaged);Inverse variance',features['SliceWise Mean Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (2D, averaged);Correlation',features['SliceWise Mean Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (2D, averaged);Autocorrelation',features['SliceWise Mean Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (2D, averaged);Cluster tendency',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (2D, averaged);Cluster shade',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (2D, averaged);Cluster prominence',features['SliceWise Mean Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (2D, averaged);Information correlation 1',features['SliceWise Mean Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (2D, averaged);Information correlation 2',features['SliceWise Mean Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (2D, slice-merged);Joint maximum',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (2D, slice-merged);Joint average',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (2D, slice-merged);Joint variance',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (2D, slice-merged);Joint entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (2D, slice-merged);Difference average',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (2D, slice-merged);Difference variance',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (2D, slice-merged);Difference entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (2D, slice-merged);Sum average',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (2D, slice-merged);Sum variance',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (2D, slice-merged);Sum entropy',features['SliceWise Mean Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (2D, slice-merged);Angular second moment',features['SliceWise Mean Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (2D, slice-merged);Contrast',features['SliceWise Mean Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (2D, slice-merged);Dissimilarity',features['SliceWise Mean Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (2D, slice-merged);Inverse difference',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (2D, slice-merged);Inverse difference normalised',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (2D, slice-merged);Inverse difference moment',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (2D, slice-merged);Inverse difference moment normalised',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (2D, slice-merged);Inverse variance',features['SliceWise Mean Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (2D, slice-merged);Correlation',features['SliceWise Mean Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (2D, slice-merged);Autocorrelation',features['SliceWise Mean Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (2D, slice-merged);Cluster tendency',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (2D, slice-merged);Cluster shade',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (2D, slice-merged);Cluster prominence',features['SliceWise Mean Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (2D, slice-merged);Information correlation 1',features['SliceWise Mean Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (2D, slice-merged);Information correlation 2',features['SliceWise Mean Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + + +def add_cooccurence_2_5d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (2.5D, direction-merged);Joint average',features['Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (2.5D, direction-merged);Joint variance',features['Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (2.5D, direction-merged);Joint entropy',features['Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (2.5D, direction-merged);Difference average',features['Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (2.5D, direction-merged);Difference variance',features['Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (2.5D, direction-merged);Difference entropy',features['Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (2.5D, direction-merged);Sum average',features['Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (2.5D, direction-merged);Sum variance',features['Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (2.5D, direction-merged);Sum entropy',features['Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (2.5D, direction-merged);Angular second moment',features['Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (2.5D, direction-merged);Contrast',features['Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (2.5D, direction-merged);Dissimilarity',features['Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference',features['Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference normalised',features['Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment',features['Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (2.5D, direction-merged);Inverse variance',features['Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (2.5D, direction-merged);Correlation',features['Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (2.5D, direction-merged);Autocorrelation',features['Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (2.5D, direction-merged);Cluster tendency',features['Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (2.5D, direction-merged);Cluster shade',features['Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (2.5D, direction-merged);Cluster prominence',features['Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 1',features['Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 2',features['Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (2.5D, direction-merged);Joint maximum',features['Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (2.5D, direction-merged);Joint average',features['Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (2.5D, direction-merged);Joint variance',features['Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (2.5D, direction-merged);Joint entropy',features['Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (2.5D, direction-merged);Difference average',features['Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (2.5D, direction-merged);Difference variance',features['Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (2.5D, direction-merged);Difference entropy',features['Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (2.5D, direction-merged);Sum average',features['Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (2.5D, direction-merged);Sum variance',features['Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (2.5D, direction-merged);Sum entropy',features['Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (2.5D, direction-merged);Angular second moment',features['Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (2.5D, direction-merged);Contrast',features['Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (2.5D, direction-merged);Dissimilarity',features['Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference',features['Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference normalised',features['Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment',features['Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (2.5D, direction-merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (2.5D, direction-merged);Inverse variance',features['Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (2.5D, direction-merged);Correlation',features['Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (2.5D, direction-merged);Autocorrelation',features['Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (2.5D, direction-merged);Cluster tendency',features['Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (2.5D, direction-merged);Cluster shade',features['Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (2.5D, direction-merged);Cluster prominence',features['Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 1',features['Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (2.5D, direction-merged);Information correlation 2',features['Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + +def add_cooccurence_3d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Co-occurrence matrix (3D, averaged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + else: + df.loc[df.index.max() + 1] = [idx,'Co-occurrence matrix (3D, averaged);Joint maximum',features['Co-occurenced Based Features::Mean Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+1,'Co-occurrence matrix (3D, averaged);Joint average',features['Co-occurenced Based Features::Mean Joint Average']] + df.loc[df.index.max() + 1] = [idx+2,'Co-occurrence matrix (3D, averaged);Joint variance',features['Co-occurenced Based Features::Mean Joint Variance']] + df.loc[df.index.max() + 1] = [idx+3,'Co-occurrence matrix (3D, averaged);Joint entropy',features['Co-occurenced Based Features::Mean Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+4,'Co-occurrence matrix (3D, averaged);Difference average',features['Co-occurenced Based Features::Mean Difference Average']] + df.loc[df.index.max() + 1] = [idx+5,'Co-occurrence matrix (3D, averaged);Difference variance',features['Co-occurenced Based Features::Mean Difference Variance']] + df.loc[df.index.max() + 1] = [idx+6,'Co-occurrence matrix (3D, averaged);Difference entropy',features['Co-occurenced Based Features::Mean Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+7,'Co-occurrence matrix (3D, averaged);Sum average',features['Co-occurenced Based Features::Mean Sum Average']] + df.loc[df.index.max() + 1] = [idx+8,'Co-occurrence matrix (3D, averaged);Sum variance',features['Co-occurenced Based Features::Mean Sum Variance']] + df.loc[df.index.max() + 1] = [idx+9,'Co-occurrence matrix (3D, averaged);Sum entropy',features['Co-occurenced Based Features::Mean Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+10,'Co-occurrence matrix (3D, averaged);Angular second moment',features['Co-occurenced Based Features::Mean Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+11,'Co-occurrence matrix (3D, averaged);Contrast',features['Co-occurenced Based Features::Mean Contrast']] + df.loc[df.index.max() + 1] = [idx+12,'Co-occurrence matrix (3D, averaged);Dissimilarity',features['Co-occurenced Based Features::Mean Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+13,'Co-occurrence matrix (3D, averaged);Inverse difference',features['Co-occurenced Based Features::Mean Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+14,'Co-occurrence matrix (3D, averaged);Inverse difference normalised',features['Co-occurenced Based Features::Mean Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+15,'Co-occurrence matrix (3D, averaged);Inverse difference moment',features['Co-occurenced Based Features::Mean Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+16,'Co-occurrence matrix (3D, averaged);Inverse difference moment normalised',features['Co-occurenced Based Features::Mean Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+17,'Co-occurrence matrix (3D, averaged);Inverse variance',features['Co-occurenced Based Features::Mean Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+18,'Co-occurrence matrix (3D, averaged);Correlation',features['Co-occurenced Based Features::Mean Correlation']] + df.loc[df.index.max() + 1] = [idx+19,'Co-occurrence matrix (3D, averaged);Autocorrelation',features['Co-occurenced Based Features::Mean Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+20,'Co-occurrence matrix (3D, averaged);Cluster tendency',features['Co-occurenced Based Features::Mean Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+21,'Co-occurrence matrix (3D, averaged);Cluster shade',features['Co-occurenced Based Features::Mean Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+22,'Co-occurrence matrix (3D, averaged);Cluster prominence',features['Co-occurenced Based Features::Mean Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+23,'Co-occurrence matrix (3D, averaged);Information correlation 1',features['Co-occurenced Based Features::Mean First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+24,'Co-occurrence matrix (3D, averaged);Information correlation 2',features['Co-occurenced Based Features::Mean Second Measure of Information Correlation']] + + df.loc[df.index.max() + 1] = [idx+25,'Co-occurrence matrix (3D, merged);Joint maximum',features['Co-occurenced Based Features::Overall Joint Maximum']] + df.loc[df.index.max() + 1] = [idx+26,'Co-occurrence matrix (3D, merged);Joint average',features['Co-occurenced Based Features::Overall Joint Average']] + df.loc[df.index.max() + 1] = [idx+27,'Co-occurrence matrix (3D, merged);Joint variance',features['Co-occurenced Based Features::Overall Joint Variance']] + df.loc[df.index.max() + 1] = [idx+28,'Co-occurrence matrix (3D, merged);Joint entropy',features['Co-occurenced Based Features::Overall Joint Entropy']] + df.loc[df.index.max() + 1] = [idx+29,'Co-occurrence matrix (3D, merged);Difference average',features['Co-occurenced Based Features::Overall Difference Average']] + df.loc[df.index.max() + 1] = [idx+30,'Co-occurrence matrix (3D, merged);Difference variance',features['Co-occurenced Based Features::Overall Difference Variance']] + df.loc[df.index.max() + 1] = [idx+31,'Co-occurrence matrix (3D, merged);Difference entropy',features['Co-occurenced Based Features::Overall Difference Entropy']] + df.loc[df.index.max() + 1] = [idx+32,'Co-occurrence matrix (3D, merged);Sum average',features['Co-occurenced Based Features::Overall Sum Average']] + df.loc[df.index.max() + 1] = [idx+33,'Co-occurrence matrix (3D, merged);Sum variance',features['Co-occurenced Based Features::Overall Sum Variance']] + df.loc[df.index.max() + 1] = [idx+34,'Co-occurrence matrix (3D, merged);Sum entropy',features['Co-occurenced Based Features::Overall Sum Entropy']] + df.loc[df.index.max() + 1] = [idx+35,'Co-occurrence matrix (3D, merged);Angular second moment',features['Co-occurenced Based Features::Overall Angular Second Moment']] + df.loc[df.index.max() + 1] = [idx+36,'Co-occurrence matrix (3D, merged);Contrast',features['Co-occurenced Based Features::Overall Contrast']] + df.loc[df.index.max() + 1] = [idx+37,'Co-occurrence matrix (3D, merged);Dissimilarity',features['Co-occurenced Based Features::Overall Dissimilarity']] + df.loc[df.index.max() + 1] = [idx+38,'Co-occurrence matrix (3D, merged);Inverse difference',features['Co-occurenced Based Features::Overall Inverse Difference']] + df.loc[df.index.max() + 1] = [idx+39,'Co-occurrence matrix (3D, merged);Inverse difference normalised',features['Co-occurenced Based Features::Overall Inverse Difference Normalized']] + df.loc[df.index.max() + 1] = [idx+40,'Co-occurrence matrix (3D, merged);Inverse difference moment',features['Co-occurenced Based Features::Overall Inverse Difference Moment']] + df.loc[df.index.max() + 1] = [idx+41,'Co-occurrence matrix (3D, merged);Inverse difference moment normalised',features['Co-occurenced Based Features::Overall Inverse Difference Moment Normalized']] + df.loc[df.index.max() + 1] = [idx+42,'Co-occurrence matrix (3D, merged);Inverse variance',features['Co-occurenced Based Features::Overall Inverse Variance']] + df.loc[df.index.max() + 1] = [idx+43,'Co-occurrence matrix (3D, merged);Correlation',features['Co-occurenced Based Features::Overall Correlation']] + df.loc[df.index.max() + 1] = [idx+44,'Co-occurrence matrix (3D, merged);Autocorrelation',features['Co-occurenced Based Features::Overall Autocorrelation']] + df.loc[df.index.max() + 1] = [idx+45,'Co-occurrence matrix (3D, merged);Cluster tendency',features['Co-occurenced Based Features::Overall Cluster Tendency']] + df.loc[df.index.max() + 1] = [idx+46,'Co-occurrence matrix (3D, merged);Cluster shade',features['Co-occurenced Based Features::Overall Cluster Shade']] + df.loc[df.index.max() + 1] = [idx+47,'Co-occurrence matrix (3D, merged);Cluster prominence',features['Co-occurenced Based Features::Overall Cluster Prominence']] + df.loc[df.index.max() + 1] = [idx+48,'Co-occurrence matrix (3D, merged);Information correlation 1',features['Co-occurenced Based Features::Overall First Measure of Information Correlation']] + df.loc[df.index.max() + 1] = [idx+49,'Co-occurrence matrix (3D, merged);Information correlation 2',features['Co-occurenced Based Features::Overall Second Measure of Information Correlation']] + return idx+50 + +def add_runlength_2d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (2D, averaged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (2D, averaged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (2D, averaged);Long runs emphasis',features['SliceWise Mean Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (2D, averaged);Low grey level run emphasis',features['SliceWise Mean Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (2D, averaged);High grey level run emphasis',features['SliceWise Mean Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (2D, averaged);Short run low grey level emphasis',features['SliceWise Mean Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (2D, averaged);Short run high grey level emphasis',features['SliceWise Mean Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (2D, averaged);Long run low grey level emphasis',features['SliceWise Mean Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (2D, averaged);Long run high grey level emphasis',features['SliceWise Mean Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (2D, averaged);Grey level non-uniformity',features['SliceWise Mean Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (2D, averaged);Grey level non-uniformity normalised',features['SliceWise Mean Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (2D, averaged);Run length non-uniformity',features['SliceWise Mean Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (2D, averaged);Run length non-uniformity normalised',features['SliceWise Mean Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (2D, averaged);Run percentage',features['SliceWise Mean Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (2D, averaged);Grey level variance',features['SliceWise Mean Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (2D, averaged);Run length variance',features['SliceWise Mean Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (2D, averaged);Run entropy',features['SliceWise Mean Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (2D, slice-merged);Short runs emphasis',features['SliceWise Mean Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (2D, slice-merged);Long runs emphasis',features['SliceWise Mean Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (2D, slice-merged);Low grey level run emphasis',features['SliceWise Mean Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (2D, slice-merged);High grey level run emphasis',features['SliceWise Mean Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (2D, slice-merged);Short run low grey level emphasis',features['SliceWise Mean Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (2D, slice-merged);Short run high grey level emphasis',features['SliceWise Mean Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (2D, slice-merged);Long run low grey level emphasis',features['SliceWise Mean Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (2D, slice-merged);Long run high grey level emphasis',features['SliceWise Mean Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (2D, slice-merged);Grey level non-uniformity',features['SliceWise Mean Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (2D, slice-merged);Grey level non-uniformity normalised',features['SliceWise Mean Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (2D, slice-merged);Run length non-uniformity',features['SliceWise Mean Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (2D, slice-merged);Run length non-uniformity normalised',features['SliceWise Mean Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (2D, slice-merged);Run percentage',features['SliceWise Mean Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (2D, slice-merged);Grey level variance',features['SliceWise Mean Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (2D, slice-merged);Run length variance',features['SliceWise Mean Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (2D, slice-merged);Run entropy',features['SliceWise Mean Run Length::Run length entropy Comb.']] + return idx+32 + +def add_runlength_2_5d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (2.5D, direction-merged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (2.5D, direction-merged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (2.5D, direction-merged);Long runs emphasis',features['Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (2.5D, direction-merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (2.5D, direction-merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (2.5D, direction-merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (2.5D, direction-merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (2.5D, direction-merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (2.5D, direction-merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (2.5D, direction-merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (2.5D, direction-merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (2.5D, direction-merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (2.5D, direction-merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (2.5D, direction-merged);Run percentage',features['Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (2.5D, direction-merged);Grey level variance',features['Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (2.5D, direction-merged);Run length variance',features['Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (2.5D, direction-merged);Run entropy',features['Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (2.5D, merged);Short runs emphasis',features['Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (2.5D, merged);Long runs emphasis',features['Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (2.5D, merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (2.5D, merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (2.5D, merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (2.5D, merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (2.5D, merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (2.5D, merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (2.5D, merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (2.5D, merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (2.5D, merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (2.5D, merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (2.5D, merged);Run percentage',features['Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (2.5D, merged);Grey level variance',features['Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (2.5D, merged);Run length variance',features['Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (2.5D, merged);Run entropy',features['Run Length::Run length entropy Comb.']] + return idx+32 + +def add_runlength_3d_features_to_df(df, features, idx): + if math.isnan(df.index.max()): + df.loc[0] = [idx,'Run length matrix (3D, averaged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + else: + df.loc[df.index.max() + 1] = [idx,'Run length matrix (3D, averaged);Short runs emphasis',features['Run Length::Short run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+1,'Run length matrix (3D, averaged);Long runs emphasis',features['Run Length::Long run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+2,'Run length matrix (3D, averaged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+3,'Run length matrix (3D, averaged);High grey level run emphasis',features['Run Length::High grey level run emphasis Means']] + df.loc[df.index.max() + 1] = [idx+4,'Run length matrix (3D, averaged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+5,'Run length matrix (3D, averaged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+6,'Run length matrix (3D, averaged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+7,'Run length matrix (3D, averaged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Means']] + df.loc[df.index.max() + 1] = [idx+8,'Run length matrix (3D, averaged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+9,'Run length matrix (3D, averaged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+10,'Run length matrix (3D, averaged);Run length non-uniformity',features['Run Length::Run length nonuniformity Means']] + df.loc[df.index.max() + 1] = [idx+11,'Run length matrix (3D, averaged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Means']] + df.loc[df.index.max() + 1] = [idx+12,'Run length matrix (3D, averaged);Run percentage',features['Run Length::Run percentage Means']] + df.loc[df.index.max() + 1] = [idx+13,'Run length matrix (3D, averaged);Grey level variance',features['Run Length::Grey level variance Means']] + df.loc[df.index.max() + 1] = [idx+14,'Run length matrix (3D, averaged);Run length variance',features['Run Length::Run length variance Means']] + df.loc[df.index.max() + 1] = [idx+15,'Run length matrix (3D, averaged);Run entropy',features['Run Length::Run length entropy Means']] + + df.loc[df.index.max() + 1] = [idx+16,'Run length matrix (3D, merged);Short runs emphasis',features['Run Length::Short run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+17,'Run length matrix (3D, merged);Long runs emphasis',features['Run Length::Long run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+18,'Run length matrix (3D, merged);Low grey level run emphasis',features['Run Length::Low grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+19,'Run length matrix (3D, merged);High grey level run emphasis',features['Run Length::High grey level run emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+20,'Run length matrix (3D, merged);Short run low grey level emphasis',features['Run Length::Short run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+21,'Run length matrix (3D, merged);Short run high grey level emphasis',features['Run Length::Short run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+22,'Run length matrix (3D, merged);Long run low grey level emphasis',features['Run Length::Long run low grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+23,'Run length matrix (3D, merged);Long run high grey level emphasis',features['Run Length::Long run high grey level emphasis Comb.']] + df.loc[df.index.max() + 1] = [idx+24,'Run length matrix (3D, merged);Grey level non-uniformity',features['Run Length::Grey level nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+25,'Run length matrix (3D, merged);Grey level non-uniformity normalised',features['Run Length::Grey level nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+26,'Run length matrix (3D, merged);Run length non-uniformity',features['Run Length::Run length nonuniformity Comb.']] + df.loc[df.index.max() + 1] = [idx+27,'Run length matrix (3D, merged);Run length non-uniformity normalised',features['Run Length::Run length nonuniformity normalized Comb.']] + df.loc[df.index.max() + 1] = [idx+28,'Run length matrix (3D, merged);Run percentage',features['Run Length::Run percentage Comb.']] + df.loc[df.index.max() + 1] = [idx+29,'Run length matrix (3D, merged);Grey level variance',features['Run Length::Grey level variance Comb.']] + df.loc[df.index.max() + 1] = [idx+30,'Run length matrix (3D, merged);Run length variance',features['Run Length::Run length variance Comb.']] + df.loc[df.index.max() + 1] = [idx+31,'Run length matrix (3D, merged);Run entropy',features['Run Length::Run length entropy Comb.']] + return idx+32 + +def add_size_zone_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Size zone matrix (2D);Small zone emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);High grey level emphasis',features['SliceWise Mean Grey Level Size Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Small zone high grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Small Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone low grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Large zone high grey level emphasis',features['SliceWise Mean Grey Level Size Zone::Large Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level non-uniformity',features['SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level non uniformity normalised',features['SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size non-uniformity',features['SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size non-uniformity normalised',features['SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone percentage',features['SliceWise Mean Grey Level Size Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Grey level variance',features['SliceWise Mean Grey Level Size Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size variance',features['SliceWise Mean Grey Level Size Zone::Zone Size Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Size zone matrix (2D);Zone size entropy',features['SliceWise Mean Grey Level Size Zone::Zone Size Entropy']] + return cidx() + +def add_size_zone_3d_features_to_df(df, features, idx, feature_name="Distance zone matrix (2D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Small zone emphasis',features['Grey Level Size Zone::Small Zone Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone emphasis',features['Grey Level Size Zone::Small Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone emphasis',features['Grey Level Size Zone::Large Zone Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level emphasis',features['Grey Level Size Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level emphasis',features['Grey Level Size Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone low grey level emphasis',features['Grey Level Size Zone::Small Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small zone high grey level emphasis',features['Grey Level Size Zone::Small Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone low grey level emphasis',features['Grey Level Size Zone::Large Zone Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large zone high grey level emphasis',features['Grey Level Size Zone::Large Zone High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Grey Level Size Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non uniformity normalised',features['Grey Level Size Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size non-uniformity',features['Grey Level Size Zone::Zone Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size non-uniformity normalised',features['Grey Level Size Zone::Zone Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone percentage',features['Grey Level Size Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Grey Level Size Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size variance',features['Grey Level Size Zone::Zone Size Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone size entropy',features['Grey Level Size Zone::Zone Size Entropy']] + return cidx() + +def add_distance_zone_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Distance zone matrix (2D);Small distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);High grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Small distance high grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Small Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance low grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Large distance high grey level emphasis',features['SliceWise Mean Grey Level Distance Zone::Large Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level non-uniformity',features['SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level non-uniformity normalised',features['SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance non-uniformity',features['SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance non-uniformity normalised',features['SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone percentage',features['SliceWise Mean Grey Level Distance Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Grey level variance',features['SliceWise Mean Grey Level Distance Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance variance',features['SliceWise Mean Grey Level Distance Zone::Zone Distance Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Distance zone matrix (2D);Zone distance entropy',features['SliceWise Mean Grey Level Distance Zone::Zone Distance Entropy']] + return cidx() + +def add_distance_zone_3d_features_to_df(df, features, idx, feature_name="Distance zone matrix (3D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Small distance emphasis',features['Grey Level Distance Zone::Small Distance Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance emphasis',features['Grey Level Distance Zone::Small Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance emphasis',features['Grey Level Distance Zone::Large Distance Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level emphasis',features['Grey Level Distance Zone::Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level emphasis',features['Grey Level Distance Zone::High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance low grey level emphasis',features['Grey Level Distance Zone::Small Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Small distance high grey level emphasis',features['Grey Level Distance Zone::Small Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance low grey level emphasis',features['Grey Level Distance Zone::Large Distance Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Large distance high grey level emphasis',features['Grey Level Distance Zone::Large Distance High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Grey Level Distance Zone::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity normalised',features['Grey Level Distance Zone::Grey Level Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance non-uniformity',features['Grey Level Distance Zone::Distance Size Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance non-uniformity normalised',features['Grey Level Distance Zone::Distance Size Non-Uniformity Normalized']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone percentage',features['Grey Level Distance Zone::Zone Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Grey Level Distance Zone::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance variance',features['Grey Level Distance Zone::Zone Distance Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Zone distance entropy',features['Grey Level Distance Zone::Zone Distance Entropy']] + return cidx() + +def add_neighbourhood_grey_tone_difference_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Coarseness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Coarsness']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Coarseness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Coarsness']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Contrast',features['SliceWise Mean Neighbourhood Grey Tone Difference::Contrast']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Busyness',features['SliceWise Mean Neighbourhood Grey Tone Difference::Busyness']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Complexity',features['SliceWise Mean Neighbourhood Grey Tone Difference::Complexity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbourhood grey tone difference matrix (2D);Strength',features['SliceWise Mean Neighbourhood Grey Tone Difference::Strength']] + return cidx() + +def add_neighbourhood_grey_tone_difference_3d_features_to_df(df, features, idx, feature_name="Neighbourhood grey tone difference matrix (3D)"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Coarseness',features['Neighbourhood Grey Tone Difference::Coarsness']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Coarseness',features['Neighbourhood Grey Tone Difference::Coarsness']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Contrast',features['Neighbourhood Grey Tone Difference::Contrast']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Busyness',features['Neighbourhood Grey Tone Difference::Busyness']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Complexity',features['Neighbourhood Grey Tone Difference::Complexity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Strength',features['Neighbourhood Grey Tone Difference::Strength']] + return cidx() + +def add_neighbouring_grey_level_dependence_2d_features_to_df(df, features, idx): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low grey level count emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High grey level count emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence low grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Low dependence high grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence low grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);High dependence high grey level emphasis',features['SliceWise Mean Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level non-uniformity',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level non-uniformity normalised',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count non-uniformity',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count non-uniformity normalised',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count percentage',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Percentage']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Grey level variance',features['SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count variance',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Variance']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count entropy',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Entropy']] + df.loc[df.index.max() + 1] = [cidx(),'Neighbouring grey level dependence matrix (2D);Dependence count energy',features['SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Energy']] + return cidx() + +def add_neighbouring_grey_level_dependence_3d_features_to_df(df, features, idx, feature_name='Neighbouring grey level dependence matrix (3D)'): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),feature_name+';Low dependence emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + else: + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence emphasis',features['Neighbouring Grey Level Dependence::High Dependence Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low grey level count emphasis',features['Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High grey level count emphasis',features['Neighbouring Grey Level Dependence::High Grey Level Count Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence low grey level emphasis',features['Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Low dependence high grey level emphasis',features['Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence low grey level emphasis',features['Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';High dependence high grey level emphasis',features['Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity',features['Neighbouring Grey Level Dependence::Grey Level Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level non-uniformity normalised',features['Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count non-uniformity',features['Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count non-uniformity normalised',features['Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count percentage',features['Neighbouring Grey Level Dependence::Dependence Count Percentage']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Grey level variance',features['Neighbouring Grey Level Dependence::Grey Level Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count variance',features['Neighbouring Grey Level Dependence::Dependence Count Variance']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count entropy',features['Neighbouring Grey Level Dependence::Dependence Count Entropy']] + df.loc[df.index.max() + 1] = [cidx(),feature_name+';Dependence count energy',features['Neighbouring Grey Level Dependence::Dependence Count Energy']] + return cidx() + + + +def add_image_description_features_to_df(df, features, idx, name="Diagnostics"): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),name+';Image dimension x',features['Diagnostic::Image Dimension X']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension x',features['Diagnostic::Image Dimension X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension y',features['Diagnostic::Image Dimension Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Image dimension z',features['Diagnostic::Image Dimension Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension x',features['Diagnostic::Image Spacing X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension y',features['Diagnostic::Image Spacing Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Voxel dimension z',features['Diagnostic::Image Spacing Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Mean intensity',features['Diagnostic::Image Mean intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Minimum intensity',features['Diagnostic::Image Minimum intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Maximum intensity',features['Diagnostic::Image Maximum intensity']] + return cidx() + +def add_mask_description_features_to_df(df, features, idx, name="Diagnostics", features_morph=None): + cidx = IncrementalIndex(idx) + if math.isnan(df.index.max()): + df.loc[0] = [cidx(),name+';Int. mask dimension x',features['Diagnostic::Mask Dimension X']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension x',features['Diagnostic::Mask Dimension X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension y',features['Diagnostic::Mask Dimension Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask dimension z',features['Diagnostic::Mask Dimension Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension x',features['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension y',features['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask bounding box dimension z',features['Diagnostic::Mask bounding box Z']] + if features_morph is None: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension x',features['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension y',features['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension z',features['Diagnostic::Mask bounding box Z']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension x',features_morph['Diagnostic::Mask bounding box X']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension y',features_morph['Diagnostic::Mask bounding box Y']] + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask bounding box dimension z',features_morph['Diagnostic::Mask bounding box Z']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask voxel count',features['Diagnostic::Mask Voxel Count']] + if features_morph is None: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask voxel count',features['Diagnostic::Mask Voxel Count']] + else: + df.loc[df.index.max() + 1] = [cidx(),name+';Morph. mask voxel count',features_morph['Diagnostic::Mask Voxel Count']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask mean intensity',features['Diagnostic::Mask Mean intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask minimum intensity',features['Diagnostic::Mask Minimum intensity']] + df.loc[df.index.max() + 1] = [cidx(),name+';Int. mask maximum intensity',features['Diagnostic::Mask Maximum intensity']] + return cidx() diff --git a/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/folderProcessing.py b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/folderProcessing.py new file mode 100644 index 0000000000..0785765300 --- /dev/null +++ b/Wrapping/Python/PackageUtility/UbuntuPackageDocker/scripts/folderProcessing.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jan 9 10:30:20 2019 +@author: goetzm +""" + +import os +import pyMITK as mitk +import calculate_3d_features as c3df +import glob +import pandas as pd +import math + + +base_path=r"/data" + +def set_bins_normal(calculator): + calculator.SetBins(32) + calculator.SetUseBins(True) + +def set_bins_onedistance(calculator): + calculator.SetBinsize(1) + calculator.SetUseBinsize(True) + calculator.SetCorrectForBinsize(True) + +if True: + for t1_image_path in glob.iglob(os.path.join(base_path,"**","*T1w.nii.gz"), recursive=True): + print(t1_image_path) + image_dir = os.path.dirname(t1_image_path) + + list_t1_images = mitk.IOUtil.Load(t1_image_path) + t1_image = list_t1_images[0].ConvertToImage() + # Segments: + atlas_image_path = glob.glob(os.path.join(image_dir, "*Schaefer2018_100*.nii.gz"))[0] + list_atlas_images = mitk.IOUtil.Load(atlas_image_path) + atlas_image = list_atlas_images[0].ConvertToImage() + list_atlas_images2 = mitk.IOUtil.Load(atlas_image_path) + atlas_image1 = list_atlas_images2[0].ConvertToImage() + + atlas_mask_image=mitk.ArithmeticOperation.Divide(atlas_image, atlas_image1) + + list_of_dfs=[] + for i in range(100): + print("Working on Atlas ID",i+1) + current_mask=mitk.MaskCleaningOperation.RangeBasedMasking(atlas_image, atlas_mask_image, True, i+0.5, True, i+1.5) + cdf=c3df.calculate_3d_features(t1_image, t1_image, + current_mask, current_mask, current_mask, + set_bins_normal, set_bins_onedistance, set_bins_onedistance) + list_of_dfs.append(cdf) + + if True: + col_names=cdf['Name'].values.tolist() + col_names.append('SegmentID') + final_df=pd.DataFrame(columns=col_names) + for cdf,i in zip(list_of_dfs,range(100)): + cvalues=cdf['Value'].values.tolist() + cvalues.append(i+1) + if math.isnan(final_df.index.max()): + final_df.loc[0] = cvalues + else: + final_df.loc[final_df.index.max() + 1] = cvalues + final_df.to_csv(os.path.join(image_dir, "radiomics_values.csv"),sep=";") diff --git a/Wrapping/Python/PackageUtility/imagefiles/imagefiles/cmd.sh b/Wrapping/Python/PackageUtility/imagefiles/imagefiles/cmd.sh deleted file mode 100755 index d876ad6cfc..0000000000 --- a/Wrapping/Python/PackageUtility/imagefiles/imagefiles/cmd.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh - -set -x - -export SRC_DIR="/tmp/mitk" -export BLD_DIR="/tmp/bin" -export OUT_DIR="/var/io" - -MITK_GIT_TAG=T24046-SwigBasedPythonWrapping - -PYTHON_VERSIONS=${PYTHON_VERSIONS:-$(ls /opt/python | sed -e 's/cp2[0-6][^ ]\+ \?//g')} - -NPROC=$(grep -c processor /proc/cpuinfo) -export MAKEFLAGS="-j ${NPROC}" - - -function build_mitk { - - echo "MITK_GIT_TAG: ${MITK_GIT_TAG}" - - git clone https://phabricator.mitk.org/source/mitk.git ${SRC_DIR} && - (cd ${SRC_DIR} && git checkout ${MITK_GIT_TAG} ) && - rm -rf ${BLD_DIR} && - mkdir -p ${BLD_DIR} && cd ${BLD_DIR} && - cmake \ - -DBUILD_TESTING:BOOL=OFF \ - -DMITK_USE_SWIG:BOOL=ON \ - -DMITK_USE_Qt5:BOOL=OFF \ - -DMITK_USE_CTK:BOOL=OFF \ - -DMITK_USE_BLUEBERRY:BOOL=OFF \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/local/bin/gcc \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/local/bin/g++ \ - -DMITK_WHITELIST:STRING=Wrapping \ - -DCMAKE_BUILD_TYPE:STRING=Release \ - ${SRC_DIR} && - make -j8 -} - -function build_mitk_python { - - PYTHON_EXECUTABLE=/opt/python/${PYTHON}/bin/python - PYTHON_INCLUDE_DIR="$( find -L /opt/python/${PYTHON}/include/ -name Python.h -exec dirname {} \; )" - - echo "" - echo "PYTHON_EXECUTABLE:${PYTHON_EXECUTABLE}" - echo "PYTHON_INCLUDE_DIR:${PYTHON_INCLUDE_DIR}" - echo "PYTHON_LIBRARY:${PYTHON_LIBRARY}" - - cd ${BLD_DIR}/MITK-build && - cmake \ - -DWRAP_PYTHON:BOOL=ON \ - -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} \ - -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} \ - . - make dist -B -} - -build_mitk || exit 1 - - -for PYTHON in ${PYTHON_VERSIONS}; do - build_mitk_python && - auditwheel repair $(find ${BLD_DIR}/MITK-build/Wrapping/Python/dist -name pyMITK*.whl) -w ${OUT_DIR}/wheelhouse/ - rm $(find ${BLD_DIR}/MITK-build/Wrapping/Python/dist/ -name pyMITK*.whl) -done - diff --git a/Wrapping/Python/PackageUtility/imagefiles/install-gcc.sh b/Wrapping/Python/PackageUtility/imagefiles/install-gcc.sh deleted file mode 100755 index b36458f281..0000000000 --- a/Wrapping/Python/PackageUtility/imagefiles/install-gcc.sh +++ /dev/null @@ -1,680 +0,0 @@ -#!/bin/bash -# -# Date: 2015-09-29 -# -# This downloads, builds and installs the gcc-4.9.3 compiler and boost -# 1.58. It handles the dependent packages like gmp-6.0.0a, mpfr-3.1.3, -# mpc-1.0.2, ppl-1.1, cloog-0.18.0 and binutils-2.24. -# -# To install gcc-4.9.3 in ~/tmp/gcc-4.9.3/rtf/bin you would run this -# script as follows: -# -# % # Install in ~/tmp/gcc-4.9.3/rtf/bin -# % bld.sh ~/tmp/gcc-4.9.3 2>&1 | tee bld.log -# -# If you do not specify a directory, then it will install in the -# current directory which means that following command will also -# install in ~/tmp/gcc-4.9.3/rtf/bin: -# -# % # Install in ~/tmp/gcc-4.9.3/rtf/bin -# % mkdir -p ~/tmp/gcc-4.9.3 -# % cd ~/tmp/gcc-4.9.3 -# % bld.sh 2>&1 | tee bld.log -# -# This script creates 4 subdirectories: -# -# Directory Description -# ========= ================================================== -# archives This is where the package archives are downloaded. -# src This is where the package source is located. -# bld This is where the packages are built from source. -# rtf This is where the packages are installed. -# -# When the build is complete you can safely remove the archives, bld -# and src directory trees to save disk space. -# -# Copyright (C) 2014 Joe Linoff -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, sublicense, and/or sell copies of the Software, -# and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# ================================================================ -# Trim a string, remove internal spaces, convert to lower case. -# ================================================================ -function get-platform-trim { - local s=$(echo "$1" | tr -d '[ \t]' | tr 'A-Z' 'a-z') - echo $s -} - -# ================================================================ -# Get the platform root name. -# ================================================================ -function get-platform-root -{ - if which uname >/dev/null 2>&1 ; then - # Greg Moeller reported that the original code didn't - # work because the -o option is not available on solaris. - # I modified the script to correctly identify that - # case and recover by using the -s option. - if uname -o >/dev/null 2>&1 ; then - # Linux distro - uname -o | tr 'A-Z' 'a-z' - elif uname -s >/dev/null 2>&1 ; then - # Solaris variant - uname -s | tr 'A-Z' 'a-z' - else - echo "unkown" - fi - else - echo "unkown" - fi -} - -# ================================================================ -# Get the platform identifier. -# -# The format of the output is: -# --- -# ^ ^ ^ ^ -# | | | +----- architecture: x86_64, i86pc, etc. -# | | +----------- version: 5.5, 6.4, 10.9, etc. -# | +------------------ distribution: centos, rhel, nexenta, darwin -# +------------------------- platform: linux, sunos, macos -# -# ================================================================ -function get-platform -{ - local plat=$(get-platform-root) - case "$plat" in - "gnu/linux") - d=$(get-platform-trim "$(lsb_release -i)" | awk -F: '{print $2;}') - r=$(get-platform-trim "$(lsb_release -r)" | awk -F: '{print $2;}') - m=$(get-platform-trim "$(uname -m)") - if [[ "$d" == "redhatenterprise"* ]] ; then - # Need a little help for Red Hat because - # they don't make the minor version obvious. - d="rhel_${d:16}" # keep the tail (e.g., es or client) - x=$(get-platform-trim "$(lsb_release -c)" | \ - awk -F: '{print $2;}' | \ - sed -e 's/[^0-9]//g') - r="$r.$x" - fi - echo "linux-$d-$r-$m" - ;; - "cygwin") - x=$(get-platform-trim "$(uname)") - echo "linux-$x" - ;; - "sunos") - d=$(get-platform-trim "$(uname -v)") - r=$(get-platform-trim "$(uname -r)") - m=$(get-platform-trim "$(uname -m)") - echo "sunos-$d-$r-$m" - ;; - "darwin") - d=$(get-platform-trim "$(uname -s)") - r=$(get-platform-trim "$(uname -r)") - m=$(get-platform-trim "$(uname -m)") - echo "macos-$d-$r-$m" - ;; - "unknown") - echo "unk-unk-unk-unk" - ;; - *) - echo "$plat-unk-unk-unk" - ;; - esac -} - -# ================================================================ -# Command header -# Usage : docmd_hdr $ar $* -# Example: docmd_hdr $ar -# ================================================================ -function docmd_hdr { - local ar=$1 - shift - local cmd=($*) - echo - echo " # ================================================================" - if [[ "$ar" != "" ]] ; then - echo " # Archive: $ar" - fi - echo " # PWD: "$(pwd) - echo " # CMD: "${cmd[@]} - echo " # ================================================================" -} - -# ================================================================ -# Execute command with decorations and status testing. -# Usage : docmd $ar -# Example: docmd $ar ls -l -# ================================================================ -function docmd { - docmd_hdr $* - shift - local cmd=($*) - ${cmd[@]} - local st=$? - echo "STATUS = $st" - if (( $st != 0 )) ; then - exit $st; - fi -} - -# ================================================================ -# Report an error and exit. -# Usage : doerr [ .. ] -# Example: doerr "line 1 msg" -# Example: doerr "line 1 msg" "line 2 msg" -# ================================================================ -function doerr { - local prefix="ERROR: " - for ln in "$@" ; do - echo "${prefix}${ln}" - prefix=" " - done - exit 1 -} - -# ================================================================ -# Extract archive information. -# Usage : ard=( $(extract-ar-info $ar) ) -# Example: ard=( $(extract-ar-info $ar) ) -# fn=${ard[1]} -# ext=${ard[2]} -# d=${ard[3]} -# ================================================================ -function extract-ar-info { - local ar=$1 - local fn=$(basename $ar) - local ext=$(echo $fn | awk -F. '{print $NF}') - local d=${fn%.*tar.$ext} - echo $ar - echo $fn - echo $ext - echo $d -} - -# ================================================================ -# Print a banner for a new section. -# Usage : banner STEP $ar -# Example: banner "DOWNLOAD" $ar -# Example: banner "BUILD" $ar -# ================================================================ -function banner { - local step=$1 - local ard=( $(extract-ar-info $2) ) - local ar=${ard[0]} - local fn=${ard[1]} - local ext=${ard[2]} - local d=${ard[3]} - echo - echo '# ================================================================' - echo "# Step : $step" - echo "# Archive: $ar" - echo "# File : $fn" - echo "# Ext : $ext" - echo "# Dir : $d" - echo '# ================================================================' -} - -# ================================================================ -# Make a set of directories -# Usage : mkdirs [ .. ] -# Example: mkdirs foo bar spam spam/foo/bar -# ================================================================ -function mkdirs { - local ds=($*) - #echo "mkdirs" - for d in ${ds[@]} ; do - #echo " testing $d" - if [ ! -d $d ] ; then - #echo " creating $d" - mkdir -p $d - fi - done -} - -# ================================================================ -# Check the current platform to see if it is in the tested list, -# if it isn't, then issue a warning. -# It doesn't work on CentOS 5.x. -# It doesn't work on Mac OS X 10.9 (Maverick) but is close. -# ================================================================ -function check-platform -{ - local plat=$(get-platform) - local tested_plats=( - 'linux-centos-6.4-x86_64') - local plat_found=0 - - echo "PLATFORM: $plat" - for tested_plat in ${tested_plats[@]} ; do - if [[ "$plat" == "$tested_plat" ]] ; then - plat_found=1 - break - fi - done - if (( $plat_found == 0 )) ; then - echo "WARNING: This platform ($plat) has not been tested." - fi -} - -# ================================================================ -# my-readlink -# Some platforms (like darwin) do not support "readlink -f". -# This function checks to see if readlink -f is available, -# if it isn't then it uses a more POSIX compliant approach. -# ================================================================ -function my-readlink -{ - # First make sure that the command works. - readlink -f "$1" 1>/dev/null 2>/dev/null - local st=$? - if (( $st )) ; then - # If readlink didn't work then this may be a platform - # like Mac OS X. - local abspath="$(cd $(dirname .); pwd)" - else - local abspath=$(readlink -f "$1" 2>/dev/null) - fi - echo "$abspath" -} - -# ================================================================ -# DATA -# ================================================================ -# List of archives -# The order is important. -ARS=( - http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz - https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 - http://www.mpfr.org/mpfr-current/mpfr-3.1.3.tar.bz2 - http://www.multiprecision.org/mpc/download/mpc-1.0.2.tar.gz - http://bugseng.com/products/ppl/download/ftp/releases/1.1/ppl-1.1.tar.bz2 - http://www.bastoul.net/cloog/pages/download/cloog-0.18.1.tar.gz - http://ftp.gnu.org/gnu/gcc/gcc-4.9.4/gcc-4.9.4.tar.bz2 - http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2 - #http://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.bz2 - # - # Why glibc is disabled (for now). - # - # glibc does not work on CentOS because the versions of the shared - # libraries we are building are not compatiable with installed - # shared libraries. - # - # This is the run-time error: ELF file OS ABI invalid that I see - # when I try to run binaries compiled with the local glibc-2.15. - # - # Note that the oldest supported ABI for glibc-2.15 is 2.2. The - # CentOS 5.5 ABI is 0. - # http://ftp.gnu.org/gnu/glibc/glibc-2.15.tar.bz2 -) - -# ================================================================ -# MAIN -# ================================================================ -umask 0 - -check-platform - -# Read the command line argument, if it exists. -ROOTDIR=$(my-readlink .) -if (( $# == 1 )) ; then - ROOTDIR=$(my-readlink $1) -elif (( $# > 1 )) ; then - doerr "too many command line arguments ($#), only zero or one is allowed" "foo" -fi - -# Setup the directories. -ARDIR="/tmp/archives" -RTFDIR="$ROOTDIR" -SRCDIR="/tmp/src" -BLDDIR="/tmp/bld" -TSTDIR="/tmp/LOCAL-TEST" - -export PATH="${RTFDIR}/bin:${PATH}" -export LD_LIBRARY_PATH="${RTFDIR}/lib:${RTFDIR}/lib64:${LD_LIBRARY_PATH}" - -echo -echo "# ================================================================" -echo '# Version : gcc-4.9.3 2015-08-15' -echo "# RootDir : $ROOTDIR" -echo "# ArchiveDir : $ARDIR" -echo "# RtfDir : $RTFDIR" -echo "# SrcDir : $SRCDIR" -echo "# BldDir : $BLDDIR" -echo "# TstDir : $TSTDIR" -echo "# Gcc : "$(which gcc) -echo "# GccVersion : "$(gcc --version | head -1) -echo "# Hostname : "$(hostname) -echo "# O/S : "$(uname -s -r -v -m) -echo "# Date : "$(date) -echo "# Platform : "$(get-platform) -echo "# ================================================================" - -mkdirs $ARDIR $RTFDIR $SRCDIR $BLDDIR - -# ================================================================ -# Download -# ================================================================ -#for ar in ${ARS[@]} ; do -# banner 'DOWNLOAD' $ar -# ard=( $(extract-ar-info $ar) ) -# fn=${ard[1]} -# ext=${ard[2]} -# d=${ard[3]} -# if [ -f "${ARDIR}/$fn" ] ; then -# echo "skipping $fn" -# else -# # get -# docmd $ar wget $ar -O "${ARDIR}/$fn" -# fi -#done - -# ================================================================ -# Extract -# ================================================================ -for ar in ${ARS[@]} ; do - banner 'EXTRACT' $ar - ard=( $(extract-ar-info $ar) ) - fn=${ard[1]} - ext=${ard[2]} - d=${ard[3]} - sd="$SRCDIR/$d" - if [ -d $sd ] ; then - echo "skipping $fn" - else - # unpack - pushd $SRCDIR - case "$ext" in - "bz2") - docmd $ar tar jxf ${ARDIR}/$fn - ;; - "gz") - docmd $ar tar zxf ${ARDIR}/$fn - ;; - "tar") - docmd $ar tar xf ${ARDIR}/$fn - ;; - *) - doerr "unrecognized extension: $ext" "Can't continue." - ;; - esac - popd - if [ ! -d $sd ] ; then - # Some archives (like gcc-g++) overlay. We create a dummy - # directory to avoid extracting them every time. - mkdir -p $sd - fi - fi - - # special hack for gmp-6.0.0a - if [[ $d == "gmp-6.0.0a" ]] ; then - if [ ! -f $sd/configure ] ; then - sdn="$SRCDIR/gmp-6.0.0" - echo "fixing $sdn --> $sd" - docmd $sd rm -rf $sd - docmd $sd ln -s $sdn $sd - fi - fi -done - -# ================================================================ -# Build -# ================================================================ -for ar in ${ARS[@]} ; do - banner 'BUILD' $ar - ard=( $(extract-ar-info $ar) ) - fn=${ard[1]} - ext=${ard[2]} - d=${ard[3]} - sd="$SRCDIR/$d" - bd="$BLDDIR/$d" - if [ -d $bd ] ; then - echo "skipping $sd" - else - # Build - regex='^gcc-g\+\+.*' - if [[ $fn =~ $regex ]] ; then - # Don't build/configure the gcc-g++ package explicitly because - # it is part of the regular gcc package. - echo "skipping $sd" - # Dummy - continue - fi - - # Set the CONF_ARGS - plat=$(get-platform) - run_conf=1 - run_boost_bootstrap=0 - case "$d" in - binutils-*) - # Binutils will not compile with strict error - # checking on so I disabled -Werror by setting - # --disable-werror. - CONF_ARGS=( - --disable-cloog-version-check - --disable-ppl-version-check - --disable-werror - --enable-cloog-backend=isl - --enable-lto - --enable-libssp - --enable-gold - --prefix=${RTFDIR} - --with-cloog=${RTFDIR} - --with-gmp=${RTFDIR} - --with-mlgmp=${RTFDIR} - --with-mpc=${RTFDIR} - --with-mpfr=${RTFDIR} - --with-ppl=${RTFDIR} - CC=${RTFDIR}/bin/gcc - CXX=${RTFDIR}/bin/g++ - ) - ;; - - boost_*) - # The boost configuration scheme requires - # that the build occur in the source directory. - run_conf=0 - run_boost_bootstrap=1 - CONF_ARGS=( - --prefix=${RTFDIR} - --with-python=python2.7 - ) - ;; - - cloog-*) - GMPDIR=$(ls -1d ${BLDDIR}/gmp-*) - CONF_ARGS=( - --prefix=${RTFDIR} - --with-gmp-builddir=${GMPDIR} - --with-gmp=build - ) - ;; - - gcc-*) - # We are using a newer version of CLooG (0.18.0). - # I have also made stack protection available - # (similar to DEP in windows). - CONF_ARGS=( - --disable-cloog-version-check - --disable-ppl-version-check - --enable-cloog-backend=isl - --enable-gold - --enable-languages='c,c++' - --enable-lto - --enable-libssp - --prefix=${RTFDIR} - --with-cloog=${RTFDIR} - --with-gmp=${RTFDIR} - --with-mlgmp=${RTFDIR} - --with-mpc=${RTFDIR} - --with-mpfr=${RTFDIR} - --with-ppl=${RTFDIR} - ) - - macplats=("macos-darwin-13.0.0-x86_64" "macos-darwin-13.1.0-x86_64") - for macplat in ${macplats[@]} ; do - if [[ "$plat" == "$macplat" ]] ; then - # Special handling for Mac OS X 10.9. - # Fix the bad reference to CFBase.h in - # src/gcc-4.9.3/libsanitizer/asan/asan_malloc_mac.cc - src="$sd/libsanitizer/asan/asan_malloc_mac.cc" - if [ -f $src ] ; then - if [ ! -f $src.orig ] ; then - cp $src $src.orig - cat $src.orig |\ - sed -e 's@#include @//#include @' >$src - fi - fi - fi - done - ;; - - glibc-*) - CONF_ARGS=( - --enable-static-nss=no - --prefix=${RTFDIR} - --with-binutils=${RTFDIR} - --with-elf - CC=${RTFDIR}/bin/gcc - CXX=${RTFDIR}/bin/g++ - ) - ;; - - gmp-*) - CONF_ARGS=( - --enable-cxx - --prefix=${RTFDIR} - ) - if [[ "$plat" == "linux-cygwin_nt-6.1-wow64" ]] ; then - CONF_ARGS+=('--enable-static') - CONF_ARGS+=('--disable-shared') - fi - ;; - - libiconv-*) - CONF_ARGS=( - --prefix=${RTFDIR} - ) - ;; - - mpc-*) - CONF_ARGS=( - --prefix=${RTFDIR} - --with-gmp=${RTFDIR} - --with-mpfr=${RTFDIR} - ) - if [[ "$plat" == "linux-cygwin_nt-6.1-wow64" ]] ; then - CONF_ARGS+=('--enable-static') - CONF_ARGS+=('--disable-shared') - fi - ;; - - mpfr-*) - CONF_ARGS=( - --prefix=${RTFDIR} - --with-gmp=${RTFDIR} - ) - ;; - - ppl-*) - CONF_ARGS=( - --prefix=${RTFDIR} - --with-gmp=${RTFDIR} - ) - if [[ "$plat" == "linux-cygwin_nt-6.1-wow64" ]] ; then - # Cygwin does not implement long double so I cheated. - CONF_ARGS+=('--enable-static') - CONF_ARGS+=('--disable-shared') - fi - - # We need a special fix for the pax archive prompt. - # Change the configure code. - if [ ! -f "$sd/configure.orig" ] ; then - # Fix the configure code so that it does not use 'pax -r'. - # The problem with 'pax -r' is that it expects a "." input - # from stdin which breaks the flow. - cp $sd/configure{,.orig} - sed -e "s/am__untar='pax -r'/am__untar='tar -xf' #am__untar='pax -r'/" \ - $sd/configure.orig >$sd/configure - fi - - # We need to make a special fix here - src="$sd/src/mp_std_bits.defs.hh" - if [ -f $src ] ; then - if [ ! -f $src.orig ] ; then - if ! grep -q '__GNU_MP_VERSION' $src ; then - cp $src $src.orig - cat $src.orig | \ - awk \ -'{ \ - if($1=="namespace" && $2 == "std") { \ - printf("// Automatically patched by bld.sh for gcc-4.9.3.\n"); \ - printf("#define tininess_before tinyness_before\n"); \ - printf("#if __GNU_MP_VERSION < 5 || (__GNU_MP_VERSION == 5 && __GNU_MP_VERSION_MINOR < 1)\n"); - } \ - print $0; \ - if($1 == "}" && $2=="//" && $3=="namespace") { \ - printf("#endif // #if __GNU_MP_VERSION < 5 || (__GNU_MP_VERSION == 5 && __GNU_MP_VERSION_MINOR < 1)\n"); - } \ -}' >$src - fi - fi - fi - ;; - - *) - doerr "unrecognized package: $d" - ;; - esac - - mkdir -p $bd - pushd $bd - if (( $run_conf )) ; then - docmd $ar $sd/configure --help - docmd $ar $sd/configure ${CONF_ARGS[@]} - docmd $ar make - docmd $ar make install - fi - if (( $run_boost_bootstrap )) ; then - pushd $sd - docmd $ar which g++ - docmd $ar gcc --version - docmd $ar $sd/bootstrap.sh --help - docmd $ar $sd/bootstrap.sh ${CONF_ARGS[@]} - docmd $ar ./b2 --help - docmd $ar ./b2 --clean - docmd $ar ./b2 --reconfigure - docmd $ar ./b2 -a -d+2 --build-dir $bd - docmd $ar ./b2 -d+2 --build-dir $bd install - docmd $ar ./b2 install - popd - fi - - # Redo the tests if anything changed. - if [ -d $TSTDIR ] ; then - rm -rf $TSTDIR - fi - popd - fi -done diff --git a/Wrapping/Python/PackageUtility/imagefiles/install-libtiff.sh b/Wrapping/Python/PackageUtility/imagefiles/install-libtiff.sh deleted file mode 100755 index efd0520a98..0000000000 --- a/Wrapping/Python/PackageUtility/imagefiles/install-libtiff.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -cd /tmp/archive -tar -xzf tiff-4.0.9.tar.gz -C /tmp/ -cd /tmp/tiff-4.0.9 -./configure CC=/usr/local/bin/gcc CXX=/usr/local/bin/g++ -make -make install diff --git a/log.txt b/log.txt new file mode 100644 index 0000000000..e69de29bb2