diff --git a/CMake/FindEigen.cmake b/CMake/FindEigen.cmake deleted file mode 100644 index 2ec430484c..0000000000 --- a/CMake/FindEigen.cmake +++ /dev/null @@ -1,16 +0,0 @@ -find_path(Eigen_INCLUDE_DIR - NAMES Eigen/Eigen - PATHS ${Eigen_DIR} ${MITK_EXTERNAL_PROJECT_PREFIX} ${CMAKE_PREFIX_PATH} - PATH_SUFFIXES include include/eigen3 -) - -if (NOT TARGET Eigen) - add_library(Eigen INTERFACE IMPORTED GLOBAL) - set_property(TARGET Eigen APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Eigen_INCLUDE_DIR}) -endif() - -find_package_handle_standard_args(Eigen - FOUND_VAR Eigen_FOUND - REQUIRED_VARS Eigen_INCLUDE_DIR -) - diff --git a/CMake/PackageDepends/MITK_Eigen_Config.cmake b/CMake/PackageDepends/MITK_Eigen_Config.cmake deleted file mode 100644 index c4a7aba4ab..0000000000 --- a/CMake/PackageDepends/MITK_Eigen_Config.cmake +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND ALL_LIBRARIES Eigen) - diff --git a/CMakeExternals/Eigen.cmake b/CMakeExternals/Eigen.cmake deleted file mode 100644 index eb734a01b6..0000000000 --- a/CMakeExternals/Eigen.cmake +++ /dev/null @@ -1,45 +0,0 @@ -#----------------------------------------------------------------------------- -# Eigen -#----------------------------------------------------------------------------- - -if(MITK_USE_Eigen) - - # Sanity checks - if(DEFINED Eigen_DIR AND NOT EXISTS ${Eigen_DIR}) - message(FATAL_ERROR "Eigen_DIR variable is defined but corresponds to non-existing directory") - endif() - - set(proj Eigen) - set(proj_DEPENDENCIES Boost) - set(Eigen_DEPENDS ${proj}) - - if(NOT DEFINED Eigen_DIR) - - ExternalProject_Add(${proj} - LIST_SEPARATOR ${sep} - GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git - GIT_TAG 3.4.0 - CMAKE_GENERATOR ${gen} - CMAKE_GENERATOR_PLATFORM ${gen_platform} - CMAKE_ARGS - ${ep_common_args} - "-DBoost_DIR:PATH=${Boost_DIR}" - -DBUILD_TESTING:BOOL=ON - -DEIGEN_BUILD_PKGCONFIG:BOOL=OFF - CMAKE_CACHE_ARGS - ${ep_common_cache_args} - CMAKE_CACHE_DEFAULT_ARGS - ${ep_common_cache_default_args} - DEPENDS ${proj_DEPENDENCIES} - ) - - set(Eigen_DIR ${ep_prefix}) - mitkFunctionInstallExternalCMakeProject(${proj}) - - else() - - mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") - - endif() - -endif() diff --git a/CMakeExternals/ExternalProjectList.cmake b/CMakeExternals/ExternalProjectList.cmake index cdccff2a8d..0ce05a09a6 100644 --- a/CMakeExternals/ExternalProjectList.cmake +++ b/CMakeExternals/ExternalProjectList.cmake @@ -1,30 +1,29 @@ mitkFunctionAddExternalProject(NAME Poco ON COMPONENTS Foundation Net Util XML Zip) mitkFunctionAddExternalProject(NAME DCMTK ON DOC "EXPERIMENTAL, superbuild only: Use DCMTK in MITK") mitkFunctionAddExternalProject(NAME tinyxml2 ON ADVANCED) mitkFunctionAddExternalProject(NAME GDCM ON ADVANCED) mitkFunctionAddExternalProject(NAME Boost ON NO_CACHE) -mitkFunctionAddExternalProject(NAME Eigen ON DEPENDS Boost ADVANCED DOC "Use the Eigen library") mitkFunctionAddExternalProject(NAME ANN ON ADVANCED DOC "Use Approximate Nearest Neighbor Library") mitkFunctionAddExternalProject(NAME CppUnit ON ADVANCED DOC "Use CppUnit for unit tests") mitkFunctionAddExternalProject(NAME HDF5 ON ADVANCED) mitkFunctionAddExternalProject(NAME ITK ON NO_CACHE DEPENDS HDF5) mitkFunctionAddExternalProject(NAME VTK ON NO_CACHE) mitkFunctionAddExternalProject(NAME ZLIB OFF ADVANCED) mitkFunctionAddExternalProject(NAME lz4 ON ADVANCED) mitkFunctionAddExternalProject(NAME cpprestsdk OFF DEPENDS Boost ZLIB ADVANCED) mitkFunctionAddExternalProject(NAME ACVD OFF DOC "Use Approximated Centroidal Voronoi Diagrams") mitkFunctionAddExternalProject(NAME CTK ON DEPENDS Qt6 DCMTK DOC "Use CTK in MITK") mitkFunctionAddExternalProject(NAME DCMQI ON DEPENDS DCMTK ITK DOC "Use dcmqi in MITK") mitkFunctionAddExternalProject(NAME MatchPoint OFF ADVANCED DEPENDS Boost ITK DOC "Use the MatchPoint translation image registration library") mitkFunctionAddExternalProject(NAME nlohmann_json ON ADVANCED) if(MITK_USE_Qt6) mitkFunctionAddExternalProject(NAME Qt6Qwt6 ON ADVANCED DEPENDS Qt6) endif() if(UNIX AND NOT APPLE) mitkFunctionAddExternalProject(NAME PCRE OFF ADVANCED NO_PACKAGE) mitkFunctionAddExternalProject(NAME SWIG OFF ADVANCED NO_PACKAGE DEPENDS PCRE) elseif(WIN32) mitkFunctionAddExternalProject(NAME SWIG OFF ADVANCED NO_PACKAGE) endif() diff --git a/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/ThirdPartyLibs.dox b/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/ThirdPartyLibs.dox index 599bd44375..1a2190b2e0 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/ThirdPartyLibs.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Starting/SettingUpMITK/ThirdPartyLibs.dox @@ -1,99 +1,95 @@ /** \page thirdpartylibs Third-party libraries The following third-party libraries can be used with MITK by default and can, in part, be automatically downloaded during superbuild. \par ACVD https://www.creatis.insa-lyon.fr/~valette/public/project/acvd/ \par ANN https://www.cs.umd.edu/~mount/ANN/ \par Boost https://www.boost.org/ \par C++ REST SDK https://github.com/Microsoft/cpprestsdk/ \par CppUnit https://sourceforge.net/projects/cppunit/ \par CTK https://commontk.org/ \par DCMTK https://dicom.offis.de/dcmtk -\par Eigen - -https://eigen.tuxfamily.org/index.php?title=Main_Page - \par GDCM https://gdcm.sourceforge.net/ \par HDF5 https://support.hdfgroup.org/HDF5/ \par ITK https://itk.org/ \par JSON for Modern C++ https://github.com/nlohmann/json \par lz4 https://github.com/lz4/lz4 \par MatchPoint https://www.dkfz.de/en/sidt/projects/MatchPoint/info.html \par PCRE https://www.pcre.org/ \par POCO https://pocoproject.org/ \par Python https://www.python.org/ \par Qt https://www.qt.io/ \par Qwt https://qwt.sourceforge.io/ \par SWIG https://www.swig.org/ \par TinyXML-2 https://www.grinninglizard.com/tinyxml2/ \par VTK https://vtk.org/ \par zlib https://zlib.net/ For copyright information on any of the above toolkits see the corresponding home page or the corresponding source folder. */ diff --git a/Modules/Classification/CLCore/CMakeLists.txt b/Modules/Classification/CLCore/CMakeLists.txt index cdcd91eb6f..0dd8fad85e 100644 --- a/Modules/Classification/CLCore/CMakeLists.txt +++ b/Modules/Classification/CLCore/CMakeLists.txt @@ -1,5 +1,4 @@ MITK_CREATE_MODULE( DEPENDS MitkCore MitkCommandLine - PACKAGE_DEPENDS - PUBLIC Eigen + PACKAGE_DEPENDS PUBLIC ITK|ITKEigen3 ) diff --git a/Modules/Classification/CLCore/include/mitkAbstractClassifier.h b/Modules/Classification/CLCore/include/mitkAbstractClassifier.h index 40c55a9ceb..ff976df587 100644 --- a/Modules/Classification/CLCore/include/mitkAbstractClassifier.h +++ b/Modules/Classification/CLCore/include/mitkAbstractClassifier.h @@ -1,195 +1,195 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkAbstractClassifier_h #define mitkAbstractClassifier_h #include #include // Eigen -#include +#include // STD Includes // MITK includes #include namespace mitk { class MITKCLCORE_EXPORT AbstractClassifier : public BaseData { public: mitkClassMacro(AbstractClassifier,BaseData); /// /// @brief Build a forest of trees from the training set (X, y). /// @param X The training input samples. Matrix of shape = [n_samples, n_features] /// @param Y The target values (class labels in classification, real numbers in regression). Matrix of shape = [n_samples, 1] /// virtual void Train(const Eigen::MatrixXd &X, const Eigen::MatrixXi &Y) = 0; /// /// @brief Predict class for X. /// @param X The input samples. /// @return The predicted classes. Y matrix of shape = [n_samples, 1] /// virtual Eigen::MatrixXi Predict(const Eigen::MatrixXd &X) = 0; /// /// @brief GetPointWiseWeightCopy /// @return return label matrix of shape = [n_samples , 1] /// Eigen::MatrixXi & GetLabels() { return m_OutLabel; } protected: Eigen::MatrixXi m_OutLabel; public: // * --------------- * // PointWiseWeight // * --------------- * /// /// @brief SupportsPointWiseWeight /// @return True if the classifier supports pointwise weighting else false /// virtual bool SupportsPointWiseWeight() = 0; /// /// @brief GetPointWiseWeightCopy /// @return Create and return a copy of W /// virtual Eigen::MatrixXd & GetPointWiseWeight() { return m_PointWiseWeight; } /// /// @brief SetPointWiseWeight /// @param W The pointwise weights. W matrix of shape = [n_samples, 1] /// virtual void SetPointWiseWeight(const Eigen::MatrixXd& W) { this->m_PointWiseWeight = W; } /// /// @brief UsePointWiseWeight /// @param value weighting on/off /// virtual void UsePointWiseWeight(bool value) { this->m_IsUsingPointWiseWeight = value; } /// /// @brief IsUsingPointWiseWeight /// @return true if pointewise weighting is enabled. /// virtual bool IsUsingPointWiseWeight() { return this->m_IsUsingPointWiseWeight; } protected: Eigen::MatrixXd m_PointWiseWeight; bool m_IsUsingPointWiseWeight; // * --------------- * // PointWiseProbabilities // * --------------- * public: /// /// @brief SupportsPointWiseProbability /// @return True if the classifier supports pointwise class probability calculation else false /// virtual bool SupportsPointWiseProbability() = 0; /// /// @brief GetPointWiseWeightCopy /// @return return probability matrix /// virtual Eigen::MatrixXd & GetPointWiseProbabilities() { return m_OutProbability; } /// /// \brief UsePointWiseProbabilities /// \param value /// virtual void UsePointWiseProbability(bool value) { m_IsUsingPointWiseProbability = value; } /// /// \brief IsUsingPointWiseProbabilities /// \return /// virtual bool IsUsingPointWiseProbability() { return m_IsUsingPointWiseProbability; } protected: Eigen::MatrixXd m_OutProbability; bool m_IsUsingPointWiseProbability; private: void MethodForBuild(); public: void SetNthItems(const char *val, unsigned int idx); std::string GetNthItems(unsigned int idx) const; void SetItemList(std::vector); std::vector GetItemList() const; #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; } #endif // Skip Doxygen }; } #endif diff --git a/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h b/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h index a1e36bc404..623d79c799 100644 --- a/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h +++ b/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h @@ -1,342 +1,342 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkAbstractGlobalImageFeature_h #define mitkAbstractGlobalImageFeature_h #include #include #include #include #include // STD Includes // Eigen -#include +#include // MITK includes #include namespace mitk { /**Used as ID for features calculated by feature classes*/ struct MITKCLCORE_EXPORT FeatureID { /**Name of the feature*/ std::string name; /**Name of the feature class*/ std::string featureClass; /**ID for the setting that is represented by parameters and is specified by the feature class while calculating the features. It must be as unique as the parameters themself.*/ std::string settingID; /**Alternative name that containes the legacy naming of the feature that encodes the parametersetting directly in the string.*/ std::string legacyName; /**Version of the feature definition*/ std::string version = "1"; using ParametersType = std::map; ParametersType parameters; bool operator < (const FeatureID& rh) const; bool operator ==(const FeatureID& rh) const; }; /**Helper that takes a pass templateID clones it and populates it with the also passed informations befor returning it. * @param templateID reference ID that should be cloned. * @param name Name of the feature.*/ MITKCLCORE_EXPORT FeatureID CreateFeatureID(FeatureID templateID, std::string name); /** * * * ## 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.) * * ### 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; using ParametersType = FeatureID::ParametersType; /** * \brief Calculates the feature of this abstact interface. Does not necessarily considers the parameter settings. */ FeatureListType CalculateFeatures(const Image* image, const Image* mask); virtual FeatureListType CalculateFeatures(const Image* image, const Image* mask, const Image* maskNoNAN) = 0; /** * \brief Calculates the given feature Slice-wise. Might not be availble for an individual filter! */ FeatureListType CalculateFeaturesSlicewise(const Image::Pointer & image, const Image::Pointer &mask, int sliceID); /** * \brief Calculates the feature of this abstact interface. Does not necessarily considers the parameter settings. */ virtual void CalculateAndAppendFeaturesSliceWise(const Image::Pointer & image, const Image::Pointer &mask, int sliceID, FeatureListType &featureList, bool checkParameterActivation = true); /** * \brief Calculates the feature of this abstact interface. Does not necessarily considers the parameter settings. * @param image * @param mask * @param maskNoNaN * @param featureList * @param checkParameterActivation Indicates if the features should only be calculated and added if the FeatureClass is activated in the parameters. * True: only append if activated in the parametes. False: always and append it. */ void CalculateAndAppendFeatures(const Image* image, const Image* mask, const Image* maskNoNaN, FeatureListType &featureList, bool checkParameterActivation = true); itkSetMacro(Prefix, std::string); itkSetMacro(ShortName, std::string); itkSetMacro(LongName, std::string); itkSetMacro(FeatureClassName, std::string); itkSetMacro(Direction, int); void SetParameters(ParametersType param) { m_Parameters = param; this->ConfigureQuantifierSettingsByParameters(); this->ConfigureSettingsByParameters(param); this->Modified(); }; itkGetConstMacro(Prefix, std::string); itkGetConstMacro(ShortName, std::string); itkGetConstMacro(LongName, std::string); itkGetConstMacro(FeatureClassName, std::string); itkGetConstMacro(Parameters, ParametersType); 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); itkSetMacro(Bins, int); itkSetMacro(UseBins, bool); itkGetConstMacro(UseBins, bool); itkGetConstMacro(Bins, int); itkSetMacro(IgnoreMask, bool); itkGetConstMacro(IgnoreMask, bool); itkSetMacro(EncodeParametersInFeaturePrefix, bool); itkGetConstMacro(EncodeParametersInFeaturePrefix, bool); itkBooleanMacro(EncodeParametersInFeaturePrefix); std::string GetOptionPrefix() const { if (!m_Prefix.empty()) return m_Prefix + "::" + m_ShortName; return m_ShortName; } /** Can be called to add all relevant argument for configuring the feature instance to the passed parser instance. Must be implemented be derived classes. For adding the quantifier arguments use AddQuantifierArguments(...) as helper function.*/ virtual void AddArguments(mitkCommandLineParser &parser) const = 0; /** Helper function that generates the legacy feature name without encoding of parameters; as it is used e.g. in the unit tests.*/ static std::string GenerateLegacyFeatureNameWOEncoding(const FeatureID& id); protected: std::vector SplitDouble(std::string str, char delimiter); virtual FeatureListType DoCalculateFeatures(const Image* image, const Image* mask) = 0; void AddQuantifierArguments(mitkCommandLineParser& parser) const; /** Ensures that all quantifier relevant variables of the instance are set correctly given the information in m_Parameters.*/ void ConfigureQuantifierSettingsByParameters(); /** Ensures that the instance is configured according to the information given in the passed parameters. * This method will be called by SetParameters(...) after ConfigureQuantifierSettingsByParameters() was called.*/ virtual void ConfigureSettingsByParameters(const ParametersType& parameters); /**Initializes the quantifier gigen the quantifier relevant variables and the passed arguments.*/ void InitializeQuantifier(const Image* image, const Image* mask, unsigned int defaultBins = 256); /** Helper that encodes the quantifier parameters in a string (e.g. used for the legacy feature name)*/ std::string QuantifierParameterString() const; /* Creates a template feature id. * it will set the featureClass, the settingID (assuming that it is the featureClass with the passed suffix * and all parameters that are global or have the option prefix of the instance.*/ FeatureID CreateTemplateFeatureID(std::string settingsSuffix = "", FeatureID::ParametersType additionalParams = {}); /** Helper that generates the legacy feature names for a passed FeatureID. * Format of the legacy feature name is: \::[\::]\ * Overwrite GenerateLegacyFeatureNamePart and GenerateLegacyFeatureEncoding to change behavior in * derived classes. */ virtual std::string GenerateLegacyFeatureName(const FeatureID& id) const; virtual std::string GenerateLegacyFeatureNamePart(const FeatureID& id) const; virtual std::string GenerateLegacyFeatureEncoding(const FeatureID& id) const; 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; ParametersType m_Parameters; // Parameter setting mitk::Image::Pointer m_MorphMask = nullptr; IntensityQuantifier::Pointer m_Quantifier; //Quantifier relevant variables double m_MinimumIntensity = 0; bool m_UseMinimumIntensity = false; double m_MaximumIntensity = 100; bool m_UseMaximumIntensity = false; bool m_EncodeParametersInFeaturePrefix = 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; //#endif // Skip Doxygen }; } #endif diff --git a/Modules/Classification/CLMRUtilities/CMakeLists.txt b/Modules/Classification/CLMRUtilities/CMakeLists.txt index 6a56a7aedd..ea79076e36 100644 --- a/Modules/Classification/CLMRUtilities/CMakeLists.txt +++ b/Modules/Classification/CLMRUtilities/CMakeLists.txt @@ -1,4 +1,3 @@ MITK_CREATE_MODULE( DEPENDS MitkCore MitkCLCore - PACKAGE_DEPENDS PUBLIC Eigen ) diff --git a/Modules/Classification/CLUtilities/CMakeLists.txt b/Modules/Classification/CLUtilities/CMakeLists.txt index 577381576a..c7766e1cad 100644 --- a/Modules/Classification/CLUtilities/CMakeLists.txt +++ b/Modules/Classification/CLUtilities/CMakeLists.txt @@ -1,10 +1,10 @@ mitk_create_module( DEPENDS MitkCore MitkCLCore MitkCommandLine MitkDICOM - PACKAGE_DEPENDS PUBLIC Eigen OpenMP PRIVATE tinyxml2 ITK|MathematicalMorphology+Smoothing VTK|FiltersStatistics + PACKAGE_DEPENDS PUBLIC OpenMP PRIVATE tinyxml2 ITK|MathematicalMorphology+Smoothing VTK|FiltersStatistics ) if(TARGET ${MODULE_TARGET}) if(BUILD_TESTING) add_subdirectory(test) endif() endif() diff --git a/Modules/Classification/CLUtilities/include/mitkCLUtil.h b/Modules/Classification/CLUtilities/include/mitkCLUtil.h index 7241b2d4af..1ab2c82b5a 100644 --- a/Modules/Classification/CLUtilities/include/mitkCLUtil.h +++ b/Modules/Classification/CLUtilities/include/mitkCLUtil.h @@ -1,581 +1,581 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkCLUtil_h #define mitkCLUtil_h -#include +#include #include #include #include #include #include #include namespace mitk { class MITKCLUTILITIES_EXPORT CLUtil { public: /// /// \brief The MorphologicalDimensions enum /// enum MorphologicalDimensions { Axial,Coronal,Sagittal,All }; /// /// \brief CreateCheckerBoardPredictionMask /// \param image /// \param outimage /// static void CreateCheckerboardMask(mitk::Image::Pointer image, mitk::Image::Pointer & outimage); /// /// \brief InterpolateCreateCheckerboardPrediction /// \param checkerboard_prediction /// \param checkerboard_mask /// \param outimage /// static void InterpolateCheckerboardPrediction(mitk::Image::Pointer checkerboard_prediction, mitk::Image::Pointer & checkerboard_mask, mitk::Image::Pointer & outimage); /// /// \brief CountVoxel /// \param image /// \param map /// static void CountVoxel(mitk::Image::Pointer image, std::map & map); /// /// \brief CountVoxel /// \param image /// \param label /// \param count /// static void CountVoxel(mitk::Image::Pointer image, unsigned int label, unsigned int & count); /// /// \brief CountVoxel /// \param image /// \param count /// static void CountVoxel(mitk::Image::Pointer image, unsigned int & count); /// /// \brief SumVoxelForLabel /// \param image /// \param source /// \param label /// \param val /// static void SumVoxelForLabel(mitk::Image::Pointer image, const mitk::Image::Pointer & source , unsigned int label, double & val ); /// /// \brief SqSumVoxelForLabel /// \param image /// \param source /// \param label /// \param val /// static void SqSumVoxelForLabel(mitk::Image::Pointer image, const mitk::Image::Pointer & source, unsigned int label, double & val ); /// /// \brief LogicalAndImages /// \param image1 /// \param image2 /// \param outimage /// static void LogicalAndImages(const Image::Pointer &image1, const Image::Pointer &image2, Image::Pointer &outimage); /// /// \brief GaussianFilter /// \param image /// \param smoothed /// \param sigma /// static void GaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed ,double sigma); /// /// \brief SubtractGaussianFilter /// \param image /// \param smoothed (Result is sigma1-sigma2) /// \param sigma1 /// \param sigma2 /// static void DifferenceOfGaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed, double sigma1, double sigma2); /// /// \brief Laplacian of Gaussian /// \param image /// \param smoothed (Result is sigma1-sigma2) /// \param sigma1 /// static void LaplacianOfGaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed, double sigma1); /// /// \brief SubtractGaussianFilter /// \param image /// \param out /// \param sigma /// static void HessianOfGaussianFilter(mitk::Image::Pointer image, std::vector &out, double sigma); /// /// \brief Local Histogram /// \param image /// \param out /// \param Bins /// \param NeighbourhoodSize /// static void LocalHistogram(mitk::Image::Pointer image, std::vector &out, int Bins, int NeighbourhoodSize); /// /// \brief transform /// \param matrix /// \param mask /// template static mitk::Image::Pointer Transform(const Eigen::Matrix & matrix, const mitk::Image::Pointer & mask) { itk::Image::Pointer itkMask; mitk::CastToItkImage(mask,itkMask); typename itk::Image::Pointer itk_img = itk::Image::New(); itk_img->SetRegions(itkMask->GetLargestPossibleRegion()); itk_img->SetOrigin(itkMask->GetOrigin()); itk_img->SetSpacing(itkMask->GetSpacing()); itk_img->SetDirection(itkMask->GetDirection()); itk_img->Allocate(); unsigned int n_numSamples = 0; mitk::CLUtil::CountVoxel(mask,n_numSamples); if(n_numSamples != matrix.rows()) MITK_ERROR << "Number of samples in matrix and number of points under the masks is not the same!"; auto mit = itk::ImageRegionConstIterator >(itkMask, itkMask->GetLargestPossibleRegion()); auto oit = itk::ImageRegionIterator >(itk_img, itk_img->GetLargestPossibleRegion()); unsigned int current_row = 0; while(!mit.IsAtEnd()) { if(mit.Value() > 0) oit.Set(matrix(current_row++,0)); else oit.Set(0.0); ++mit; ++oit; } mitk::Image::Pointer out_img = mitk::Image::New(); mitk::GrabItkImageMemory(itk_img,out_img); return out_img; } /// /// \brief TransformImageToMatrix /// \param img /// \param mask /// template static Eigen::Matrix Transform(const mitk::Image::Pointer & img, const mitk::Image::Pointer & mask) { itk::Image::Pointer current_mask; mitk::CastToItkImage(mask,current_mask); unsigned int n_numSamples = 0; mitk::CLUtil::CountVoxel(mask,n_numSamples); typename itk::Image::Pointer current_img; mitk::CastToItkImage(img,current_img); Eigen::Matrix out_matrix(n_numSamples,1); auto mit = itk::ImageRegionConstIterator >(current_mask, current_mask->GetLargestPossibleRegion()); auto iit = itk::ImageRegionConstIterator >(current_img,current_img->GetLargestPossibleRegion()); unsigned int current_row = 0; while (!mit.IsAtEnd()) { if(mit.Value() > 0) out_matrix(current_row++) = iit.Value(); ++mit; ++iit; } return out_matrix; } /// /// \brief DilateBinary /// \param sourceImage /// \param resultImage /// \param radius Size of the StructuringElement /// \param d /// static void DilateBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int radius , MorphologicalDimensions d); /// /// \brief ErodeBinary /// \param sourceImage /// \param resultImage /// \param radius Size of the StructuringElement /// \param d /// static void ErodeBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int radius, MorphologicalDimensions d); /// /// \brief ClosingBinary /// \param sourceImage /// \param resultImage /// \param radius Size of the StructuringElement /// \param d /// static void ClosingBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int radius, MorphologicalDimensions d); /// /// \brief MergeLabels /// \param img /// \param map merge instruction where each map entry defines a mapping instruction. Key \c \ - Value \c \ /// static void MergeLabels(mitk::Image::Pointer & img, const std::map & map); /// /// \brief ConnectedComponentsImage /// \param image /// \param mask /// \param outimage /// \param num_components Number of components found in the image /// static void ConnectedComponentsImage(mitk::Image::Pointer & image, mitk::Image::Pointer& mask, mitk::Image::Pointer &outimage, unsigned int& num_components); /// /// \brief GrabLabel /// \param image /// \param outimage /// \param label /// static void GrabLabel(mitk::Image::Pointer & image, mitk::Image::Pointer & outimage, unsigned int label); /// /// \brief itkInsertLabel /// \param image /// \param maskImage /// \param label /// static void InsertLabel(mitk::Image::Pointer & image, mitk::Image::Pointer & maskImage, unsigned int label); /// /// \brief ErodeGrayscale /// \param image /// \param outimage /// \param radius /// \param d /// static void ErodeGrayscale(mitk::Image::Pointer & image, unsigned int radius, mitk::CLUtil::MorphologicalDimensions d, mitk::Image::Pointer & outimage ); /// /// \brief DilateGrayscale /// \param image /// \param outimage /// \param radius /// \param d /// static void DilateGrayscale(mitk::Image::Pointer & image, unsigned int radius, mitk::CLUtil::MorphologicalDimensions d, mitk::Image::Pointer & outimage ); /// /// \brief FillHoleGrayscale /// \param image /// \param outimage /// static void FillHoleGrayscale(mitk::Image::Pointer & image, mitk::Image::Pointer & outimage); /// /// \brief ProbabilityMap /// \param sourceImage /// \param mean /// \param std_dev /// \param resultImage /// static void ProbabilityMap(const mitk::Image::Pointer& sourceImage, double mean, double std_dev, mitk::Image::Pointer& resultImage); template static void itkCountVoxel( TImageType * image, std::map & map) { auto it = itk::ImageRegionIterator< TImageType >(image,image->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { if(map.find(it.Value()) == map.end()) map[it.Value()] = 0; map[it.Value()]++; ++it; } } template static void itkCountVoxel(TImageType* image, typename TImageType::PixelType label, unsigned int & count ) { itk::ImageRegionConstIterator inputIter(image, image->GetLargestPossibleRegion()); while(!inputIter.IsAtEnd()) { if(inputIter.Value() == label) ++count; ++inputIter; } } template static inline void itkCountVoxel(TImageType * mask, unsigned int & n_numSamples) { auto mit = itk::ImageRegionConstIterator(mask, mask->GetLargestPossibleRegion()); while (!mit.IsAtEnd()) { if(mit.Value() > 0) n_numSamples++; ++mit; } } template static void itkSampleLabel(TImageType1* image, TImageType2* output, double acceptrate, unsigned int label) { std::srand (time(nullptr)); itk::ImageRegionConstIterator< TImageType1 > inputIter(image, image->GetLargestPossibleRegion()); itk::ImageRegionIterator< TImageType2 > outputIter(output, output->GetLargestPossibleRegion()); while (!inputIter.IsAtEnd()) { double r = (double)(rand()) / RAND_MAX; if(inputIter.Get() == label && r < acceptrate) outputIter.Set(label); ++inputIter; ++outputIter; } } template static void itkSampleLabel(TImageType* image, mitk::Image::Pointer & output, unsigned int n_samples_drawn) { std::srand (time(nullptr)); typename TImageType::Pointer itk_out = TImageType::New(); itk_out->SetRegions(image->GetLargestPossibleRegion()); itk_out->SetDirection(image->GetDirection()); itk_out->SetOrigin(image->GetOrigin()); itk_out->SetSpacing(image->GetSpacing()); itk_out->Allocate(); itk_out->FillBuffer(0); itk::ImageRegionConstIterator< TImageType > inputIter(image, image->GetLargestPossibleRegion()); itk::ImageRegionIterator< TImageType > outputIter(itk_out, itk_out->GetLargestPossibleRegion()); for(unsigned int i = 0 ; i < n_samples_drawn ;) { double r = (double)(rand()) / RAND_MAX; if(inputIter.Value() != 0 && r < 0.01 && outputIter.Value() == 0) { outputIter.Set(inputIter.Value()); i++; } ++inputIter; ++outputIter; if(inputIter.IsAtEnd()) { inputIter.GoToBegin(); outputIter.GoToBegin(); } } mitk::CastToMitkImage(itk_out, output); } private: template static void itkErodeGrayscale(TImageType * image, mitk::Image::Pointer & outimage , unsigned int radius, mitk::CLUtil::MorphologicalDimensions d); template static void itkDilateGrayscale(TImageType * image, mitk::Image::Pointer & outimage , unsigned int radius, mitk::CLUtil::MorphologicalDimensions d); template static void itkFillHoleGrayscale(TImageType * image, mitk::Image::Pointer & outimage); template< typename TImageType > static void itkInsertLabel(TImageType * maskImage, mitk::Image::Pointer & outimage, unsigned int label) { typename TImageType::Pointer itk_out; if(outimage.IsNull()) // create if necessary { MITK_INFO << "Initialize new image"; itk_out = TImageType::New(); itk_out->SetSpacing(maskImage->GetSpacing()); itk_out->SetDirection(maskImage->GetDirection()); itk_out->SetOrigin(maskImage->GetOrigin()); itk_out->SetRegions(maskImage->GetLargestPossibleRegion()); itk_out->Allocate(); itk_out->FillBuffer(0); }else { mitk::CastToItkImage(outimage, itk_out); } itk::ImageRegionIterator oit(itk_out,itk_out->GetLargestPossibleRegion()); itk::ImageRegionConstIterator mit(maskImage,maskImage->GetLargestPossibleRegion()); while(!mit.IsAtEnd()) { if(mit.Value() != 0) { oit.Set(label); } ++oit; ++mit; } mitk::CastToMitkImage(itk_out,outimage); } template< typename TImageType > static void itkGrabLabel(TImageType * image, mitk::Image::Pointer & outimage, unsigned int label) { typedef itk::Image TOutType; TOutType::Pointer itk_out = TOutType::New(); itk_out->SetRegions(image->GetLargestPossibleRegion()); itk_out->SetDirection(image->GetDirection()); itk_out->SetOrigin(image->GetOrigin()); itk_out->SetSpacing(image->GetSpacing()); itk_out->Allocate(); itk::ImageRegionConstIterator iit(image, image->GetLargestPossibleRegion()); itk::ImageRegionIterator oit(itk_out,itk_out->GetLargestPossibleRegion()); while(!iit.IsAtEnd()) { if(iit.Value() == static_cast(label)) oit.Set(1); else oit.Set(0); ++iit; ++oit; } mitk::CastToMitkImage(itk_out, outimage); } template static void itkMergeLabels(TImagetype * img, const std::map & map) { auto it = itk::ImageRegionIterator(img,img->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { if(map.find(it.Value())!=map.end()) it.Set( map.at(it.Value()) ); ++it; } } template static void itkConnectedComponentsImage(TImageType * image, mitk::Image::Pointer& mask, mitk::Image::Pointer &outimage, unsigned int& num_components) { typedef itk::Image MaskImageType; MaskImageType::Pointer itk_mask; if(mask.IsNull()) { itk_mask = MaskImageType::New(); itk_mask->SetRegions(image->GetLargestPossibleRegion()); itk_mask->SetDirection(image->GetDirection()); itk_mask->SetOrigin(image->GetOrigin()); itk_mask->SetSpacing(image->GetSpacing()); itk_mask->Allocate(); itk_mask->FillBuffer(1); }else{ mitk::CastToItkImage(mask,itk_mask); } typedef itk::ConnectedComponentImageFilter FilterType; typename FilterType::Pointer cc_filter = FilterType::New(); cc_filter->SetMaskImage(itk_mask.GetPointer()); cc_filter->SetInput(image); cc_filter->SetBackgroundValue(0); cc_filter->Update(); num_components = cc_filter->GetObjectCount(); mitk::CastToMitkImage(cc_filter->GetOutput(), outimage); } template< typename TImageType > static void itkCreateCheckerboardMask(TImageType * image, mitk::Image::Pointer & outimage); template< typename TImageType > static void itkInterpolateCheckerboardPrediction(TImageType * checkerboard_prediction, mitk::Image::Pointer & checkerboard_mask, mitk::Image::Pointer & outimage); template static void itkSumVoxelForLabel(TImageType* image, const mitk::Image::Pointer & source , typename TImageType::PixelType label, double & val ); template static void itkSqSumVoxelForLabel(TImageType* image, const mitk::Image::Pointer & source, typename TImageType::PixelType label, double & val ); template static void itkFitStructuringElement(TStructuringElement & se, MorphologicalDimensions d, int radius); template static void itkDilateBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int radius , MorphologicalDimensions d); template static void itkErodeBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int radius, MorphologicalDimensions d); template static void itkClosingBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int radius, MorphologicalDimensions d); template static void itkFillHolesBinary(itk::Image* sourceImage, mitk::Image::Pointer& resultImage); template static void itkLogicalAndImages(const TImageType * image1, const mitk::Image::Pointer & image2, mitk::Image::Pointer & outimage); template static void itkGaussianFilter(TImageType * image, mitk::Image::Pointer & smoothed ,double sigma); template static void itkDifferenceOfGaussianFilter(TImageType * image, mitk::Image::Pointer & smoothed, double sigma1, double sigma2); template static void itkProbabilityMap(const TImageType * sourceImage, double mean, double std_dev, mitk::Image::Pointer& resultImage); template static void itkHessianOfGaussianFilter(itk::Image* itkImage, double variance, std::vector &out); template static void itkLaplacianOfGaussianFilter(itk::Image* itkImage, double variance, mitk::Image::Pointer &output); template static void itkLocalHistograms(itk::Image* itkImage, std::vector &out, int size, int bins); }; } //namespace MITK #endif diff --git a/Modules/Classification/CLUtilities/include/mitkGIFCooccurenceMatrix2.h b/Modules/Classification/CLUtilities/include/mitkGIFCooccurenceMatrix2.h index f3190da6f4..c4b22ed7f0 100644 --- a/Modules/Classification/CLUtilities/include/mitkGIFCooccurenceMatrix2.h +++ b/Modules/Classification/CLUtilities/include/mitkGIFCooccurenceMatrix2.h @@ -1,162 +1,162 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkGIFCooccurenceMatrix2_h #define mitkGIFCooccurenceMatrix2_h #include #include #include -#include +#include namespace mitk { /** * \brief Calculates features based on the co-occurence matrix. * * The co-occurence matrix describes the relations between voxels in a specific direction. The elements \f$m_{i,k} \f$ of the * matrix count how often a voxel with the intensity \f$i \f$ has a neighbour in a certain direction with the intensity \f$ k \f$. * The direction for each matrix is given by a directed vector \f$ \overrightarrow{d} \f$. * * It is important to calculate the matrices for all possible directions in order to obtain a rotation invariant feature. * For the 3D case, this means that there are 26 possible directions. Using the symmetrical properties of the co-occurence * matrix, it is then possible to calculate the features in all directions looking at 13 different directions. * * The standard length of the vector is 1, e.g. looking at direct neighbours. It is possible to look at more * distance neighbours. This is achieved using the parameter range which defines the distance between * two neighbouring voxels in number of voxels. The default value for this is 1. It can be changes using the Method * SetRange() or by passing the option cooc2::range. * * There are two possible ways of combining the information obtained from the multiple directions. The first option * is to calculate a common matrix for all directions and then use this matrix to calculate the describing features. * The second method is to calculate a matrix for each direction, obtain the features and then report the mean and * standard value of these features. Both mehtods are calcuated by this filters and reported, distinguisehd by either * an "Overall" if a single matrix is used, a "Mean" for the mean Value, or an "Std.Dev." for the standard deviation. * * The connected areas are based on the binned image, the binning parameters can be set via the default * parameters as described in AbstractGlobalImageFeature. The intensity used for the calculation is * always equal to the bin number. 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. * * This feature calculator is activated by the option -cooccurence2 or -cooc2. * * The features are calculated based on a mask. It is assumed that the mask is * of the type of an unsigned short image. All voxels with the value 1 are treated as masked. * * The following features are defined. We always give the notation for the overall matrix feature * although those for the mean and std.dev. are basically equal. In the name, \ is replace * by the distance of the neighbours. For the definitions of the feature, the probability of each * intensity pair (i,k) \f$ p_{i,k} = \frac{m_{i,k}}{\sum_i \sum_k m_{i,k}} \f$. * * In addition, the marginal sum \f$ p_{i,\cdot} = p_{\cdot,k=i} = \sum_k p_{i,k} \f$, which is * identical for both axis due to the symetrical nature of the matrix. Furthermore, the diagonal and * cross diagnoal features are used: * \f[ p_{i-k}(l) = \sum_i \sum_k p_{i,k} \delta(l - \| i -k \| ) \enspace \enspace l = 0, \dots, N_g -1 \f] * \f[ p_{i+k}(l) = \sum_i \sum_k p_{i,k} \delta(l - ( i + k ) ) \enspace \enspace l = 2, \dots, 2 N_g \f] * Here, \f$ \delta(x) \f$ is the dirac function, which is one for \f$x=0 \f$ and zero otherwise. * - Co-occurenced Based Features (\)::%Overall Joint Maximum: * \f[ \textup{Joint Maximum}= \textup{max}(p_{i,k}) \f] * - Co-occurenced Based Features (\)::%Overall Joint Average: * \f[ \textup{Joint Average} = \mu_{ja} = \sum_i \sum_k i p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Joint Variance: * \f[ \textup{Joint Variance} = \sum_i \sum_k (i - \mu_{ja})^2 p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Joint Entropy: * \f[ \textup{Joint Entropy} = e_j = - \sum_i \sum_k p_{i,k} \textup{log}_2 p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Row Maximum: * \f[ \textup{Row Maximum}= \textup{max}(p_{i,\cdot}) \f] * - Co-occurenced Based Features (\)::%Overall Row Average: * \f[ \textup{Row Average} = \mu_{ra} = \sum_i i p_{i,\cdot} \f] * - Co-occurenced Based Features (\)::%Overall Row Variance: * \f[ \textup{Row Variance} = \sigma^2_{i, \cdot} = \sum_i (i - \mu_{ra})^2 p_{i,\cdot} \f] * - Co-occurenced Based Features (\)::%Overall Row Entropy: * \f[ \textup{Row Entropy} = e_r = - \sum_i p_{i,\cdot} \textup{log}_2 p_{i,\cdot} \f] * - Co-occurenced Based Features (\)::%Overall First Row-Column Entropy: * \f[ \textup{First Row-Column Entropy} = e_1 = - \sum_i \sum_k p_{i,k} \textup{log}_2 ( p_{i,\cdot} p_{\cdot,k}) \f] * - Co-occurenced Based Features (\)::%Overall Second Row-Column Entropy: * \f[ \textup{Second Row-Column Entropy} = e_2 = - \sum_i \sum_k p_{i,\cdot} p_{\cdot,k} \textup{log}_2 ( p_{i,\cdot} p_{\cdot,k}) \f] * - Co-occurenced Based Features (\)::%Overall Difference Average: * \f[ \textup{Difference Average} = \mu_{da} = \sum_l l p_{i-k}(l) \f] * - Co-occurenced Based Features (\)::%Overall Difference Variance: * \f[ \textup{Difference Variance} = \sum_l (i - \mu_{da})^2 p_{i-k}(l) \f] * - Co-occurenced Based Features (\)::%Overall Difference Entropy: * \f[ \textup{Difference Entropy} = - \sum_l p_{i-k}(l) \textup{log}_2 p_{i-k}(l) \f] * - Co-occurenced Based Features (\)::%Overall Sum Average: * \f[ \textup{Sum Average} = \mu_{sa} = \sum_l l p_{i+k}(l) \f] * - Co-occurenced Based Features (\)::%Overall Sum Variance: * \f[ \textup{Sum Variance} = \sum_l (i - \mu_{sa})^2 p_{i+k}(l) \f] * - Co-occurenced Based Features (\)::%Overall Sum Entropy: * \f[ \textup{Sum Entropy} = - \sum_l p_{i+k}(l) \textup{log}_2 p_{i+k}(l) \f] * - Co-occurenced Based Features (\)::%Overall Angular Second Moment: * \f[ \textup{Angular Second Moment} = \sum_i \sum_k p^2_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Contrast: * \f[ \textup{Contrast} = \sum_i \sum_k (i-k)^2 p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Dissimilarity: * \f[ \textup{Dissimilarity} = \sum_i \sum_k \| i-k\| p^2_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Inverse Difference: * \f[ \textup{Inverse Difference} = \sum_i \sum_k \frac{p_{i,k}}{1+\| i-k\|} \f] * - Co-occurenced Based Features (\)::%Overall Inverse Difference Normalized: * \f[ \textup{Inverse Difference Normalized} = \sum_i \sum_k \frac{p_{i,k}}{1+\frac{\| i-k\|}{N_g}} \f] * - Co-occurenced Based Features (\)::%Overall Inverse Difference Moment: * \f[ \textup{Inverse Difference Moment} = \sum_i \sum_k \frac{p_{i,k}}{1+ ( i-k )^2} \f] * - Co-occurenced Based Features (\)::%Overall Inverse Difference Moment Normalized: * \f[ \textup{Inverse Difference Moment Normalized} = \sum_i \sum_k \frac{p_{i,k}}{1+\frac{( i-k ) ^2}{N_g}} \f] * - Co-occurenced Based Features (\)::%Overall Inverse Variance: * \f[ \textup{Inverse Difference Moment Normalized} = \sum_i \sum_k \frac{p_{i,k}}{(i-k)^2} \f] * - Co-occurenced Based Features (\)::%Overall Correlation: * \f[ \textup{Correlation} = \frac{1}{\sigma^2_{i,\cdot}} \sum_i \sum_k (i - \mu_{ra})(k - \mu_{ra}) p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Autocorrelation: * \f[ \textup{Autocorrelation} = \sum_i \sum_k i k p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Cluster Tendency: * \f[ \textup{Cluster Tendency} = \sum_i \sum_k (i + k - 2\mu_{ra})^2 p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Cluster Shade: * \f[ \textup{Cluster Shade} = \sum_i \sum_k (i + k - 2\mu_{ra})^3 p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall Cluster Prominence: * \f[ \textup{Cluster Prominence} = \sum_i \sum_k (i + k - 2\mu_{ra})^4 p_{i,k} \f] * - Co-occurenced Based Features (\)::%Overall First Measure of Information Correlation: * \f[ \textup{First Measure of Information Correlation} = \frac{ e_j- e_1}{e_r} \f] * - Co-occurenced Based Features (\)::%Overall Second Measure of Information Correlation: * \f[ \textup{Second Measure of Information Correlation} = \sqrt{1- \exp(-2 (e_2 - e_j)} \f] */ class MITKCLUTILITIES_EXPORT GIFCooccurenceMatrix2 : public AbstractGlobalImageFeature { public: mitkClassMacro(GIFCooccurenceMatrix2, AbstractGlobalImageFeature); itkFactorylessNewMacro(Self); itkCloneMacro(Self); GIFCooccurenceMatrix2(); FeatureListType CalculateFeatures(const Image* image, const Image* mask, const Image* maskNoNAN) override; using Superclass::CalculateFeatures; itkGetConstMacro(Ranges, std::vector); void SetRanges(std::vector ranges); void SetRange(double range); void AddArguments(mitkCommandLineParser& parser) const override; protected: std::string GenerateLegacyFeatureEncoding(const FeatureID& id) const override; FeatureListType DoCalculateFeatures(const Image* image, const Image* mask) override; void ConfigureSettingsByParameters(const ParametersType& parameters) override; private: std::vector m_Ranges; }; } #endif diff --git a/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelDistanceZone.h b/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelDistanceZone.h index fa3cbd29bd..019795f32e 100644 --- a/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelDistanceZone.h +++ b/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelDistanceZone.h @@ -1,168 +1,168 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkGIFGreyLevelDistanceZone_h #define mitkGIFGreyLevelDistanceZone_h #include #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(); FeatureListType CalculateFeatures(const Image* image, const Image* mask, const Image* maskNoNAN) override; using Superclass::CalculateFeatures; void AddArguments(mitkCommandLineParser& parser) const override; protected: FeatureListType DoCalculateFeatures(const Image* image, const Image* mask) override; }; } #endif diff --git a/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelSizeZone.h b/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelSizeZone.h index 9f900b22fd..b9f2a6c9de 100644 --- a/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelSizeZone.h +++ b/Modules/Classification/CLUtilities/include/mitkGIFGreyLevelSizeZone.h @@ -1,112 +1,112 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkGIFGreyLevelSizeZone_h #define mitkGIFGreyLevelSizeZone_h #include #include #include -#include +#include namespace mitk { class MITKCLUTILITIES_EXPORT GIFGreyLevelSizeZone : public AbstractGlobalImageFeature { /** * \brief Calculates the Grey level size zone based features. * * Grey level size zone based features are similar to Grey Level Cooccurence features. But instead * of measuring the similarity within a given neighbourhood, the size of areas with the same intensity * is assessed. For this, a matrix is created that gives the number of areas \f$ m_{x,s} \f$ with the intensity \f$ x \f$ and * the size of \f$ s \f$. Each area is specified as connected voxels with the given intensity. * * The image is quantified prior to the calculation of the features. This reduces the number of * available intensity values. Instead of using the pure intensity value, the features are * calculated using the number of the bins as intensity value \f$ x_i \f$. The parameter of the * quantification of the image can be controlled using the general binning parameters as defined * in AbstractGlobalImageFeature. * * By default, the calculation is based on a 26 neighourhood for 3D and a 8 neighbourhood in 2D. It is further * possible to exclude directions from the calculation, e.g. calculating the feature in 2D, even if a * 3D image is passed. This is controlled by determine the * dimensionality of the neighbourhood using direction-related commands as described in AbstractGlobalImageFeature. * No other options are possible beside these two options. * * This feature calculator is activated by the option -grey-level-sizezone or -glsz. * * The features are calculated based on a mask. It is assumed that the mask is * of the type of an unsigned short image. All voxels with the value 1 are treated as masked. * * Several values are definied for the definition of the features. \f$ N_v \f$ is the number of masked voxels, * \f$N_s \f$ is the number of different zones, \f$ m_{x,\cdot} = \sum_s m{x,s} \f$ is the number of all areas * with a given intensity value, and likewise \f$ m_{\cdot, s} = \sum_x m{x,s} \f$ is the number of all areas * with a given size. The features are then defined as: * - Grey Level Size Zone::Small Zone Emphasis: * \f[ \textup{Small Zone Emphasis}= \frac{1}{N_s} \sum_s { \frac{m_{\cdot, s}}{s^2} } \f] * - Grey Level Size Zone::Large Zone Emphasis: * \f[ \textup{Large Zone Emphasis}= \frac{1}{N_s} \sum_s { m_{\cdot, s} s^2} \f] * - Grey Level Size Zone::Low Grey Level Zone Emphasis: * \f[ \textup{Low Grey Level Zone Emphasis}= \frac{1}{N_s} \sum_x { \frac{m_{x,\cdot}}{x^2} } \f] * - Grey Level Size Zone::High Grey Level Zone Emphasis: * \f[ \textup{High Grey Level Zone Emphasis}= \frac{1}{N_s} \sum_x { m_{x,\cdot} x^2} \f] * - Grey Level Size Zone::Small Zone Low Grey Level Emphasis: * \f[ \textup{Small Zone Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_s { \frac{m_{x,s}}{x^2 s^2} } \f] * - Grey Level Size Zone::Small Zone High Grey Level Emphasis: * \f[ \textup{Small Zone High Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_s { \frac{x^2 m_{x,s}}{s^2} } \f] * - Grey Level Size Zone::Large Zone Low Grey Level Emphasis: * \f[ \textup{Large Zone Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_s { \frac{s^2 m_{x,s}}{x^2} } \f] * - Grey Level Size Zone::Large Zone High Grey Level Emphasis: * \f[ \textup{Large Zone High Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_s { x^2 s^2 m_{x,s} } \f] * - Grey Level Size Zone::Grey Level Non-Uniformity: * \f[ \textup{Grey Level Non-Uniformity}= \frac{1}{N_s} \sum_x m_{x,\cdot}^2 \f] * - Grey Level Size Zone::Grey Level Non-Uniformity Normalized: * \f[ \textup{Grey Level Non-Uniformity Normalized}= \frac{1}{N_s^2} \sum_x m_{x,\cdot}^2 \f] * - Grey Level Size Zone::Zone Size Non-Uniformity: * \f[ \textup{Zone Size Non-Uniformity}= \frac{1}{N_s} \sum_s m_{\cdot, s}^2 \f] * - Grey Level Size Zone::Zone Size Non-Uniformity Normalized: * \f[ \textup{Zone Size Non-Uniformity Normalized}= \frac{1}{N_s^2} \sum_s m_{\cdot, s}^2 \f] * - Grey Level Size Zone::Zone Percentage: The ratio of realized areas to the theoretical limit of zones: * \f[ \textup{Zone Percentage}= \frac{N_s}{N_v} \f] * - Grey Level Size Zone::Grey Level Mean: * \f[ \textup{Grey Level Mean} = \mu_x = \frac{1}{N_s} \sum_x x m_{x, \cdot} \f] * - Grey Level Size Zone::Grey Level Variance: * \f[ \textup{Grey Level Variance} = \frac{1}{N_s} \sum_x (x -mu_x)^2 m_{x, \cdot} \f] * - Grey Level Size Zone::Zone Size Mean: * \f[ \textup{Zone Size Mean} = \mu_s = \frac{1}{N_s} \sum_s s m_{\cdot, s} \f] * - Grey Level Size Zone::Grey Level Variance: * \f[ \textup{Grey Level Variance} = \frac{1}{N_s} \sum_s (s -mu_s)^2 m_{\cdot, s} \f] * - Grey Level Size Zone::Zone Size Entropy: This feature would be equivalent with * the Grey Level Entropy, which is therefore not included. It is based on the likelihood * for a given intensity- size combination \f$ p_{x,s} = \frac{m_{x,s}}{N_s} \f$. : * \f[ \textup{Zone Size Entropy} = \sum_x \sum_s p_{x,s} \textup{log}_2 \left( p{_x,s} \right) \f] */ public: mitkClassMacro(GIFGreyLevelSizeZone, AbstractGlobalImageFeature); itkFactorylessNewMacro(Self); itkCloneMacro(Self); GIFGreyLevelSizeZone(); FeatureListType CalculateFeatures(const Image* image, const Image* mask, const Image* maskNoNAN) override; using Superclass::CalculateFeatures; void AddArguments(mitkCommandLineParser& parser) const override; protected: FeatureListType DoCalculateFeatures(const Image* image, const Image* mask) override; }; } #endif diff --git a/Modules/Classification/CLUtilities/include/mitkGIFNeighbouringGreyLevelDependenceFeatures.h b/Modules/Classification/CLUtilities/include/mitkGIFNeighbouringGreyLevelDependenceFeatures.h index 5a7d2889b0..91ffa1adf5 100644 --- a/Modules/Classification/CLUtilities/include/mitkGIFNeighbouringGreyLevelDependenceFeatures.h +++ b/Modules/Classification/CLUtilities/include/mitkGIFNeighbouringGreyLevelDependenceFeatures.h @@ -1,149 +1,149 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkGIFNeighbouringGreyLevelDependenceFeatures_h #define mitkGIFNeighbouringGreyLevelDependenceFeatures_h #include #include #include -#include +#include namespace mitk { /** * \brief Calculates the Neighbouring Grey Level Dependence Features * * The Neighbouring Grey Level Dependence Features were proposed by Sun and Wee (1983) and * capture the coarsness of the image texture. They are rotational invariant. * * The features are calculated on a matrix \f$ m \f$. To obtain the matrix, a neighbourhood * around each feature is calculated and the number of voxels within the neighbourhood that * are greater than the center voxel plus \f$ \alpha \f$ is counted. This is called the * number of dependence voxels. The matrix gives the * number of voxels with an intesity \f$ x \f$ and \f$ d \f$ dependence neighbourhood voxels. * * The image is quantified prior to the calculation of the features. This reduces the number of * available intensity values. Instead of using the pure intensity value, the features are * calculated using the number of the bins as intensity value \f$ x_i \f$. The parameter of the * quantification of the image can be controlled using the general binning parameters as defined * in AbstractGlobalImageFeature. * * By default, the calculation is based on a 26 neighourhood for 3D and a 8 neighbourhood in 2D. It is further * possible to exclude directions from the calculation, e.g. calculating the feature in 2D, even if a * 3D image is passed. This is controlled by determine the * dimensionality of the neighbourhood using direction-related commands as described in AbstractGlobalImageFeature. * * In addition to this, the size of the neighbourhood can be controlled by setting the parameter * ngld::range. By default it is one. To pass more than one range, separate the ranges with * a semicolon. E.g. 1;2;3 would calculate the features for the ranges 1, 2, and 3. * * This feature calculator is activated by the option -neighbouring-grey-level-dependence * or -ngld. * * The features are calculated based on a mask. It is assumed that the mask is * a unsigned short image. All voxels with a value greater 0 are treated as masked. * * Several values are definied for the definition of the features. \f$ N_v \f$ is the number of masked voxels, * \f$N_s \f$ is the number of neighbourhoods, \f$ m_{x,\cdot} = \sum_d m{x,d} \f$ is the number of neighbourhoods * with a given intensity value, and likewise \f$ m_{\cdot, d} = \sum_x m{x,d} \f$ is the number of neighbourhoods * with a given number of dependence features: * - Neighbouring Grey Level Dependence::Low Dependence Emphasis: * \f[ \textup{Low dependence emphasis}= \frac{1}{N_s} \sum_d { \frac{m_{\cdot, d}}{d^2} } \f] * - Neighbouring Grey Level Dependence::High Dependence Emphasis: * \f[ \textup{High dependence emphasis}= \frac{1}{N_s} \sum_d { m_{\cdot, d} d^2} \f] * - Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis: * \f[ \textup{Low grey level count emphasis}= \frac{1}{N_s} \sum_x { \frac{m_{x,\cdot}}{x^2} } \f] * - Neighbouring Grey Level Dependence::High Grey Level Count Emphasis: * \f[ \textup{High grey level count emphasis}= \frac{1}{N_s} \sum_x { m_{x,\cdot} x^2} \f] * - Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis: * \f[ \textup{Low Dependence Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_d { \frac{m_{x,d}}{x^2 d^2} } \f] * - Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis: * \f[ \textup{Low dependence high grey level emphasis}= \frac{1}{N_s} \sum_x \sum_d { \frac{x^2 m_{x,d}}{d^2} } \f] * - Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis: * \f[ \textup{High Dependence Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_d { \frac{d^2 m_{x,d}}{x^2} } \f] * - Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis: * \f[ \textup{High dependence high grey level emphasis}= \frac{1}{N_s} \sum_x \sum_d { x^2 d^2 m_{x,d} } \f] * - Neighbouring Grey Level Dependence::Grey level nonuniformity: * \f[ \textup{Grey level nonuniformity}= \frac{1}{N_s} \sum_x m_{x,\cdot}^2 \f] * - Neighbouring Grey Level Dependence::Grey level nonuniformity normalized: * \f[ \textup{Grey level nonuniformity normalized}= \frac{1}{N_s^2} \sum_x m_{x,\cdot}^2 \f] * - Neighbouring Grey Level Dependence::Dependence Count Nonuniformity: * \f[ \textup{Dependence count nonuniformity}= \frac{1}{N_s} \sum_d m_{\cdot, d}^2 \f] * - Neighbouring Grey Level Dependence::Dependence Count Nonuniformity Normalized: * \f[ \textup{Dependence count nonuniformity normalized}= \frac{1}{N_s^2} \sum_d m_{\cdot, d}^2 \f] * - Neighbouring Grey Level Dependence::DEpendence Count Percentage THe number of realized * neighbourhoods relativ to the theoretical maximum of realized neighbourhoods. This feature is always * one for this implementation as partial neighbourhoods are still considered. * - Neighbouring Grey Level Dependence::Grey Level Mean: The mean value of all grey level. * \f[ \textup{Grey Level Mean} = \mu_x = \frac{1}{N_s} \sum_x x m_{x,\cdot} \f] * - Neighbouring Grey Level Dependence::Grey Level Variance: * \f[ \textup{Grey level variance} = \frac{1}{N_s} \sum_x (x -mu_x)^2 m_{x, \cdot} \f] * - Neighbouring Grey Level Dependence::Dependence Count Mean: The mean value of all dependence counts. * \f[ \textup{Dependence count mean} = \mu_d = \frac{1}{N_s} \sum_d d m_{\cdot,d} \f] * - Neighbouring Grey Level Dependence::Dependence Count Variance: * \f[ \textup{Dependence count variance} = \frac{1}{N_s} \sum_d (d -mu_d)^2 m_{\cdot, d} \f] * - Neighbouring Grey Level Dependence::Dependence Count Entropy: This feature would be equivalent with * the Grey Level Entropy, which is therefore not included. It is based on the likelihood * for a given intensity- size combination \f$ p_{x,d} = \frac{m_{x,d}}{N_s} \f$. : * \f[ \textup{Dependence count entropy} = \sum_x \sum_d p_{x,d} \textup{log}_2 \left( p_{x,d} \right) \f] * - Neighbouring Grey Level Dependence::Dependence Count Energy: This feature would be equivalent with * the Grey Level Energy, which is therefore not included. It is based on the likelihood * for a given intensity- size combination \f$ p_{x,d} = \frac{m_{x,d}}{N_s} \f$. : * \f[ \textup{Dependence count energy} = \sum_x \sum_d p_{x,d}^2 \f] * - Neighbouring Grey Level Dependence::Expected Neighbourhood Size: The expected size of a * full neighbourhood. It depends on the dimension of the area that is looked at. * - Neighbouring Grey Level Dependence::Average Neighbourhood Size: The feature calculation * allows to consider partially masked neighbourhoods. Due to that, some neighbourhoods might be smaller. * This feature gives not the theoretical neighbourhood size but the average realized neighbourhood sizes. * - Neighbouring Grey Level Dependence::Average Incomplete Neighbourhood Size: Gives the average * size of all neighbourhoods that are not complete. * - Neighbouring Grey Level Dependence::Percentage of complete Neighbourhoods: Gives the percentage * of all complete neighbourhoods from all realized neighbourhoods. * - Neighbouring Grey Level Dependence::Percentage of Dependence Neighbour Voxels: Gives the * percentage of voxels in all neighbourhoods compared to the expected number of voxels. */ class MITKCLUTILITIES_EXPORT GIFNeighbouringGreyLevelDependenceFeature : public AbstractGlobalImageFeature { public: mitkClassMacro(GIFNeighbouringGreyLevelDependenceFeature, AbstractGlobalImageFeature); itkFactorylessNewMacro(Self); itkCloneMacro(Self); GIFNeighbouringGreyLevelDependenceFeature(); FeatureListType CalculateFeatures(const Image* image, const Image* mask, const Image* maskNoNAN) override; using Superclass::CalculateFeatures; itkGetConstMacro(Ranges, std::vector); void SetRanges(std::vector ranges); void SetRange(double range); itkGetConstMacro(Alpha, int); itkSetMacro(Alpha, int); void AddArguments(mitkCommandLineParser& parser) const override; protected: std::string GenerateLegacyFeatureEncoding(const FeatureID& id) const override; FeatureListType DoCalculateFeatures(const Image* image, const Image* mask) override; void ConfigureSettingsByParameters(const ParametersType& parameters) override; private: std::vector m_Ranges; int m_Alpha; }; } #endif diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp index 026f64a6d2..2fb8536e1c 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFVolumetricDensityStatistics.cpp @@ -1,513 +1,513 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #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 +#include struct GIFVolumetricDensityStatisticsParameters { double volume; mitk::FeatureID id; }; template void CalculateVolumeDensityStatistic(const itk::Image* itkImage, const mitk::Image* mask, GIFVolumetricDensityStatisticsParameters params, mitk::GIFVolumetricDensityStatistics::FeatureListType & featureList) { typedef itk::Image ImageType; typedef itk::Image MaskType; double volume = params.volume; typename MaskType::Pointer maskImage = MaskType::New(); mitk::CastToItkImage(mask, maskImage); itk::ImageRegionConstIteratorWithIndex imgA(itkImage, itkImage->GetLargestPossibleRegion()); itk::ImageRegionConstIteratorWithIndex imgB(itkImage, itkImage->GetLargestPossibleRegion()); itk::ImageRegionConstIteratorWithIndex maskA(maskImage, maskImage->GetLargestPossibleRegion()); itk::ImageRegionConstIteratorWithIndex maskB(maskImage, maskImage->GetLargestPossibleRegion()); double moranA = 0; double moranB = 0; double geary = 0; double Nv = 0; double w_ij = 0; double mean = 0; typename ImageType::PointType pointA; typename ImageType::PointType pointB; while (!imgA.IsAtEnd()) { if (maskA.Get() > 0) { Nv += 1; mean += imgA.Get(); } ++imgA; ++maskA; } mean /= Nv; imgA.GoToBegin(); maskA.GoToBegin(); 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); 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); } ++imgA; ++maskA; } MITK_INFO << "Volume: " << volume; MITK_INFO << " Mean: " << mean; featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume integrated intensity"), volume* mean)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume Moran's I index"), Nv / w_ij * moranA / moranB)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "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) { // 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; } 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; 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::GIFVolumetricDensityStatistics() { SetLongName("volume-density"); SetShortName("volden"); SetFeatureClassName("Morphological Density"); } void mitk::GIFVolumetricDensityStatistics::AddArguments(mitkCommandLineParser& parser) const { std::string name = GetOptionPrefix(); parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Volume-Density Statistic", "calculates volume density based features", us::Any()); } mitk::AbstractGlobalImageFeature::FeatureListType mitk::GIFVolumetricDensityStatistics::DoCalculateFeatures(const Image* image, const Image* mask) { FeatureListType featureList; if (image->GetDimension() < 3) { MITK_INFO << "Skipped calculating volumetric density features; only 3D images are supported ...."; return featureList; } MITK_INFO << "Start calculating volumetric density features ...."; vtkSmartPointer mesher = vtkSmartPointer::New(); vtkSmartPointer stats = vtkSmartPointer::New(); vtkSmartPointer stats2 = vtkSmartPointer::New(); auto nonconstVtkData = const_cast(mask->GetVtkImageData()); mesher->SetInputData(nonconstVtkData); 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; calculateMEE(mesher->GetOutput(), vol_mvee, surf_mvee); double vol_mobb; double surf_mobb; 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.id = this->CreateTemplateFeatureID(); AccessByItk_3(image, CalculateVolumeDensityStatistic, 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]; 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; 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) { 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 (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 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 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); } ad_aee = meshSurf / ad_aee; double vd_ch = meshVolume / stats2->GetVolume(); double ad_ch = meshSurf / stats2->GetSurfaceArea(); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density axis-aligned bounding box"), vd_aabb)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density axis-aligned bounding box"), ad_aabb)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density oriented minimum bounding box"), meshVolume / vol_mobb)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density oriented minimum bounding box"), meshSurf / surf_mobb)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density approx. enclosing ellipsoid"), vd_aee)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density approx. enclosing ellipsoid"), ad_aee)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density approx. minimum volume enclosing ellipsoid"), meshVolume / vol_mvee)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density approx. minimum volume enclosing ellipsoid"), meshSurf / surf_mvee)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Volume density convex hull"), vd_ch)); featureList.push_back(std::make_pair(mitk::CreateFeatureID(params.id, "Surface density convex hull"), ad_ch)); MITK_INFO << "Finished calculating volumetric density features...."; return featureList; } mitk::AbstractGlobalImageFeature::FeatureListType mitk::GIFVolumetricDensityStatistics::CalculateFeatures(const Image* image, const Image* mask, const Image*) { return Superclass::CalculateFeatures(image, mask); } diff --git a/Modules/Classification/CLUtilities/src/mitkCLUtil.cpp b/Modules/Classification/CLUtilities/src/mitkCLUtil.cpp index d67040b3f6..2b78ecf3d4 100644 --- a/Modules/Classification/CLUtilities/src/mitkCLUtil.cpp +++ b/Modules/Classification/CLUtilities/src/mitkCLUtil.cpp @@ -1,642 +1,642 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef _mitkCLUtil_HXX #define _mitkCLUtil_HXX #include #include -#include +#include #include // itk includes #include #include #include "itkHessianRecursiveGaussianImageFilter.h" #include "itkUnaryFunctorImageFilter.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" #include #include // Morphologic Operations #include #include #include #include #include #include #include #include // Image Filter #include #include void mitk::CLUtil::ProbabilityMap(const mitk::Image::Pointer & image , double mean, double stddev, mitk::Image::Pointer & outimage) { AccessFixedDimensionByItk_3(image, mitk::CLUtil::itkProbabilityMap, 3, mean, stddev, outimage); } void mitk::CLUtil::ErodeGrayscale(mitk::Image::Pointer & image , unsigned int radius, mitk::CLUtil::MorphologicalDimensions d, mitk::Image::Pointer & outimage) { AccessFixedDimensionByItk_3(image, mitk::CLUtil::itkErodeGrayscale, 3, outimage, radius, d); } void mitk::CLUtil::DilateGrayscale(mitk::Image::Pointer & image, unsigned int radius, mitk::CLUtil::MorphologicalDimensions d, mitk::Image::Pointer & outimage) { AccessFixedDimensionByItk_3(image, mitk::CLUtil::itkDilateGrayscale, 3, outimage, radius, d); } void mitk::CLUtil::FillHoleGrayscale(mitk::Image::Pointer & image, mitk::Image::Pointer & outimage) { AccessFixedDimensionByItk_1(image, mitk::CLUtil::itkFillHoleGrayscale, 3, outimage); } void mitk::CLUtil::InsertLabel(mitk::Image::Pointer & image, mitk::Image::Pointer & maskImage, unsigned int label) { AccessByItk_2(image, mitk::CLUtil::itkInsertLabel, maskImage, label); } void mitk::CLUtil::GrabLabel(mitk::Image::Pointer & image, mitk::Image::Pointer & outimage, unsigned int label) { AccessFixedDimensionByItk_2(image, mitk::CLUtil::itkGrabLabel, 3, outimage, label); } void mitk::CLUtil::ConnectedComponentsImage(mitk::Image::Pointer & image, mitk::Image::Pointer& mask, mitk::Image::Pointer &outimage, unsigned int& num_components) { AccessFixedDimensionByItk_3(image, mitk::CLUtil::itkConnectedComponentsImage,3, mask, outimage, num_components); } void mitk::CLUtil::MergeLabels(mitk::Image::Pointer & img, const std::map & map) { AccessByItk_1(img, mitk::CLUtil::itkMergeLabels, map); } void mitk::CLUtil::CountVoxel(mitk::Image::Pointer image, std::map & map) { AccessByItk_1(image, mitk::CLUtil::itkCountVoxel, map); } void mitk::CLUtil::CountVoxel(mitk::Image::Pointer image, unsigned int label, unsigned int & count) { AccessByItk_2(image, mitk::CLUtil::itkCountVoxel, label, count); } void mitk::CLUtil::CountVoxel(mitk::Image::Pointer image, unsigned int & count) { AccessByItk_1(image, mitk::CLUtil::itkCountVoxel, count); } void mitk::CLUtil::CreateCheckerboardMask(mitk::Image::Pointer image, mitk::Image::Pointer & outimage) { AccessFixedDimensionByItk_1(image, mitk::CLUtil::itkCreateCheckerboardMask,3, outimage); } void mitk::CLUtil::LogicalAndImages(const mitk::Image::Pointer & image1, const mitk::Image::Pointer & image2, mitk::Image::Pointer & outimage) { AccessFixedDimensionByItk_2(image1,itkLogicalAndImages, 3, image2, outimage); } void mitk::CLUtil::InterpolateCheckerboardPrediction(mitk::Image::Pointer checkerboard_prediction, mitk::Image::Pointer & checkerboard_mask, mitk::Image::Pointer & outimage) { AccessFixedDimensionByItk_2(checkerboard_prediction, mitk::CLUtil::itkInterpolateCheckerboardPrediction,3, checkerboard_mask, outimage); } void mitk::CLUtil::GaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed ,double sigma) { AccessFixedDimensionByItk_2(image, mitk::CLUtil::itkGaussianFilter,3, smoothed, sigma); } void mitk::CLUtil::DifferenceOfGaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed, double sigma1, double sigma2) { AccessFixedDimensionByItk_3(image, mitk::CLUtil::itkDifferenceOfGaussianFilter, 3, smoothed, sigma1, sigma2); } void mitk::CLUtil::LaplacianOfGaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed, double sigma1) { AccessByItk_2(image, mitk::CLUtil::itkLaplacianOfGaussianFilter, sigma1, smoothed); } void mitk::CLUtil::HessianOfGaussianFilter(mitk::Image::Pointer image, std::vector &out, double sigma) { AccessByItk_2(image, mitk::CLUtil::itkHessianOfGaussianFilter, sigma, out); } void mitk::CLUtil::LocalHistogram(mitk::Image::Pointer image, std::vector &out, int Bins, int NeighbourhoodSize) { AccessByItk_3(image, mitk::CLUtil::itkLocalHistograms, out, NeighbourhoodSize, Bins); } void mitk::CLUtil::DilateBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int factor , MorphologicalDimensions d) { AccessFixedDimensionByItk_3(sourceImage, mitk::CLUtil::itkDilateBinary, 3, resultImage, factor, d); } void mitk::CLUtil::ErodeBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int factor, MorphologicalDimensions d) { AccessFixedDimensionByItk_3(sourceImage, mitk::CLUtil::itkErodeBinary, 3, resultImage, factor, d); } void mitk::CLUtil::ClosingBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int factor, MorphologicalDimensions d) { AccessFixedDimensionByItk_3(sourceImage, mitk::CLUtil::itkClosingBinary, 3, resultImage, factor, d); } template void mitk::CLUtil::itkProbabilityMap(const TImageType * sourceImage, double mean, double std_dev, mitk::Image::Pointer& resultImage) { itk::Image::Pointer itk_img = itk::Image::New(); itk_img->SetRegions(sourceImage->GetLargestPossibleRegion()); itk_img->SetOrigin(sourceImage->GetOrigin()); itk_img->SetSpacing(sourceImage->GetSpacing()); itk_img->SetDirection(sourceImage->GetDirection()); itk_img->Allocate(); itk::ImageRegionConstIterator it(sourceImage,sourceImage->GetLargestPossibleRegion()); itk::ImageRegionIterator > outit(itk_img,itk_img->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { double x = it.Value(); double prob = (1.0/(std_dev*std::sqrt(2.0*itk::Math::pi))) * std::exp(-(((x-mean)*(x-mean))/(2.0*std_dev*std_dev))); outit.Set(prob); ++it; ++outit; } mitk::CastToMitkImage(itk_img, resultImage); } template< typename TImageType > void mitk::CLUtil::itkInterpolateCheckerboardPrediction(TImageType * checkerboard_prediction, Image::Pointer &checkerboard_mask, mitk::Image::Pointer & outimage) { typename TImageType::Pointer itk_checkerboard_mask; mitk::CastToItkImage(checkerboard_mask,itk_checkerboard_mask); typename TImageType::Pointer itk_outimage = TImageType::New(); itk_outimage->SetRegions(checkerboard_prediction->GetLargestPossibleRegion()); itk_outimage->SetDirection(checkerboard_prediction->GetDirection()); itk_outimage->SetOrigin(checkerboard_prediction->GetOrigin()); itk_outimage->SetSpacing(checkerboard_prediction->GetSpacing()); itk_outimage->Allocate(); itk_outimage->FillBuffer(0); //typedef typename itk::ShapedNeighborhoodIterator::SizeType SizeType; typedef itk::Size<3> SizeType; SizeType size; size.Fill(1); itk::ShapedNeighborhoodIterator iit(size,checkerboard_prediction,checkerboard_prediction->GetLargestPossibleRegion()); itk::ShapedNeighborhoodIterator mit(size,itk_checkerboard_mask,itk_checkerboard_mask->GetLargestPossibleRegion()); itk::ImageRegionIterator oit(itk_outimage,itk_outimage->GetLargestPossibleRegion()); typedef typename itk::ShapedNeighborhoodIterator::OffsetType OffsetType; OffsetType offset; offset.Fill(0); offset[0] = 1; // {1,0,0} iit.ActivateOffset(offset); mit.ActivateOffset(offset); offset[0] = -1; // {-1,0,0} iit.ActivateOffset(offset); mit.ActivateOffset(offset); offset[0] = 0; offset[1] = 1; //{0,1,0} iit.ActivateOffset(offset); mit.ActivateOffset(offset); offset[1] = -1; //{0,-1,0} iit.ActivateOffset(offset); mit.ActivateOffset(offset); // iit.ActivateOffset({{0,0,1}}); // iit.ActivateOffset({{0,0,-1}}); // mit.ActivateOffset({{0,0,1}}); // mit.ActivateOffset({{0,0,-1}}); while(!iit.IsAtEnd()) { if(mit.GetCenterPixel() == 0) { typename TImageType::PixelType mean = 0; for (auto i = iit.Begin(); ! i.IsAtEnd(); i++) { mean += i.Get(); } //std::sort(list.begin(),list.end(),[](const typename TImageType::PixelType x,const typename TImageType::PixelType y){return x<=y;}); oit.Set((mean+0.5)/6.0); } else { oit.Set(iit.GetCenterPixel()); } ++iit; ++mit; ++oit; } mitk::CastToMitkImage(itk_outimage,outimage); } template< typename TImageType > void mitk::CLUtil::itkCreateCheckerboardMask(TImageType * image, mitk::Image::Pointer & outimage) { typename TImageType::Pointer zeroimg = TImageType::New(); zeroimg->SetRegions(image->GetLargestPossibleRegion()); zeroimg->SetDirection(image->GetDirection()); zeroimg->SetOrigin(image->GetOrigin()); zeroimg->SetSpacing(image->GetSpacing()); zeroimg->Allocate(); zeroimg->FillBuffer(0); typedef itk::CheckerBoardImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput1(image); filter->SetInput2(zeroimg); typename FilterType::PatternArrayType pattern; pattern.SetElement(0,(image->GetLargestPossibleRegion().GetSize()[0])); pattern.SetElement(1,(image->GetLargestPossibleRegion().GetSize()[1])); pattern.SetElement(2,(image->GetLargestPossibleRegion().GetSize()[2])); filter->SetCheckerPattern(pattern); filter->Update(); mitk::CastToMitkImage(filter->GetOutput(), outimage); } template void mitk::CLUtil::itkSumVoxelForLabel(TImageType* image, const mitk::Image::Pointer & source , typename TImageType::PixelType label, double & val ) { itk::Image::Pointer itk_source; mitk::CastToItkImage(source,itk_source); itk::ImageRegionConstIterator inputIter(image, image->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< itk::Image > sourceIter(itk_source, itk_source->GetLargestPossibleRegion()); while(!inputIter.IsAtEnd()) { if(inputIter.Value() == label) val += sourceIter.Value(); ++inputIter; ++sourceIter; } } template void mitk::CLUtil::itkSqSumVoxelForLabel(TImageType* image, const mitk::Image::Pointer & source, typename TImageType::PixelType label, double & val ) { itk::Image::Pointer itk_source; mitk::CastToItkImage(source,itk_source); itk::ImageRegionConstIterator inputIter(image, image->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< itk::Image > sourceIter(itk_source, itk_source->GetLargestPossibleRegion()); while(!inputIter.IsAtEnd()) { if(inputIter.Value() == label) val += sourceIter.Value() * sourceIter.Value(); ++inputIter; ++sourceIter; } } template void mitk::CLUtil::itkFitStructuringElement(TStructuringElement & se, MorphologicalDimensions d, int factor) { typename TStructuringElement::SizeType size; size.Fill(factor); switch(d) { case(All): case(Axial): size.SetElement(2,0); break; case(Sagittal): size.SetElement(0,0); break; case(Coronal): size.SetElement(1,0); break; } se.SetRadius(size); se.CreateStructuringElement(); } template void mitk::CLUtil::itkClosingBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int factor, MorphologicalDimensions d) { typedef itk::BinaryBallStructuringElement BallType; typedef itk::BinaryMorphologicalClosingImageFilter FilterType; BallType strElem; itkFitStructuringElement(strElem,d,factor); typename FilterType::Pointer erodeFilter = FilterType::New(); erodeFilter->SetKernel(strElem); erodeFilter->SetInput(sourceImage); erodeFilter->SetForegroundValue(1); erodeFilter->Update(); mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); } template void mitk::CLUtil::itkDilateBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int factor, MorphologicalDimensions d) { typedef itk::BinaryBallStructuringElement BallType; typedef typename itk::BinaryDilateImageFilter BallDilateFilterType; BallType strElem; itkFitStructuringElement(strElem,d,factor); typename BallDilateFilterType::Pointer erodeFilter = BallDilateFilterType::New(); erodeFilter->SetKernel(strElem); erodeFilter->SetInput(sourceImage); erodeFilter->SetDilateValue(1); erodeFilter->Update(); mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); } template void mitk::CLUtil::itkErodeBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int factor, MorphologicalDimensions d) { typedef itk::BinaryBallStructuringElement BallType; typedef typename itk::BinaryErodeImageFilter BallErodeFilterType; BallType strElem; itkFitStructuringElement(strElem,d,factor); typename BallErodeFilterType::Pointer erodeFilter = BallErodeFilterType::New(); erodeFilter->SetKernel(strElem); erodeFilter->SetInput(sourceImage); erodeFilter->SetErodeValue(1); // erodeFilter->UpdateLargestPossibleRegion(); erodeFilter->Update(); mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); } /// /// \brief itkFillHolesBinary /// \param sourceImage /// \param resultImage /// template void mitk::CLUtil::itkFillHolesBinary(itk::Image* sourceImage, mitk::Image::Pointer& resultImage) { typedef itk::Image ImageType; typedef typename itk::BinaryFillholeImageFilter FillHoleFilterType; typename FillHoleFilterType::Pointer fillHoleFilter = FillHoleFilterType::New(); fillHoleFilter->SetInput(sourceImage); fillHoleFilter->SetForegroundValue(1); fillHoleFilter->Update(); mitk::CastToMitkImage(fillHoleFilter->GetOutput(), resultImage); } /// /// \brief itkLogicalAndImages /// \param image1 keep the values of image 1 /// \param image2 /// template void mitk::CLUtil::itkLogicalAndImages(const TImageType * image1, const mitk::Image::Pointer & image2, mitk::Image::Pointer & outimage) { typename TImageType::Pointer itk_outimage = TImageType::New(); itk_outimage->SetRegions(image1->GetLargestPossibleRegion()); itk_outimage->SetDirection(image1->GetDirection()); itk_outimage->SetOrigin(image1->GetOrigin()); itk_outimage->SetSpacing(image1->GetSpacing()); itk_outimage->Allocate(); itk_outimage->FillBuffer(0); typename TImageType::Pointer itk_image2; mitk::CastToItkImage(image2,itk_image2); itk::ImageRegionConstIterator it1(image1, image1->GetLargestPossibleRegion()); itk::ImageRegionConstIterator it2(itk_image2, itk_image2->GetLargestPossibleRegion()); itk::ImageRegionIterator oit(itk_outimage,itk_outimage->GetLargestPossibleRegion()); while(!it1.IsAtEnd()) { if(it1.Value() == 0 || it2.Value() == 0) { oit.Set(0); }else oit.Set(it1.Value()); ++it1; ++it2; ++oit; } mitk::CastToMitkImage(itk_outimage, outimage); } /// /// \brief GaussianFilter /// \param image /// \param smoothed /// \param sigma /// template void mitk::CLUtil::itkGaussianFilter(TImageType * image, mitk::Image::Pointer & smoothed ,double sigma) { typedef itk::DiscreteGaussianImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput(image); filter->SetVariance(sigma); filter->Update(); mitk::CastToMitkImage(filter->GetOutput(),smoothed); } template void mitk::CLUtil::itkDifferenceOfGaussianFilter(TImageType * image, mitk::Image::Pointer & smoothed, double sigma1, double sigma2) { typedef itk::DiscreteGaussianImageFilter FilterType; typedef itk::SubtractImageFilter SubtractFilterType; typename FilterType::Pointer filter1 = FilterType::New(); typename FilterType::Pointer filter2 = FilterType::New(); typename SubtractFilterType::Pointer subFilter = SubtractFilterType::New(); filter1->SetInput(image); filter1->SetVariance(sigma1); filter1->Update(); filter2->SetInput(image); filter2->SetVariance(sigma2); filter2->Update(); subFilter->SetInput1(filter1->GetOutput()); subFilter->SetInput2(filter2->GetOutput()); subFilter->Update(); mitk::CastToMitkImage(subFilter->GetOutput(), smoothed); } template void mitk::CLUtil::itkLaplacianOfGaussianFilter(itk::Image* itkImage, double variance, mitk::Image::Pointer &output) { typedef itk::Image ImageType; typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType > GaussFilterType; typedef itk::LaplacianRecursiveGaussianImageFilter LaplacianFilter; typename GaussFilterType::Pointer gaussianFilter = GaussFilterType::New(); gaussianFilter->SetInput(itkImage); gaussianFilter->SetVariance(variance); gaussianFilter->Update(); typename LaplacianFilter::Pointer laplaceFilter = LaplacianFilter::New(); laplaceFilter->SetInput(gaussianFilter->GetOutput()); laplaceFilter->Update(); mitk::CastToMitkImage(laplaceFilter->GetOutput(), output); } namespace Functor { template class MatrixFirstEigenvalue { public: MatrixFirstEigenvalue() {} virtual ~MatrixFirstEigenvalue() {} int order; inline TOutput operator ()(const TInput& input) { double a, b, c; if (input[0] < 0.01 && input[1] < 0.01 &&input[2] < 0.01 &&input[3] < 0.01 &&input[4] < 0.01 &&input[5] < 0.01) return 0; vnl_symmetric_eigensystem_compute_eigenvals(input[0], input[1], input[2], input[3], input[4], input[5], a, b, c); switch (order) { case 0: return a; case 1: return b; case 2: return c; default: return a; } } bool operator !=(const MatrixFirstEigenvalue) const { return false; } bool operator ==(const MatrixFirstEigenvalue& other) const { return !(*this != other); } }; } template void mitk::CLUtil::itkHessianOfGaussianFilter(itk::Image* itkImage, double variance, std::vector &out) { typedef itk::Image ImageType; typedef itk::Image FloatImageType; typedef itk::HessianRecursiveGaussianImageFilter HessianFilterType; typedef typename HessianFilterType::OutputImageType VectorImageType; typedef Functor::MatrixFirstEigenvalue DeterminantFunctorType; typedef itk::UnaryFunctorImageFilter DetFilterType; typename HessianFilterType::Pointer hessianFilter = HessianFilterType::New(); hessianFilter->SetInput(itkImage); hessianFilter->SetSigma(std::sqrt(variance)); for (unsigned int i = 0; i < VImageDimension; ++i) { mitk::Image::Pointer tmpImage = mitk::Image::New(); typename DetFilterType::Pointer detFilter = DetFilterType::New(); detFilter->SetInput(hessianFilter->GetOutput()); detFilter->GetFunctor().order = i; detFilter->Update(); mitk::CastToMitkImage(detFilter->GetOutput(), tmpImage); out.push_back(tmpImage); } } template void mitk::CLUtil::itkLocalHistograms(itk::Image* itkImage, std::vector &out, int size, int bins) { typedef itk::Image ImageType; typedef itk::MultiHistogramFilter MultiHistogramType; typename MultiHistogramType::Pointer filter = MultiHistogramType::New(); filter->SetInput(itkImage); filter->SetUseImageIntensityRange(true); filter->SetSize(size); filter->SetBins(bins); filter->Update(); for (int i = 0; i < bins; ++i) { mitk::Image::Pointer img = mitk::Image::New(); mitk::CastToMitkImage(filter->GetOutput(i), img); out.push_back(img); } } template void mitk::CLUtil::itkErodeGrayscale(TImageType * image, mitk::Image::Pointer & outimage , unsigned int radius, mitk::CLUtil::MorphologicalDimensions d) { typedef itk::BinaryBallStructuringElement StructureElementType; typedef itk::GrayscaleErodeImageFilter FilterType; StructureElementType ball; itkFitStructuringElement(ball,d, radius); typename FilterType::Pointer filter = FilterType::New(); filter->SetKernel(ball); filter->SetInput(image); filter->Update(); mitk::CastToMitkImage(filter->GetOutput(),outimage); } template void mitk::CLUtil::itkDilateGrayscale(TImageType * image, mitk::Image::Pointer & outimage , unsigned int radius, mitk::CLUtil::MorphologicalDimensions d) { typedef itk::BinaryBallStructuringElement StructureElementType; typedef itk::GrayscaleDilateImageFilter FilterType; StructureElementType ball; itkFitStructuringElement(ball,d, radius); typename FilterType::Pointer filter = FilterType::New(); filter->SetKernel(ball); filter->SetInput(image); filter->Update(); mitk::CastToMitkImage(filter->GetOutput(),outimage); } template void mitk::CLUtil::itkFillHoleGrayscale(TImageType * image, mitk::Image::Pointer & outimage) { typedef itk::GrayscaleFillholeImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput(image); filter->Update(); mitk::CastToMitkImage(filter->GetOutput(),outimage); } #endif diff --git a/Modules/ImageStatistics/mitkImageMaskGenerator.h b/Modules/ImageStatistics/mitkImageMaskGenerator.h index e97bc76855..e9db4ad457 100644 --- a/Modules/ImageStatistics/mitkImageMaskGenerator.h +++ b/Modules/ImageStatistics/mitkImageMaskGenerator.h @@ -1,61 +1,61 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkImageMaskGenerator_h #define mitkImageMaskGenerator_h #include #include #include #include #include namespace mitk { class MITKIMAGESTATISTICS_EXPORT ImageMaskGenerator: public MaskGenerator { public: /** Standard Self typedef */ typedef ImageMaskGenerator Self; typedef MaskGenerator Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ - itkTypeMacro(BinaryImageMaskGenerator, MaskGenerator); + itkTypeMacro(ImageMaskGenerator, MaskGenerator); unsigned int GetNumberOfMasks() const override; itkSetConstObjectMacro(ImageMask, Image) protected: ImageMaskGenerator():Superclass(){ m_InternalMaskUpdateTime = 0; } Image::ConstPointer DoGetMask(unsigned int) override; private: bool IsUpdateRequired() const; void UpdateInternalMask(); mitk::Image::ConstPointer m_ImageMask; mitk::Image::ConstPointer m_InternalMask; unsigned long m_InternalMaskUpdateTime; }; } #endif diff --git a/Modules/ImageStatistics/mitkImageStatisticsCalculator.h b/Modules/ImageStatistics/mitkImageStatisticsCalculator.h index 50ab83f181..f29b365329 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsCalculator.h +++ b/Modules/ImageStatistics/mitkImageStatisticsCalculator.h @@ -1,117 +1,117 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkImageStatisticsCalculator_h #define mitkImageStatisticsCalculator_h #include #include #include #include namespace mitk { class MITKIMAGESTATISTICS_EXPORT ImageStatisticsCalculator: public itk::Object { public: /** Standard Self typedef */ typedef ImageStatisticsCalculator Self; typedef itk::Object Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ - itkTypeMacro(ImageStatisticsCalculator_v2, itk::Object); + itkTypeMacro(ImageStatisticsCalculator, itk::Object); typedef double statisticsValueType; typedef std::map statisticsMapType; typedef itk::Statistics::Histogram HistogramType; typedef unsigned short MaskPixelType; using LabelIndex = ImageStatisticsContainer::LabelValueType; /**Documentation @brief Set the image for which the statistics are to be computed.*/ void SetInputImage(const mitk::Image* image); /**Documentation @brief Set the mask generator that creates the mask which is to be used to calculate statistics. If no more mask is desired simply set @param mask to nullptr*/ void SetMask(mitk::MaskGenerator* mask); /**Documentation @brief Set this if more than one mask should be applied (for instance if a IgnorePixelValueMask were to be used alongside with a segmentation). Both masks are combined using pixel wise AND operation. The secondary mask does not have to be the same size than the primary but they need to have some overlap*/ void SetSecondaryMask(mitk::MaskGenerator* mask); /**Documentation @brief Set number of bins to be used for histogram statistics. If Bin size is set after number of bins, bin size will be used instead!*/ void SetNBinsForHistogramStatistics(unsigned int nBins); /**Documentation @brief Retrieve the number of bins used for histogram statistics. Careful: The return value does not indicate whether NBins or BinSize is used. That solely depends on which parameter has been set last.*/ unsigned int GetNBinsForHistogramStatistics() const; /**Documentation @brief Set bin size to be used for histogram statistics. If nbins is set after bin size, nbins will be used instead!*/ void SetBinSizeForHistogramStatistics(double binSize); /**Documentation @brief Retrieve the bin size for histogram statistics. Careful: The return value does not indicate whether NBins or BinSize is used. That solely depends on which parameter has been set last.*/ double GetBinSizeForHistogramStatistics() const; /**Documentation @brief Returns the statistics. If these requested statistics are not computed yet the computation is done as well. */ ImageStatisticsContainer* GetStatistics(); protected: ImageStatisticsCalculator(){ m_nBinsForHistogramStatistics = 100; m_binSizeForHistogramStatistics = 10; m_UseBinSizeOverNBins = false; }; private: //Calculates statistics for each timestep for image template < typename TPixel, unsigned int VImageDimension > void InternalCalculateStatisticsUnmasked(const itk::Image< TPixel, VImageDimension >* image, TimeStepType timeStep); template < typename TPixel, unsigned int VImageDimension > void InternalCalculateStatisticsMasked(const itk::Image< TPixel, VImageDimension >* image, TimeStepType timeStep); template < typename TPixel, unsigned int VImageDimension > double GetVoxelVolume(const itk::Image* image) const; bool IsUpdateRequired() const; mitk::Image::ConstPointer m_Image; mitk::Image::ConstPointer m_ImageTimeSlice; mitk::Image::ConstPointer m_InternalImageForStatistics; mitk::MaskGenerator::Pointer m_MaskGenerator; mitk::Image::ConstPointer m_InternalMask; mitk::MaskGenerator::Pointer m_SecondaryMaskGenerator; mitk::Image::ConstPointer m_SecondaryMask; unsigned int m_nBinsForHistogramStatistics; double m_binSizeForHistogramStatistics; bool m_UseBinSizeOverNBins; ImageStatisticsContainer::Pointer m_StatisticContainer; }; } #endif diff --git a/Modules/Pharmacokinetics/include/mitkAIFBasedModelBase.h b/Modules/Pharmacokinetics/include/mitkAIFBasedModelBase.h index 0a9a18b411..694f23f81e 100644 --- a/Modules/Pharmacokinetics/include/mitkAIFBasedModelBase.h +++ b/Modules/Pharmacokinetics/include/mitkAIFBasedModelBase.h @@ -1,124 +1,124 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkAIFBasedModelBase_h #define mitkAIFBasedModelBase_h #include "MitkPharmacokineticsExports.h" #include "mitkModelBase.h" #include "itkArray2D.h" namespace mitk { /** \class AIFBasedModelBase * \brief Base Class for all physiological perfusion models using an Aterial Input Function * All AIF based models come with an array of AIF values and the corresponding TimeGrid ( AIF(t)) * This class provides functions for setting the AIF Values and optionally a specific AIF TimeGrid. * It also provides a method for interpolation of the AIF source array to a specified Timegrid that differs from * AIFTimeGrid. The AIF must be set with an itk::Array. If no AIFTimeGrid is specified with the Setter, it is assumed * that the AIFTimeGrid is the same as the ModelTimegrid (e.g. AIF is derived from data set to be fitted). In this * case, AIFvalues must have the same length as ModelTimeGrid, otherwise an exception is generated*/ class MITKPHARMACOKINETICS_EXPORT AIFBasedModelBase : public mitk::ModelBase { public: typedef AIFBasedModelBase Self; typedef ModelBase Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; /** Run-time type information (and related methods). */ - itkTypeMacro(PhysiologciModelBase, AIFBasedModelBase); + itkTypeMacro(AIFBasedModelBase, ModelBase); static const std::string NAME_STATIC_PARAMETER_AIF; static const std::string NAME_STATIC_PARAMETER_AIFTimeGrid; static const std::string UNIT_STATIC_PARAMETER_AIF; static const std::string UNIT_STATIC_PARAMETER_AIFTimeGrid; static const unsigned int NUMBER_OF_STATIC_PARAMETERS; static const std::string X_AXIS_NAME; static const std::string X_AXIS_UNIT; static const std::string Y_AXIS_NAME; static const std::string Y_AXIS_UNIT; /** Typedef for Aterial InputFunction AIF(t)*/ typedef itk::Array AterialInputFunctionType; itkGetConstReferenceMacro(AterialInputFunctionValues, AterialInputFunctionType); itkGetConstReferenceMacro(AterialInputFunctionTimeGrid, TimeGridType); itkSetMacro(AterialInputFunctionValues, AterialInputFunctionType); itkSetMacro(AterialInputFunctionTimeGrid, TimeGridType); std::string GetXAxisName() const override; std::string GetXAxisUnit() const override; std::string GetYAxisName() const override; std::string GetYAxisUnit() const override; /** Returns the TimeGrid used for the AIF. Either the externally set AIF time grid * or the time grid of the model if nothing is set.*/ const TimeGridType& GetCurrentAterialInputFunctionTimeGrid() const; /** Returns the Aterial Input function matching currentTimeGrid * The original values are interpolated to the passed TimeGrid * if currentTimeGrid.Size() = 0 , the Original AIF will be returned*/ const AterialInputFunctionType GetAterialInputFunction(TimeGridType currentTimeGrid) const; ParameterNamesType GetStaticParameterNames() const override; ParametersSizeType GetNumberOfStaticParameters() const override; ParamterUnitMapType GetStaticParameterUnits() const override; protected: AIFBasedModelBase(); ~AIFBasedModelBase() override; /** Reimplementation that checks if AIF and timegrid settings are valid. * @param [out] error Set internally to indicate the error reason if method returns false. Is used by GetSignal() for the * exception comment. * @return Returns true if the model is valid and can compute a signal. Otherwise it returns false.*/ bool ValidateModel(std::string& error) const override; void PrintSelf(std::ostream& os, ::itk::Indent indent) const override; void SetStaticParameter(const ParameterNameType& name, const StaticParameterValuesType& values) override; StaticParameterValuesType GetStaticParameterValue(const ParameterNameType& name) const override; TimeGridType m_AterialInputFunctionTimeGrid; AterialInputFunctionType m_AterialInputFunctionValues; private: //No copy constructor allowed AIFBasedModelBase(const Self& source); void operator=(const Self&); //purposely not implemented }; } #endif diff --git a/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelParameterizer.h b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelParameterizer.h index 5b3f3d45c3..a74a6aa15f 100644 --- a/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelParameterizer.h +++ b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelParameterizer.h @@ -1,92 +1,92 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkDescriptivePharmacokineticBrixModelParameterizer_h #define mitkDescriptivePharmacokineticBrixModelParameterizer_h #include "mitkConcreteModelParameterizerBase.h" #include "mitkDescriptivePharmacokineticBrixModel.h" namespace mitk { /** Parameterizer for the DescriptivePharmacokineticBrixModel that use an image for initializing the model. This parameterizer is amongst others used for pixel based fiting strategies. @sa DescriptivePharmacokineticBrixModelParameterizer*/ class MITKPHARMACOKINETICS_EXPORT DescriptivePharmacokineticBrixModelParameterizer : public ConcreteModelParameterizerBase { public: typedef DescriptivePharmacokineticBrixModelParameterizer Self; typedef ConcreteModelParameterizerBase Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; - itkTypeMacro(ConcreteModelParameterizerBase, ModelParameterizerBase); + itkTypeMacro(DescriptivePharmacokineticBrixModelParameterizer, ConcreteModelParameterizerBase); itkNewMacro(Self); typedef Superclass::ModelBaseType ModelBaseType; typedef Superclass::ModelBasePointer ModelBasePointer; typedef Superclass::ModelType ModelType; typedef Superclass::ModelPointer ModelPointer; typedef Superclass::StaticParameterValueType StaticParameterValueType; typedef Superclass::StaticParameterValuesType StaticParameterValuesType; typedef Superclass::StaticParameterMapType StaticParameterMapType; typedef itk::Image BaseImageType; typedef Superclass::IndexType IndexType; itkSetMacro(Tau, double); itkGetConstReferenceMacro(Tau, double); itkSetConstObjectMacro(BaseImage, BaseImageType); itkGetConstObjectMacro(BaseImage, BaseImageType); /* Returns the global static parameters for the model. * @remark this default implementation assumes no global static parameters exist. * Thus an empty map is returned.*/ StaticParameterMapType GetGlobalStaticParameters() const override; /* Returns the local static parameters for the model at the given index. * @remark this default implementation assumes no local static parameters exist. * Thus an empty map is returned.*/ StaticParameterMapType GetLocalStaticParameters(const IndexType& currentPosition) const override; /** This function returns the default parameterization (e.g. initial parametrization for fitting) defined by the model developer for for the given model.*/ ParametersType GetDefaultInitialParameterization() const override; protected: DescriptivePharmacokineticBrixModelParameterizer(); ~DescriptivePharmacokineticBrixModelParameterizer() override; /**injection time Tau in minutes [min]*/ double m_Tau; /**Pointer to the image that containes the values of the first timestep (base value of the series that should be modelled)*/ BaseImageType::ConstPointer m_BaseImage; private: //No copy constructor allowed DescriptivePharmacokineticBrixModelParameterizer(const Self& source); void operator=(const Self&); //purposely not implemented }; } #endif diff --git a/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h index de5c46e154..36d975a28d 100644 --- a/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h +++ b/Modules/Pharmacokinetics/include/mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer.h @@ -1,90 +1,90 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer_h #define mitkDescriptivePharmacokineticBrixModelValueBasedParameterizer_h #include "mitkConcreteModelParameterizerBase.h" namespace mitk { /** Parameterizer for the DescriptivePharmacokineticBrixModel that don't use an image for initializing the model but a single signal value. This parameterizer is amongst others used for ROI based fiting strategies where no complete image is needed/used. @sa DescriptivePharmacokineticBrixModelParameterizer*/ class MITKPHARMACOKINETICS_EXPORT DescriptivePharmacokineticBrixModelValueBasedParameterizer : public ConcreteModelParameterizerBase { public: typedef DescriptivePharmacokineticBrixModelValueBasedParameterizer Self; typedef ConcreteModelParameterizerBase Superclass; typedef itk::SmartPointer< Self > Pointer; typedef itk::SmartPointer< const Self > ConstPointer; - itkTypeMacro(ConcreteModelParameterizerBase, ModelParameterizerBase); + itkTypeMacro(DescriptivePharmacokineticBrixModelValueBasedParameterizer, ConcreteModelParameterizerBase); itkNewMacro(Self); typedef Superclass::ModelBaseType ModelBaseType; typedef Superclass::ModelBasePointer ModelBasePointer; typedef Superclass::ModelType ModelType; typedef Superclass::ModelPointer ModelPointer; typedef Superclass::StaticParameterValueType StaticParameterValueType; typedef Superclass::StaticParameterValuesType StaticParameterValuesType; typedef Superclass::StaticParameterMapType StaticParameterMapType; typedef itk::Image BaseImageType; typedef Superclass::IndexType IndexType; itkSetMacro(Tau, double); itkGetConstReferenceMacro(Tau, double); itkSetMacro(BaseValue, double); itkGetConstReferenceMacro(BaseValue, double); /* Returns the global static parameters for the model. * @remark this default implementation assumes no global static parameters exist. * Thus an empty map is returned.*/ StaticParameterMapType GetGlobalStaticParameters() const override; /* Returns the local static parameters for the model at the given index. * @remark this default implementation assumes no local static parameters exist. * Thus an empty map is returned.*/ StaticParameterMapType GetLocalStaticParameters(const IndexType& currentPosition) const override; /** This function returns the default parameterization (e.g. initial parametrization for fitting) defined by the model developer for for the given model.*/ ParametersType GetDefaultInitialParameterization() const override; protected: DescriptivePharmacokineticBrixModelValueBasedParameterizer(); ~DescriptivePharmacokineticBrixModelValueBasedParameterizer() override; /**injection time Tau in minutes [min]*/ double m_Tau; /** Contains the base value that should be used by the model.*/ double m_BaseValue; private: //No copy constructor allowed DescriptivePharmacokineticBrixModelValueBasedParameterizer(const Self& source); void operator=(const Self&); //purposely not implemented }; } #endif diff --git a/Modules/SurfaceInterpolation/CMakeLists.txt b/Modules/SurfaceInterpolation/CMakeLists.txt index de0af4ff06..2fc8040ea3 100644 --- a/Modules/SurfaceInterpolation/CMakeLists.txt +++ b/Modules/SurfaceInterpolation/CMakeLists.txt @@ -1,6 +1,6 @@ MITK_CREATE_MODULE( DEPENDS MitkImageExtraction MitkContourModel MitkAlgorithmsExt MitkImageStatistics - PACKAGE_DEPENDS PUBLIC Eigen + PACKAGE_DEPENDS PUBLIC ITK|ITKEigen3 ) add_subdirectory(Testing) diff --git a/Modules/SurfaceInterpolation/mitkCreateDistanceImageFromSurfaceFilter.h b/Modules/SurfaceInterpolation/mitkCreateDistanceImageFromSurfaceFilter.h index 843013952c..9e9f047138 100644 --- a/Modules/SurfaceInterpolation/mitkCreateDistanceImageFromSurfaceFilter.h +++ b/Modules/SurfaceInterpolation/mitkCreateDistanceImageFromSurfaceFilter.h @@ -1,178 +1,178 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkCreateDistanceImageFromSurfaceFilter_h #define mitkCreateDistanceImageFromSurfaceFilter_h #include #include "mitkImageSource.h" #include "mitkProgressBar.h" #include "mitkSurface.h" #include "vnl/vnl_vector_fixed.h" #include "itkImageBase.h" -#include +#include namespace mitk { /** \brief This filter interpolates the 3D surface for a segmented area. The basis for the interpolation are the edge-points of contours that are drawn into an image. The interpolation itself is performed via Radial Basis Function Interpolation. ATTENTION: This filter needs beside the edge points of the delineated contours additionally the normals for each edge point. \sa mitkSurfaceInterpolationController Based on the contour edge points and their normal this filter calculates a distance function with the following properties: - Putting a point into the distance function that lies inside the considered surface gives a negativ scalar value - Putting a point into the distance function that lies outside the considered surface gives a positive scalar value - Putting a point into the distance function that lies exactly on the considered surface gives the value zero With this interpolated distance function a distance image will be created. The desired surface can then be extract e.g. with the marching cubes algorithm. (Within the distance image the surface goes exactly where the pixelvalues are zero) Note that the obtained distance image has always an isotropig spacing. The size (in this case volume) of the image can be adjusted by calling SetDistanceImageVolume(unsigned int volume) which specifies the number ob pixels enclosed by the image. \ingroup Process $Author: fetzer$ */ class MITKSURFACEINTERPOLATION_EXPORT CreateDistanceImageFromSurfaceFilter : public ImageSource { public: typedef vnl_vector_fixed PointType; typedef itk::Image DistanceImageType; typedef DistanceImageType::IndexType IndexType; typedef std::vector NormalList; typedef std::vector CenterList; typedef std::vector SurfaceList; mitkClassMacro(CreateDistanceImageFromSurfaceFilter, ImageSource); itkFactorylessNewMacro(Self); itkCloneMacro(Self); itkGetMacro(DistanceImageSpacing, double); using Superclass::SetInput; // Methods copied from mitkSurfaceToSurfaceFilter virtual void SetInput(const mitk::Surface *surface); virtual void SetInput(unsigned int idx, const mitk::Surface *surface); virtual const mitk::Surface *GetInput(); virtual const mitk::Surface *GetInput(unsigned int idx); virtual void RemoveInputs(mitk::Surface *input); /** \brief Set the size of the output distance image. The size is specified by the image's volume (i.e. in this case how many pixels are enclosed by the image) If non is set, the volume will be 500000 pixels. */ itkSetMacro(DistanceImageVolume, unsigned int); void PrintEquationSystem(); // Resets the filter, i.e. removes all inputs and outputs void Reset(); /** \brief Set whether the mitkProgressBar should be used \a Parameter true for using the progress bar, false otherwise */ void SetUseProgressBar(bool); /** \brief Set the stepsize which the progress bar should proceed \a Parameter The stepsize for progressing */ void SetProgressStepSize(unsigned int stepSize); void SetReferenceImage(itk::ImageBase<3>::Pointer referenceImage); protected: CreateDistanceImageFromSurfaceFilter(); ~CreateDistanceImageFromSurfaceFilter() override; void GenerateData() override; void GenerateOutputInformation() override; private: void CreateSolutionMatrixAndFunctionValues(); double CalculateDistanceValue(PointType p); void FillDistanceImage(); /** * \brief This method fills the given variables with the minimum and * maximum coordinates that contain all input-points in index- and * world-coordinates. * * This method iterates over all input-points and transforms them from * world-coordinates to index-coordinates using the transform of the * reference-Image. * Next, the minimal and maximal index-coordinates are determined that * span an area that contains all given input-points. * These index-coordinates are then transformed back to world-coordinates. * * These minimal and maximal points are then set to the given variables. */ void DetermineBounds(DistanceImageType::PointType &minPointInWorldCoordinates, DistanceImageType::PointType &maxPointInWorldCoordinates, DistanceImageType::IndexType &minPointInIndexCoordinates, DistanceImageType::IndexType &maxPointInIndexCoordinates); void PreprocessContourPoints(); void CreateEmptyDistanceImage(); // Datastructures for the interpolation CenterList m_Centers; NormalList m_Normals; Eigen::MatrixXd m_SolutionMatrix; Eigen::VectorXd m_FunctionValues; Eigen::VectorXd m_Weights; DistanceImageType::Pointer m_DistanceImageITK; itk::ImageBase<3>::Pointer m_ReferenceImage; double m_DistanceImageSpacing; double m_DistanceImageDefaultBufferValue; unsigned int m_DistanceImageVolume; bool m_UseProgressBar; unsigned int m_ProgressStepSize; }; } // namespace #endif diff --git a/SuperBuild.cmake b/SuperBuild.cmake index c287ea3bc3..250dfe8795 100644 --- a/SuperBuild.cmake +++ b/SuperBuild.cmake @@ -1,505 +1,499 @@ #----------------------------------------------------------------------------- # Convenient macro allowing to download a file #----------------------------------------------------------------------------- if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL) set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL https://www.mitk.org/download/thirdparty) endif() macro(downloadFile url dest) file(DOWNLOAD ${url} ${dest} STATUS status) list(GET status 0 error_code) list(GET status 1 error_msg) if(error_code) message(FATAL_ERROR "error: Failed to download ${url} - ${error_msg}") endif() endmacro() #----------------------------------------------------------------------------- # MITK Prerequisites #----------------------------------------------------------------------------- if(UNIX AND NOT APPLE) include(mitkFunctionCheckPackageHeader) # Check for libxt-dev mitkFunctionCheckPackageHeader(StringDefs.h libxt-dev /usr/include/X11/) # Check for libtiff4-dev mitkFunctionCheckPackageHeader(tiff.h libtiff4-dev) endif() # We need a proper patch program. On Linux and MacOS, we assume # that "patch" is available. On Windows, we download patch.exe # if not patch program is found. find_program(PATCH_COMMAND patch) if((NOT PATCH_COMMAND OR NOT EXISTS ${PATCH_COMMAND}) AND WIN32) downloadFile(${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/patch.exe ${CMAKE_CURRENT_BINARY_DIR}/patch.exe) find_program(PATCH_COMMAND patch ${CMAKE_CURRENT_BINARY_DIR}) endif() if(NOT PATCH_COMMAND) message(FATAL_ERROR "No patch program found.") endif() #----------------------------------------------------------------------------- # ExternalProjects #----------------------------------------------------------------------------- get_property(external_projects GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS) if(MITK_CTEST_SCRIPT_MODE) # Write a file containing the list of enabled external project targets. # This file can be read by a ctest script to separately build projects. set(SUPERBUILD_TARGETS ) foreach(proj ${external_projects}) if(MITK_USE_${proj}) list(APPEND SUPERBUILD_TARGETS ${proj}) endif() endforeach() file(WRITE "${CMAKE_BINARY_DIR}/SuperBuildTargets.cmake" "set(SUPERBUILD_TARGETS ${SUPERBUILD_TARGETS})") endif() # A list of "nice" external projects, playing well together with CMake set(nice_external_projects ${external_projects}) list(REMOVE_ITEM nice_external_projects Boost) foreach(proj ${nice_external_projects}) if(MITK_USE_${proj}) set(EXTERNAL_${proj}_DIR "${${proj}_DIR}" CACHE PATH "Path to ${proj} build directory") mark_as_advanced(EXTERNAL_${proj}_DIR) if(EXTERNAL_${proj}_DIR) set(${proj}_DIR ${EXTERNAL_${proj}_DIR}) endif() endif() endforeach() set(EXTERNAL_Boost_ROOT "${Boost_ROOT}" CACHE PATH "Path to Boost directory") mark_as_advanced(EXTERNAL_Boost_ROOT) if(EXTERNAL_Boost_ROOT) set(Boost_ROOT ${EXTERNAL_Boost_ROOT}) endif() if(BUILD_TESTING) set(EXTERNAL_MITK_DATA_DIR "${MITK_DATA_DIR}" CACHE PATH "Path to the MITK data directory") mark_as_advanced(EXTERNAL_MITK_DATA_DIR) if(EXTERNAL_MITK_DATA_DIR) set(MITK_DATA_DIR ${EXTERNAL_MITK_DATA_DIR}) endif() endif() #----------------------------------------------------------------------------- # External project settings #----------------------------------------------------------------------------- include(ExternalProject) include(mitkMacroQueryCustomEPVars) include(mitkFunctionInstallExternalCMakeProject) include(mitkFunctionCleanExternalProject) option(MITK_AUTOCLEAN_EXTERNAL_PROJECTS "Experimental: Clean external project builds if updated" ON) set(ep_prefix "${CMAKE_BINARY_DIR}/ep") set_property(DIRECTORY PROPERTY EP_PREFIX ${ep_prefix}) # Compute -G arg for configuring external projects with the same CMake generator: if(CMAKE_EXTRA_GENERATOR) set(gen "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}") else() set(gen "${CMAKE_GENERATOR}") endif() set(gen_platform ${CMAKE_GENERATOR_PLATFORM}) # Use this value where semi-colons are needed in ep_add args: set(sep "^^") ## if(MSVC_VERSION) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj /MP") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /MP") endif() # This is a workaround for passing linker flags # actually down to the linker invocation set(_cmake_required_flags_orig ${CMAKE_REQUIRED_FLAGS}) set(CMAKE_REQUIRED_FLAGS "-Wl,-rpath") mitkFunctionCheckCompilerFlags(${CMAKE_REQUIRED_FLAGS} _has_rpath_flag) set(CMAKE_REQUIRED_FLAGS ${_cmake_required_flags_orig}) set(_install_rpath_linkflag ) if(_has_rpath_flag) if(APPLE) set(_install_rpath_linkflag "-Wl,-rpath,@loader_path/../lib") else() set(_install_rpath_linkflag "-Wl,-rpath='$ORIGIN/../lib") if(Qt6_DIR) set(_install_rpath_linkflag "${_install_rpath_linkflag}:${Qt6_DIR}/../..") endif() set(_install_rpath_linkflag "${_install_rpath_linkflag}'") endif() endif() set(_install_rpath) if(APPLE) set(_install_rpath "@loader_path/../lib") elseif(UNIX) # this work for libraries as well as executables set(_install_rpath "\$ORIGIN/../lib") if(Qt6_DIR) set(_install_rpath "${_install_rpath}:${Qt6_DIR}/../..") endif() endif() set(ep_common_args -DCMAKE_POLICY_DEFAULT_CMP0091:STRING=OLD -DCMAKE_CXX_EXTENSIONS:STRING=${CMAKE_CXX_EXTENSIONS} -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED} -DCMAKE_MACOSX_RPATH:BOOL=TRUE "-DCMAKE_INSTALL_RPATH:STRING=${_install_rpath}" -DBUILD_TESTING:BOOL=OFF -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_CXX${MITK_CXX_STANDARD}_FLAG}" #debug flags -DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} -DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} #release flags -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} -DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} #relwithdebinfo -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} #link flags -DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ) if(MSVC_VERSION) list(APPEND ep_common_args -DCMAKE_DEBUG_POSTFIX:STRING=d ) set(DCMTK_CMAKE_DEBUG_POSTFIX d) endif() set(ep_common_cache_args ) set(ep_common_cache_default_args "-DCMAKE_PREFIX_PATH:PATH=;${CMAKE_PREFIX_PATH}" "-DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH}" "-DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH}" ) # Pass the CMAKE_OSX variables to external projects if(APPLE) set(MAC_OSX_ARCHITECTURE_ARGS -DCMAKE_OSX_ARCHITECTURES:PATH=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET:PATH=${CMAKE_OSX_DEPLOYMENT_TARGET} -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT} ) set(ep_common_args ${MAC_OSX_ARCHITECTURE_ARGS} ${ep_common_args} ) endif() set(mitk_superbuild_ep_args) set(mitk_depends ) # Include external projects include(CMakeExternals/MITKData.cmake) foreach(p ${external_projects}) set(p_hash "") set(p_file "${CMAKE_SOURCE_DIR}/CMakeExternals/${p}.cmake") if(EXISTS ${p_file}) file(MD5 ${p_file} p_hash) else() foreach(MITK_EXTENSION_DIR ${MITK_ABSOLUTE_EXTENSION_DIRS}) set(MITK_CMAKE_EXTERNALS_EXTENSION_DIR "${MITK_EXTENSION_DIR}/CMakeExternals") set(p_file "${MITK_CMAKE_EXTERNALS_EXTENSION_DIR}/${p}.cmake") if(EXISTS "${p_file}") file(MD5 "${p_file}" p_hash) break() endif() endforeach() endif() if(p_hash) set(p_hash_file "${ep_prefix}/tmp/${p}-hash.txt") if(MITK_AUTOCLEAN_EXTERNAL_PROJECTS) if(EXISTS "${p_hash_file}") file(READ "${p_hash_file}" p_prev_hash) if(NOT p_hash STREQUAL p_prev_hash) mitkCleanExternalProject(${p}) endif() endif() endif() file(WRITE "${p_hash_file}" ${p_hash}) endif() include("${p_file}" OPTIONAL) list(APPEND mitk_superbuild_ep_args -DMITK_USE_${p}:BOOL=${MITK_USE_${p}} ) get_property(_package GLOBAL PROPERTY MITK_${p}_PACKAGE) if(_package) list(APPEND mitk_superbuild_ep_args -D${p}_DIR:PATH=${${p}_DIR}) endif() list(APPEND mitk_depends ${${p}_DEPENDS}) endforeach() if (SWIG_EXECUTABLE) list(APPEND mitk_superbuild_ep_args -DSWIG_EXECUTABLE=${SWIG_EXECUTABLE}) endif() #----------------------------------------------------------------------------- # Set superbuild boolean args #----------------------------------------------------------------------------- set(mitk_cmake_boolean_args BUILD_SHARED_LIBS WITH_COVERAGE BUILD_TESTING MITK_BUILD_ALL_PLUGINS MITK_BUILD_ALL_APPS MITK_BUILD_EXAMPLES MITK_USE_Qt6 MITK_USE_SYSTEM_Boost MITK_USE_BLUEBERRY MITK_USE_OpenMP ) #----------------------------------------------------------------------------- # Create the final variable containing superbuild boolean args #----------------------------------------------------------------------------- set(mitk_superbuild_boolean_args) foreach(mitk_cmake_arg ${mitk_cmake_boolean_args}) list(APPEND mitk_superbuild_boolean_args -D${mitk_cmake_arg}:BOOL=${${mitk_cmake_arg}}) endforeach() if(MITK_BUILD_ALL_PLUGINS) list(APPEND mitk_superbuild_boolean_args -DBLUEBERRY_BUILD_ALL_PLUGINS:BOOL=ON) endif() #----------------------------------------------------------------------------- # MITK Utilities #----------------------------------------------------------------------------- set(proj MITK-Utilities) ExternalProject_Add(${proj} DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS ${mitk_depends} ) #----------------------------------------------------------------------------- # Additional MITK CXX/C Flags #----------------------------------------------------------------------------- set(MITK_ADDITIONAL_C_FLAGS "" CACHE STRING "Additional C Flags for MITK") set(MITK_ADDITIONAL_C_FLAGS_RELEASE "" CACHE STRING "Additional Release C Flags for MITK") set(MITK_ADDITIONAL_C_FLAGS_DEBUG "" CACHE STRING "Additional Debug C Flags for MITK") mark_as_advanced(MITK_ADDITIONAL_C_FLAGS MITK_ADDITIONAL_C_FLAGS_DEBUG MITK_ADDITIONAL_C_FLAGS_RELEASE) set(MITK_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX Flags for MITK") set(MITK_ADDITIONAL_CXX_FLAGS_RELEASE "" CACHE STRING "Additional Release CXX Flags for MITK") set(MITK_ADDITIONAL_CXX_FLAGS_DEBUG "" CACHE STRING "Additional Debug CXX Flags for MITK") mark_as_advanced(MITK_ADDITIONAL_CXX_FLAGS MITK_ADDITIONAL_CXX_FLAGS_DEBUG MITK_ADDITIONAL_CXX_FLAGS_RELEASE) set(MITK_ADDITIONAL_EXE_LINKER_FLAGS "" CACHE STRING "Additional exe linker flags for MITK") set(MITK_ADDITIONAL_SHARED_LINKER_FLAGS "" CACHE STRING "Additional shared linker flags for MITK") set(MITK_ADDITIONAL_MODULE_LINKER_FLAGS "" CACHE STRING "Additional module linker flags for MITK") mark_as_advanced(MITK_ADDITIONAL_EXE_LINKER_FLAGS MITK_ADDITIONAL_SHARED_LINKER_FLAGS MITK_ADDITIONAL_MODULE_LINKER_FLAGS) #----------------------------------------------------------------------------- # MITK Configure #----------------------------------------------------------------------------- if(MITK_INITIAL_CACHE_FILE) set(mitk_initial_cache_arg -C "${MITK_INITIAL_CACHE_FILE}") endif() set(mitk_optional_cache_args ) foreach(type RUNTIME ARCHIVE LIBRARY) if(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY) list(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}) endif() endforeach() # Optional python variables if(MITK_USE_Python3) list(APPEND mitk_optional_cache_args -DMITK_USE_Python3:BOOL=${MITK_USE_Python3} "-DPython3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE}" "-DPython3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIRS}" "-DPython3_LIBRARY:FILEPATH=${Python3_LIBRARY}" "-DPython3_STDLIB:FILEPATH=${Python3_STDLIB}" "-DPython3_SITELIB:FILEPATH=${Python3_SITELIB}" ) endif() if(OPENSSL_ROOT_DIR) list(APPEND mitk_optional_cache_args "-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}" ) endif() if(CMAKE_FRAMEWORK_PATH) list(APPEND mitk_optional_cache_args "-DCMAKE_FRAMEWORK_PATH:PATH=${CMAKE_FRAMEWORK_PATH}" ) endif() -if(Eigen_INCLUDE_DIR) - list(APPEND mitk_optional_cache_args - -DEigen_INCLUDE_DIR:PATH=${Eigen_INCLUDE_DIR} - ) -endif() - # Optional pass through of Doxygen if(DOXYGEN_EXECUTABLE) list(APPEND mitk_optional_cache_args -DDOXYGEN_EXECUTABLE:FILEPATH=${DOXYGEN_EXECUTABLE} ) endif() if(MITK_DOXYGEN_BUILD_ALWAYS) list(APPEND mitk_optional_cache_args -DMITK_DOXYGEN_BUILD_ALWAYS:BOOL=${MITK_DOXYGEN_BUILD_ALWAYS} ) endif() set(proj MITK-Configure) ExternalProject_Add(${proj} LIST_SEPARATOR ${sep} DOWNLOAD_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_GENERATOR_PLATFORM ${gen_platform} CMAKE_CACHE_ARGS # --------------- Build options ---------------- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} "-DCMAKE_CONFIGURATION_TYPES:STRING=${CMAKE_CONFIGURATION_TYPES}" "-DCMAKE_PREFIX_PATH:PATH=${ep_prefix};${CMAKE_PREFIX_PATH}" "-DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH}" "-DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH}" # --------------- Compile options ---------------- -DCMAKE_CXX_EXTENSIONS:STRING=${CMAKE_CXX_EXTENSIONS} -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED} -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${MITK_ADDITIONAL_C_FLAGS}" "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_ADDITIONAL_CXX_FLAGS}" # debug flags "-DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} ${MITK_ADDITIONAL_CXX_FLAGS_DEBUG}" "-DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} ${MITK_ADDITIONAL_C_FLAGS_DEBUG}" # release flags "-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} ${MITK_ADDITIONAL_CXX_FLAGS_RELEASE}" "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} ${MITK_ADDITIONAL_C_FLAGS_RELEASE}" # relwithdebinfo -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} # link flags "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} ${MITK_ADDITIONAL_EXE_LINKER_FLAGS}" "-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} ${MITK_ADDITIONAL_SHARED_LINKER_FLAGS}" "-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ${MITK_ADDITIONAL_MODULE_LINKER_FLAGS}" # Output directories -DMITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY} -DMITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY} -DMITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY} # ------------- Boolean build options -------------- ${mitk_superbuild_boolean_args} ${mitk_optional_cache_args} -DMITK_USE_SUPERBUILD:BOOL=OFF -DMITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION} -DMITK_FAST_TESTING:BOOL=${MITK_FAST_TESTING} -DMITK_XVFB_TESTING:BOOL=${MITK_XVFB_TESTING} -DMITK_XVFB_TESTING_COMMAND:STRING=${MITK_XVFB_TESTING_COMMAND} -DCTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS} # ----------------- Miscellaneous --------------- -DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH} -DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH} -DMITK_CTEST_SCRIPT_MODE:STRING=${MITK_CTEST_SCRIPT_MODE} -DMITK_SUPERBUILD_BINARY_DIR:PATH=${MITK_BINARY_DIR} -DMITK_MODULES_TO_BUILD:INTERNAL=${MITK_MODULES_TO_BUILD} -DMITK_WHITELIST:STRING=${MITK_WHITELIST} -DMITK_WHITELISTS_EXTERNAL_PATH:STRING=${MITK_WHITELISTS_EXTERNAL_PATH} -DMITK_WHITELISTS_INTERNAL_PATH:STRING=${MITK_WHITELISTS_INTERNAL_PATH} -DMITK_EXTENSION_DIRS:STRING=${MITK_EXTENSION_DIRS} -DMITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES} -DMITK_ACCESSBYITK_FLOATING_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES} -DMITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES} -DMITK_ACCESSBYITK_VECTOR_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} -DMITK_ACCESSBYITK_DIMENSIONS:STRING=${MITK_ACCESSBYITK_DIMENSIONS} -DMITK_CUSTOM_REVISION_DESC:STRING=${MITK_CUSTOM_REVISION_DESC} # --------------- External project options --------------- -DMITK_DATA_DIR:PATH=${MITK_DATA_DIR} -DMITK_EXTERNAL_PROJECT_PREFIX:PATH=${ep_prefix} -DCppMicroServices_DIR:PATH=${CppMicroServices_DIR} -DDCMTK_CMAKE_DEBUG_POSTFIX:STRING=${DCMTK_CMAKE_DEBUG_POSTFIX} -DBoost_ROOT:PATH=${Boost_ROOT} -DBOOST_LIBRARYDIR:PATH=${BOOST_LIBRARYDIR} -DMITK_USE_Boost_LIBRARIES:STRING=${MITK_USE_Boost_LIBRARIES} -DQt6_DIR:PATH=${Qt6_DIR} CMAKE_ARGS ${mitk_initial_cache_arg} ${MAC_OSX_ARCHITECTURE_ARGS} ${mitk_superbuild_ep_args} SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} BINARY_DIR ${CMAKE_BINARY_DIR}/MITK-build BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS MITK-Utilities ) mitkFunctionInstallExternalCMakeProject(${proj}) #----------------------------------------------------------------------------- # MITK #----------------------------------------------------------------------------- if(CMAKE_GENERATOR MATCHES ".*Makefiles.*") set(mitk_build_cmd "$(MAKE)") else() set(mitk_build_cmd ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/MITK-build --config ${CMAKE_CFG_INTDIR}) endif() if(NOT DEFINED SUPERBUILD_EXCLUDE_MITKBUILD_TARGET OR NOT SUPERBUILD_EXCLUDE_MITKBUILD_TARGET) set(MITKBUILD_TARGET_ALL_OPTION "ALL") else() set(MITKBUILD_TARGET_ALL_OPTION "") endif() add_custom_target(MITK-build ${MITKBUILD_TARGET_ALL_OPTION} COMMAND ${mitk_build_cmd} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build DEPENDS MITK-Configure ) #----------------------------------------------------------------------------- # Custom target allowing to drive the build of the MITK project itself #----------------------------------------------------------------------------- add_custom_target(MITK COMMAND ${mitk_build_cmd} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build )