diff --git a/Modules/AppUtil/include/mitkBaseApplication.h b/Modules/AppUtil/include/mitkBaseApplication.h index 0321956252..78cd66de27 100644 --- a/Modules/AppUtil/include/mitkBaseApplication.h +++ b/Modules/AppUtil/include/mitkBaseApplication.h @@ -1,317 +1,317 @@ /*============================================================================ 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 mitkBaseApplication_h #define mitkBaseApplication_h #include #include #include #include class ctkPluginContext; class ctkPluginFramework; class QCoreApplication; class QTranslator; namespace mitk { /** * A utility class for starting BlueBerry applications. * * In the simplest case, create an instance of this class and call run(). * This will launch a CTK plugin framework instance and execute the * default application registered by a plug-in via the * org.blueberry.osgi.applications extension point. * * This class contains many convenience methods to: - * - Put the application in \emph{safe mode} which catches unhandled + * - Put the application in safe mode which catches unhandled * exceptions thrown in the Qt event loop and displays an error * message. - * - Put the application in \emph{single mode} which by default + * - Put the application in single mode which by default * sends the command line arguments to an already running instance * of the same application instead of creating a second instance. * - Add a list of library names which should be pre-loaded at * application start-up, e.g. to speed up the initial launch during * the caching process of the plug-in meta-data. * - Set a custom provisioning file to start a specific set of CTK * plug-ins during application start-up. * - Set and get CTK plugin framework properties * * The behavior can further be customized by deriving from BaseApplication * and overriding specific methods, such as: * - initializeLibraryPaths() to add specific library / plugin search paths * - defineOptions(Poco::Util::OptionSet&) to define a custom set of * command line options * - getQApplication() to provide a custom QCoreApplication instance * * A simple but complete example: - * + * \code * #include * * int main(int argc, char* argv[]) * { * mitk::BaseApplication app(argc, argv); * app.setApplicationName("MyApp"); * app.setOrganizationName("MyOrganization"); * * // Run the workbench * return app.run(); * } - * + * \endcode */ class MITKAPPUTIL_EXPORT BaseApplication : public Poco::Util::Application { public: // Command line arguments static const QString ARG_APPLICATION; static const QString ARG_CLEAN; static const QString ARG_CONSOLELOG; static const QString ARG_DEBUG; static const QString ARG_FORCE_PLUGIN_INSTALL; static const QString ARG_HOME; static const QString ARG_NEWINSTANCE; static const QString ARG_NO_LAZY_REGISTRY_CACHE_LOADING; static const QString ARG_NO_REGISTRY_CACHE; static const QString ARG_PLUGIN_CACHE; static const QString ARG_PLUGIN_DIRS; static const QString ARG_PRELOAD_LIBRARY; static const QString ARG_PRODUCT; static const QString ARG_PROVISIONING; static const QString ARG_REGISTRY_MULTI_LANGUAGE; static const QString ARG_SPLASH_IMAGE; static const QString ARG_STORAGE_DIR; static const QString ARG_XARGS; // BlueBerry specific plugin framework properties static const QString PROP_APPLICATION; static const QString PROP_FORCE_PLUGIN_INSTALL; static const QString PROP_NEWINSTANCE; static const QString PROP_NO_LAZY_REGISTRY_CACHE_LOADING; static const QString PROP_NO_REGISTRY_CACHE; static const QString PROP_PRODUCT; static const QString PROP_REGISTRY_MULTI_LANGUAGE; BaseApplication(int argc, char **argv); ~BaseApplication() override; /** * Initialize the Qt library such that a QCoreApplication * instance is available and e.g. Qt widgets can be created. * * This is usually not called directly by the user. */ void initializeQt(); /** * Launches the BlueBerry framework and runs the default application * or the one specified in the PROP_APPLICATION framework property. * * @return The return code of the application after it was shut down. */ int run() override; void printHelp(const std::string &name, const std::string &value); /** * Set the application name. Same as QCoreApplication::setApplicationName. * @param name The application name. */ void setApplicationName(const QString &name); QString getApplicationName() const; /** * Set the organization name. Same as QCoreApplication::setOrganizationName. * @param name The organization name. */ void setOrganizationName(const QString &name); QString getOrganizationName() const; /** * Set the organization domain. Same as QCoreApplication::setOrganizationDomain. * @param name The organization domain. */ void setOrganizationDomain(const QString &name); QString getOrganizationDomain() const; /** * Put the application in single mode, which by default only allows * a single instance of the application to be created. * * Calling this method after run() has been called has no effect. * * @param singleMode */ void setSingleMode(bool singleMode); bool getSingleMode() const; /** * Put the application in safe mode, catching exceptions from the * Qt event loop. * * @param safeMode */ void setSafeMode(bool safeMode); bool getSafeMode() const; /** * Set a list of library names or absoulte file paths * which should be loaded at application start-up. The name * and file path may contain a library version appended at the * end and separated by a '$' charactger. * * For example liborg_mitk_gui_qt_common$1.0. * Platform specific suffixes are appended automatically. * * @param libraryBaseNames A list of library base names. */ void setPreloadLibraries(const QStringList &libraryBaseNames); /** * Get the list of library base names which should be pre-loaded. * * @return A list of pre-loaded libraries. */ QStringList getPreloadLibraries() const; /** * Set the path to the provisioning file. * * By default a provisioning file located in the same directory * as the executable and named \.provisioning * is loaded if it exists. To disable parsing of provisioning * files, use an empty string as the argument. Use a * null QString (\c QString::null ) to reset to the * default behaviour. * * @param filePath An absolute file path to the provisioning file. */ void setProvisioningFilePath(const QString &filePath); /** * Get the file path to the provisioning file. * @return The provisioning file path. */ QString getProvisioningFilePath() const; void setProperty(const QString &property, const QVariant &value); QVariant getProperty(const QString &property) const; void installTranslator(QTranslator*); bool isRunning(); void sendMessage(const QByteArray); protected: void initialize(Poco::Util::Application &self) override; void uninitialize() override; int getArgc() const; char **getArgv() const; /** * Get the framework storage directory for the CTK plugin * framework. This method is called in the initialize(Poco::Util::Application&) * method. It must not be called without a QCoreApplications instance. * * @return The CTK Plugin Framework storage directory. */ virtual QString getCTKFrameworkStorageDir() const; /** * Initialize the CppMicroServices library. * * The default implementation set the CppMicroServices storage * path to the current ctkPluginConstants::FRAMEWORK_STORAGE property * value. * * This method is called in the initialize(Poco::Util::Application&) * after the CTK Plugin Framework storage directory property * was set. */ virtual void initializeCppMicroServices(); /** * Get the QCoreApplication object. * * This method is called in the initialize(Poco::Util::Application&) * method and must create a QCoreApplication instance if the * global qApp variable is not initialized yet. * * @return The current QCoreApplication instance. This method * never returns null. */ virtual QCoreApplication *getQApplication() const; /** * Add plugin library search paths to the CTK Plugin Framework. * * This method is called in the nitialize(Poco::Util::Application&) * method after getQApplication() was called. */ virtual void initializeLibraryPaths(); /** * Runs the application for which the platform was started. The platform * must be running. *

* The given argument is passed to the application being run. If it is an invalid QVariant * then the command line arguments used in starting the platform, and not consumed * by the platform code, are passed to the application as a QStringList. *

- * @param argument the argument passed to the application. May be invalid + * @param args the argument passed to the application. May be invalid * @return the result of running the application * @throws std::exception if anything goes wrong */ int main(const std::vector &args) override; /** * Define command line arguments * @param options */ void defineOptions(Poco::Util::OptionSet &options) override; QSharedPointer getFramework() const; ctkPluginContext *getFrameworkContext() const; /** * Get the initial properties for the CTK plugin framework. * * The returned map contains the initial framework properties for * initializing the CTK plugin framework. The value of specific * properties may change at runtime and differ from the initial * value. * * @return The initial CTK Plugin Framework properties. */ QHash getFrameworkProperties() const; /* * Initialize and display the splash screen if an image filename is given * */ void initializeSplashScreen(QCoreApplication * application) const; private: struct Impl; Impl* d; }; } #endif // MITKBASEAPPLICATION_H diff --git a/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h b/Modules/Classification/CLCore/include/mitkAbstractGlobalImageFeature.h index af235b7825..b72e15a9f5 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 // 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); + 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 //mitkAbstractGlobalImageFeature_h diff --git a/Modules/Classification/CLImportanceWeighting/include/mitkGeneralizedLinearModel.h b/Modules/Classification/CLImportanceWeighting/include/mitkGeneralizedLinearModel.h index 10c4b59fc5..629595486a 100644 --- a/Modules/Classification/CLImportanceWeighting/include/mitkGeneralizedLinearModel.h +++ b/Modules/Classification/CLImportanceWeighting/include/mitkGeneralizedLinearModel.h @@ -1,99 +1,99 @@ /*============================================================================ 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 mitkGeneralizedLinearModel_h #define mitkGeneralizedLinearModel_h #include #include #include namespace mitk { /** * \brief Generalized Linear Model that allows linear models for non-gaussian data * * Generalized linear models are an extension of standard linear models that allow * a different apperance of the data. This is for example usefull to calculate * Logistic regressions. */ class MITKCLIMPORTANCEWEIGHTING_EXPORT GeneralizedLinearModel { public: /** * \brief Initialization of the GLM. The parameters needs to be passed at the beginning. * * Constructor for a GLM. During the creation process the glm model parameter * are guessed. * * @param xData The input data matrix. * @param yData The output data matrix. The values of y must meet the requirements of the link and distribution. * @param addConstantColumn Default=True. If True an constant value is added to each row allowing a constant factor in the model. */ GeneralizedLinearModel (const vnl_matrix &xData, const vnl_vector &yData, bool addConstantColumn=true); /** * \brief Predicts the value corresponding to the given vector. * * From the learned data a guess is given depending on the provided input vector. The * value depend on the b-values of the learned model as well as on the chosen link and * distribution. * * No input validation is done. The data and the learned model might not match! * - * @paaram c Column for which the data is guessed. + * @param c Column for which the data is guessed. */ double Predict(const vnl_vector &c); /** * \brief Predicts the value corresponding to the given matrix. * * From the learned data a guess is given depending on the provided input matrix. The * value depend on the b-values of the learned model as well as on the chosen link and * distribution. * * No input validation is done. The data and the learned model might not match! * - * @paaram x Matrix for which the data is guessed. + * @param x Matrix for which the data is guessed. */ vnl_vector Predict(const vnl_matrix &x); /** * \brief Estimation of the exponential factor for a given function * * Gives the exponential part of a link function. Only suitable for log-it models. This * is especially usefull for calculating the weights for transfer learning since it * is equal to the weights. * */ vnl_vector ExpMu(const vnl_matrix &x); /** * \brief Returns the b-Vector for the estimation */ vnl_vector B(); private: // Estimates the rank of the matrix and creates a permutation vector so // that the most important columns are first. Depends on a QR-algorithm. void EstimatePermutation(const vnl_matrix &xData); vnl_vector m_Permutation; // Holds a permutation matrix which is used during calculation of B vnl_vector m_B; // B-Values. Linear componentn of the model. bool m_AddConstantColumn; // If true, a constant value is added to each row // int m_Rank; // The estimated input rank of the matrix. }; } #endif //mitkGeneralizedLInearModel_h diff --git a/Modules/Classification/CLUtilities/include/mitkCLUtil.h b/Modules/Classification/CLUtilities/include/mitkCLUtil.h index 46cd3714e4..6202e9197b 100644 --- a/Modules/Classification/CLUtilities/include/mitkCLUtil.h +++ b/Modules/Classification/CLUtilities/include/mitkCLUtil.h @@ -1,583 +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 namespace mitk { class MITKCLUTILITIES_EXPORT CLUtil { public: /// /// \brief The MorphologicalDimensions enum /// enum MorphologicalDimensions { Axial,Coronal,Sagital,All }; /// /// \brief CreateCheckerBoardPredictionMask /// \param image /// \param outimage /// static void CreateCheckerboardMask(mitk::Image::Pointer image, mitk::Image::Pointer & outimage); /// /// \brief InterpolateCreateCheckerboardPrediction - /// \param image + /// \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 - /// \param sigma2 /// static void LaplacianOfGaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed, double sigma1); /// /// \brief SubtractGaussianFilter /// \param image - /// \param smoothed (Result is sigma1-sigma2) - /// \param sigma1 - /// \param sigma2 + /// \param out + /// \param sigma /// static void HessianOfGaussianFilter(mitk::Image::Pointer image, std::vector &out, double sigma); /// /// \brief Local Histogram /// \param image - /// \param smoothed (Result is sigma1-sigma2) - /// \param sigma1 - /// \param sigma2 + /// \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 - /// \param outimage /// 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 in_img + /// \param img /// \param mask - /// \param out_matrix /// 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 BinaryImage - /// \param BinaryImage - /// \param Size of the StructuringElement - /// \param Dimension + /// \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 BinaryImage - /// \param BinaryImage - /// \param Size of the StructuringElement - /// \param Dimension + /// \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 BinaryImage - /// \param BinaryImage - /// \param Size of the StructuringElement - /// \param Dimension + /// \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 MultilabelImage + /// \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 BinaryImage - /// \param BinaryImage - /// \param MultilabelImage - /// \param Number of components found in the image + /// \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 MultiLabelImage + /// \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/DataCollection/DataHolder/mitkDataCollection.h b/Modules/Classification/DataCollection/DataHolder/mitkDataCollection.h index 19620e97a9..ec35e2b844 100644 --- a/Modules/Classification/DataCollection/DataHolder/mitkDataCollection.h +++ b/Modules/Classification/DataCollection/DataHolder/mitkDataCollection.h @@ -1,287 +1,286 @@ /*============================================================================ 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. ============================================================================*/ #ifdef _MSC_VER # pragma warning (disable : 4996) #endif #ifndef mitkDataCollection_H_ #define mitkDataCollection_H_ //#include //#include //#include "itkObjectFactory.h" //#include "mitkCommon.h" #include #include #include #include /** * \brief DataCollection - Class to facilitate loading/accessing structured data * * Data is grouped into a collection that may contain further (sub) collections or images. * * Exemplary structure * * Collection (e.g. Patient) * | * |-- Sub-Collection1 (e.g. follow-up 1) * | | * | |-- DataItem (e.g. T1) * | |-- DataItem (e.g. T2) * | * |-- Sub-Collection2 (e.g. follow-up 2) * | | * | |-- DataItem (e.g. T1) * | |-- DataItem (e.g. T2) * */ namespace mitk { class MITKDATACOLLECTION_EXPORT DataCollection : public BaseData { public: mitkClassMacro(DataCollection, BaseData); itkFactorylessNewMacro(Self); itkCloneMacro(Self); // Needed methods from Basedata void UpdateOutputInformation() override; void SetRequestedRegionToLargestPossibleRegion() override; bool RequestedRegionIsOutsideOfTheBufferedRegion() override; bool VerifyRequestedRegion() override; void SetRequestedRegion(const itk::DataObject *) override; void Init(std::string name); /** * @brief AddData Add a data item * @param data Images/Fibers/DataCollections * @param name name that allows identifying this data (e.g. a category T2, Segmentation , etc ...) - * @param description + * @param filePath * @return */ - size_t AddData(DataObject::Pointer data, std::string name, std::string filePath = ""); /** * @brief SetName - Sets name of DataCollection * @param name */ void SetName(std::string name); std::string GetName() const; std::string GetDataFilePath(size_t index) const; /** * @brief NameToIndex - Get index from data item name * @param name * @return */ size_t NameToIndex(std::string name); /** * @brief IndexToName - Get name from index * @param index * @return */ std::string IndexToName(size_t index) const; /** * @brief HasElement - check if element with this name exists in collection * @param name * @return */ bool HasElement(std::string name); /** * @brief HasElement - check if element with this index exists in collection * @param index * @return */ bool HasElement(size_t index); /** * @brief Size - number of data items in collection * @return */ size_t Size() const; /** * @brief SetData - set/update data item by index * @param data * @param index */ void SetData(itk::DataObject::Pointer data, size_t index); /** * @brief SetData - set/update data item by name * @param data * @param name */ void SetData(itk::DataObject::Pointer data, std::string name); /** * @brief GetData Get original data by index * - * To ensure a mitk::Image is returned use \ref mitk::GetMitkImage + * To ensure a mitk::Image is returned use GetMitkImage * * @param index * @return */ itk::DataObject::Pointer GetData(size_t index); /** * @brief GetData Get original data by name * - * To ensure a mitk::Image is returned use \ref mitk::GetMitkImage + * To ensure a mitk::Image is returned use GetMitkImage * * @param name * @return */ itk::DataObject::Pointer GetData(std::string name); /** * @brief GetMitkImage - casts data to mitk::Image and returns it * * \note returns nullptr is object is no mitk::Image or itk::Image * * @param index * @return */ mitk::Image::Pointer GetMitkImage(size_t index); /** * @brief GetMitkImage - casts data to mitk::Image and returns it * * \note returns nullptr is object is no mitk::Image or itk::Image * * @param name * @return */ mitk::Image::Pointer GetMitkImage(std::string name); /** * @brief GetMitkImage - casts data to privided itk::Image pointer */ template ImageType GetItkImage(size_t index, ImageType* itkImage); /** * @brief GetMitkImage - casts data to privided itk::Image pointer */ template ImageType GetItkImage(std::string name, ImageType* itkImage); itk::DataObject::Pointer& operator[](size_t index); itk::DataObject::Pointer& operator[](std::string &name); /** * @brief SetNameForIndex - sets name for given data item by index * @param index * @param name */ void SetNameForIndex(size_t index, std::string &name); /** * @brief SetXMLFile - sets xml file to which data collection is saved */ void SetXMLFile(std::string absoluteXMlFile); /** * @brief SetXMLFile - gets xml file to which data collection is supposed to be saved */ std::string GetXMLFile(); /** * @brief SetParent - sets the parent collection * @param parent */ void SetParent(mitk::DataCollection* parent); /** * @brief GetParent - returns the parent collection if available else null is returned * @return */ mitk::DataCollection* GetParent(); /** * @brief RemoveIndex - removes element at index * @param index * @return */ bool RemoveIndex(size_t index); /** * @brief RemoveElement - removes element with name * @param name * @return */ bool RemoveElement(std::string& name); /** * @brief Clear - clears the data collection */ void Clear() override; /** * @brief GetDataNode - returns data node containing data at index * @param index * @return */ mitk::DataNode::Pointer GetDataNode(size_t index); /** * @brief GetDataNode - returns data node containing data with name * @param name * @return */ mitk::DataNode::Pointer GetDataNode(std::string name); /** * @brief GetProbabilityMap - returns vectorimage generated out of images with names in the probabilityNamesVector * @param probabilityNamesVector * @return */ mitk::Image::Pointer GetProbabilityMap(std::vector probabilityNamesVector); protected: DataCollection(); ~DataCollection() override; private: // DATA std::string m_Name; std::vector m_DataVector; std::vector m_NameVector; std::vector m_FilePathVector; std::map m_DataNames; mitk::DataCollection * m_Parent; std::string m_XMLFile; // is only filled for the hightest layer when loading a data collection }; } // end namespace #endif diff --git a/Modules/ContourModel/Algorithms/mitkContourModelUtils.h b/Modules/ContourModel/Algorithms/mitkContourModelUtils.h index 2c06664812..42c91c021e 100644 --- a/Modules/ContourModel/Algorithms/mitkContourModelUtils.h +++ b/Modules/ContourModel/Algorithms/mitkContourModelUtils.h @@ -1,91 +1,96 @@ /*============================================================================ 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 mitkContourModelUtils_h #define mitkContourModelUtils_h #include #include #include #include namespace mitk { /** * \brief Helpful methods for working with contours and images * * */ class MITKCONTOURMODEL_EXPORT ContourModelUtils : public itk::Object { public: mitkClassMacroItkParent(ContourModelUtils, itk::Object); /** \brief Projects a contour onto an image point by point. Converts from world to index coordinates. + \param slice + \param contourIn3D \param correctionForIpSegmentation adds 0.5 to x and y index coordinates (difference between ipSegmentation and MITK contours) + \param constrainToInside */ static ContourModel::Pointer ProjectContourTo2DSlice(Image *slice, ContourModel *contourIn3D, bool correctionForIpSegmentation, bool constrainToInside); /** \brief Projects a slice index coordinates of a contour back into world coordinates. + \param sliceGeometry + \param contourIn2D \param correctionForIpSegmentation subtracts 0.5 to x and y index coordinates (difference between ipSegmentation and MITK contours) */ static ContourModel::Pointer BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry, ContourModel *contourIn2D, bool correctionForIpSegmentation = false); /** \brief Fill a contour in a 2D slice with a specified pixel value at time step 0. */ static void FillContourInSlice(ContourModel *projectedContour, Image *sliceImage, mitk::Image::Pointer workingImage, int paintingPixelValue = 1); /** \brief Fill a contour in a 2D slice with a specified pixel value at a given time step. */ static void FillContourInSlice(ContourModel *projectedContour, unsigned int timeStep, Image *sliceImage, mitk::Image::Pointer workingImage, int paintingPixelValue = 1); /** \brief Fills a image (filledImage) into another image (resultImage) by incorporating the rules of LabelSet-Images */ static void FillSliceInSlice(vtkSmartPointer filledImage, vtkSmartPointer resultImage, mitk::Image::Pointer image, int paintingPixelValue); /** \brief Move the contour in time step 0 to to a new contour model at the given time step. */ static ContourModel::Pointer MoveZerothContourTimeStep(const ContourModel *contour, unsigned int timeStep); protected: ContourModelUtils(); ~ContourModelUtils() override; }; } #endif diff --git a/Modules/ContourModel/DataManagement/mitkContourModel.h b/Modules/ContourModel/DataManagement/mitkContourModel.h index 7cded5022d..45aae9bcda 100644 --- a/Modules/ContourModel/DataManagement/mitkContourModel.h +++ b/Modules/ContourModel/DataManagement/mitkContourModel.h @@ -1,452 +1,453 @@ /*============================================================================ 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 _MITK_CONTOURMODEL_H_ #define _MITK_CONTOURMODEL_H_ #include "mitkBaseData.h" #include "mitkCommon.h" #include #include namespace mitk { /** \brief ContourModel is a structure of linked vertices defining a contour in 3D space. The vertices are stored in a mitk::ContourElement is stored for each timestep. The contour line segments are implicitly defined by the given linked vertices. By default two control points are are linked by a straight line.It is possible to add vertices at front and end of the contour and to iterate in both directions. Points are specified containing coordinates and additional (data) information, see mitk::ContourElement. For accessing a specific vertex either an index or a position in 3D Space can be used. The vertices are best accessed by using a VertexIterator. Interaction with the contour is thus available without any mitk interactor class using the api of ContourModel. It is possible to shift single vertices also as shifting the whole contour. A contour can be either open like a single curved line segment or closed. A closed contour can for example represent a jordan curve. \section mitkContourModelDisplayOptions Display Options The default mappers for this data structure are mitk::ContourModelGLMapper2D and mitk::ContourModelMapper3D. See these classes for display options which can can be set via properties. */ class MITKCONTOURMODEL_EXPORT ContourModel : public BaseData { public: mitkClassMacro(ContourModel, BaseData); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /*+++++++++++++++ typedefs +++++++++++++++++++++++++++++++*/ typedef mitk::ContourElement::VertexType VertexType; typedef mitk::ContourElement::VertexListType VertexListType; typedef mitk::ContourElement::VertexIterator VertexIterator; typedef mitk::ContourElement::ConstVertexIterator ConstVertexIterator; typedef std::vector ContourModelSeries; /*+++++++++++++++ END typedefs ++++++++++++++++++++++++++++*/ /** \brief Possible interpolation of the line segments between control points */ enum LineSegmentInterpolation { LINEAR, B_SPLINE }; /*++++++++++++++++ inline methods +++++++++++++++++++++++*/ /** \brief Get the current selected vertex. */ VertexType *GetSelectedVertex() { return this->m_SelectedVertex; } /** \brief Deselect vertex. */ void Deselect() { this->m_SelectedVertex = nullptr; } /** \brief Set selected vertex as control point */ void SetSelectedVertexAsControlPoint(bool isControlPoint = true) { if (this->m_SelectedVertex) { m_SelectedVertex->IsControlPoint = isControlPoint; this->Modified(); } } /** \brief Set the interpolation of the line segments between control points. */ void SetLineSegmentInterpolation(LineSegmentInterpolation interpolation) { this->m_lineInterpolation = interpolation; this->Modified(); } /** \brief Get the interpolation of the line segments between control points. */ LineSegmentInterpolation GetLineSegmentInterpolation() { return this->m_lineInterpolation; } /*++++++++++++++++ END inline methods +++++++++++++++++++++++*/ /** \brief Add a vertex to the contour at given timestep. The vertex is added at the end of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertex(mitk::Point3D &vertex, int timestep = 0); /** \brief Add a vertex to the contour at given timestep. The vertex is added at the end of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertex(VertexType &vertex, int timestep = 0); /** \brief Add a vertex to the contour at given timestep. The vertex is added at the end of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeSlicedGeometry will not be expanded. */ void AddVertex(const VertexType *vertex, int timestep = 0); /** \brief Add a vertex to the contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) \param isControlPoint - specifies the vertex to be handled in a special way (e.g. control points will be rendered). @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertex(mitk::Point3D &vertex, bool isControlPoint, int timestep = 0); /** \brief Add a vertex to the contour at given timestep AT THE FRONT of the contour. The vertex is added at the FRONT of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertexAtFront(mitk::Point3D &vertex, int timestep = 0); /** \brief Add a vertex to the contour at given timestep AT THE FRONT of the contour. The vertex is added at the FRONT of contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertexAtFront(VertexType &vertex, int timestep = 0); /** \brief Add a vertex to the contour at given timestep AT THE FRONT of the contour. \param vertex - coordinate representation of a control point \param timestep - the timestep at which the vertex will be add ( default 0) \param isControlPoint - specifies the vertex to be handled in a special way (e.g. control points will be rendered). @note Adding a vertex to a timestep which exceeds the timebounds of the contour will not be added, the TimeGeometry will not be expanded. */ void AddVertexAtFront(mitk::Point3D &vertex, bool isControlPoint, int timestep = 0); /** \brief Insert a vertex at given index. */ void InsertVertexAtIndex(mitk::Point3D &vertex, int index, bool isControlPoint = false, int timestep = 0); /** \brief Set a coordinates for point at given index. */ bool SetVertexAt(int pointId, const mitk::Point3D &point, unsigned int timestep = 0); /** \brief Set a coordinates for point at given index. */ bool SetVertexAt(int pointId, const VertexType *vertex, unsigned int timestep = 0); /** \brief Return if the contour is closed or not. */ bool IsClosed(int timestep = 0) const; /** \brief Concatenate two contours. The starting control point of the other will be added at the end of the contour. + \param other \param timestep - the timestep at which the vertex will be add ( default 0) \param check - check for intersections ( default false) */ void Concatenate(mitk::ContourModel *other, int timestep = 0, bool check = false); /** \brief Returns a const VertexIterator at the start element of the contour. @throw mitk::Exception if the timestep is invalid. */ VertexIterator Begin(int timestep = 0) const; /** \brief Returns a const VertexIterator at the start element of the contour. @throw mitk::Exception if the timestep is invalid. */ VertexIterator IteratorBegin(int timestep = 0) const; /** \brief Returns a const VertexIterator at the end element of the contour. @throw mitk::Exception if the timestep is invalid. */ VertexIterator End(int timestep = 0) const; /** \brief Returns a const VertexIterator at the end element of the contour. @throw mitk::Exception if the timestep is invalid. */ VertexIterator IteratorEnd(int timestep = 0) const; /** \brief Close the contour. The last control point will be linked with the first point. */ virtual void Close(int timestep = 0); /** \brief Set isClosed to false contour. The link between the last control point the first point will be removed. */ virtual void Open(int timestep = 0); /** \brief Set closed property to given boolean. false - The link between the last control point the first point will be removed. true - The last control point will be linked with the first point. */ virtual void SetClosed(bool isClosed, int timestep = 0); /** \brief Returns the number of vertices at a given timestep. \param timestep - default = 0 */ int GetNumberOfVertices(int timestep = 0) const; /** \brief Returns whether the contour model is empty at a given timestep. \param timestep - default = 0 */ virtual bool IsEmpty(int timestep) const; /** \brief Returns whether the contour model is empty. */ bool IsEmpty() const override; /** \brief Returns the vertex at the index position within the container. */ virtual const VertexType *GetVertexAt(int index, int timestep = 0) const; /** \brief Remove a vertex at given timestep within the container. \return index of vertex. -1 if not found. */ int GetIndex(const VertexType *vertex, int timestep = 0); /** \brief Check if there isn't something at this timestep. */ bool IsEmptyTimeStep(unsigned int t) const override; /** \brief Check if mouse cursor is near the contour. */ virtual bool IsNearContour(mitk::Point3D &point, float eps, int timestep); /** \brief Mark a vertex at an index in the container as selected. */ bool SelectVertexAt(int index, int timestep = 0); /** \brief Mark a vertex at an index in the container as control point. */ bool SetControlVertexAt(int index, int timestep = 0); /** \brief Mark a vertex at a given position in 3D space. \param point - query point in 3D space \param eps - radius for nearest neighbour search (error bound). \param timestep - search at this timestep @return true = vertex found; false = no vertex found */ bool SelectVertexAt(mitk::Point3D &point, float eps, int timestep = 0); /* \pararm point - query point in 3D space \pararm eps - radius for nearest neighbour search (error bound). \pararm timestep - search at this timestep @return true = vertex found; false = no vertex found */ bool SetControlVertexAt(mitk::Point3D &point, float eps, int timestep = 0); /** \brief Remove a vertex at given index within the container. @return true = the vertex was successfuly removed; false = wrong index. */ bool RemoveVertexAt(int index, int timestep = 0); /** \brief Remove a vertex at given timestep within the container. @return true = the vertex was successfuly removed. */ bool RemoveVertex(const VertexType *vertex, int timestep = 0); /** \brief Remove a vertex at a query position in 3D space. The vertex to be removed will be search by nearest neighbour search. Note that possibly no vertex at this position and eps is stored inside the contour. @return true = the vertex was successfuly removed; false = no vertex found. */ bool RemoveVertexAt(mitk::Point3D &point, float eps, int timestep = 0); /** \brief Shift the currently selected vertex by a translation vector. \param translate - the translation vector. */ void ShiftSelectedVertex(mitk::Vector3D &translate); /** \brief Shift the whole contour by a translation vector at given timestep. \param translate - the translation vector. \param timestep - at this timestep the contour will be shifted. */ void ShiftContour(mitk::Vector3D &translate, int timestep = 0); /** \brief Clear the storage container at given timestep. All control points are removed at timestep. */ virtual void Clear(int timestep); /** \brief Initialize all data objects */ void Initialize() override; /** \brief Initialize object with specs of other contour. Note: No data will be copied. */ void Initialize(mitk::ContourModel &other); /*++++++++++++++++++ method inherit from base data +++++++++++++++++++++++++++*/ /** \brief Inherit from base data - no region support available for contourModel objects. */ void SetRequestedRegionToLargestPossibleRegion() override; /** \brief Inherit from base data - no region support available for contourModel objects. */ bool RequestedRegionIsOutsideOfTheBufferedRegion() override; /** \brief Inherit from base data - no region support available for contourModel objects. */ bool VerifyRequestedRegion() override; /** \brief Get the updated geometry with recomputed bounds. */ virtual const mitk::BaseGeometry *GetUpdatedGeometry(int t = 0); /** \brief Get the BaseGeometry for timestep t. */ virtual mitk::BaseGeometry *GetGeometry(int t = 0) const; /** \brief Inherit from base data - no region support available for contourModel objects. */ void SetRequestedRegion(const itk::DataObject *data) override; /** \brief Expand the timebounds of the TimeGeometry to given number of timesteps. */ void Expand(unsigned int timeSteps) override; /** \brief Update the OutputInformation of a ContourModel object The BoundingBox of the contour will be updated, if necessary. */ void UpdateOutputInformation() override; /** \brief Clear the storage container. The object is set to initial state. All control points are removed and the number of timesteps are set to 1. */ void Clear() override; /** \brief overwrite if the Data can be called by an Interactor (StateMachine). */ void ExecuteOperation(Operation *operation) override; /** \brief Redistributes ontrol vertices with a given period (as number of vertices) \param period - the number of vertices between control points. \param timestep - at this timestep all lines will be rebuilt. */ virtual void RedistributeControlVertices(int period, int timestep); protected: mitkCloneMacro(Self); ContourModel(); ContourModel(const mitk::ContourModel &other); ~ContourModel() override; // inherit from BaseData. called by Clear() void ClearData() override; // inherit from BaseData. Initial state of a contour with no vertices and a single timestep. void InitializeEmpty() override; // Shift a vertex void ShiftVertex(VertexType *vertex, mitk::Vector3D &vector); // Storage with time resolved support. ContourModelSeries m_ContourSeries; // The currently selected vertex. VertexType *m_SelectedVertex; // The interpolation of the line segment between control points. LineSegmentInterpolation m_lineInterpolation; // only update the bounding geometry if necessary bool m_UpdateBoundingBox; }; itkEventMacro(ContourModelEvent, itk::AnyEvent); itkEventMacro(ContourModelShiftEvent, ContourModelEvent); itkEventMacro(ContourModelSizeChangeEvent, ContourModelEvent); itkEventMacro(ContourModelAddEvent, ContourModelSizeChangeEvent); itkEventMacro(ContourModelRemoveEvent, ContourModelSizeChangeEvent); itkEventMacro(ContourModelExpandTimeBoundsEvent, ContourModelEvent); itkEventMacro(ContourModelClosedEvent, ContourModelEvent); } #endif diff --git a/Modules/ContourModel/DataManagement/mitkContourModelSet.h b/Modules/ContourModel/DataManagement/mitkContourModelSet.h index d23664374e..e98b8ccdf2 100644 --- a/Modules/ContourModel/DataManagement/mitkContourModelSet.h +++ b/Modules/ContourModel/DataManagement/mitkContourModelSet.h @@ -1,120 +1,120 @@ /*============================================================================ 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 _mitkContourModelSet_H_ #define _mitkContourModelSet_H_ #include "mitkCommon.h" #include #include "mitkContourModel.h" #include namespace mitk { /** \brief */ class MITKCONTOURMODEL_EXPORT ContourModelSet : public mitk::BaseData { public: mitkClassMacro(ContourModelSet, mitk::BaseData); itkFactorylessNewMacro(Self); itkCloneMacro(Self); typedef std::deque ContourModelListType; typedef ContourModelListType::iterator ContourModelSetIterator; // start of inline methods /** \brief Return an iterator a the front. */ virtual ContourModelSetIterator Begin() { return this->m_Contours.begin(); } /** \brief Return an iterator a the front. */ virtual ContourModelSetIterator End() { return this->m_Contours.end(); } /** \brief Returns the number of contained contours. */ virtual int GetSize() const { return this->m_Contours.size(); } // end of inline methods /** \brief Add a ContourModel to the container. */ virtual void AddContourModel(mitk::ContourModel &contourModel); /** \brief Add a ContourModel to the container. */ virtual void AddContourModel(mitk::ContourModel::Pointer contourModel); /** \brief Returns the ContourModel a given index \param index */ virtual mitk::ContourModel *GetContourModelAt(int index) const; /** \brief Returns the container of the contours. */ ContourModelListType *GetContourModelList(); /** \brief Returns a bool whether the container is empty or not. */ bool IsEmpty() const override; /** \brief Remove the given ContourModel from the container if exists. - \param ContourModel - the ContourModel to be removed. + \param contourModel - the ContourModel to be removed. */ virtual bool RemoveContourModel(mitk::ContourModel *contourModel); /** \brief Remove a ContourModel at given index within the container if exists. \param index - the index where the ContourModel should be removed. */ virtual bool RemoveContourModelAt(int index); /** \brief Clear the storage container. */ void Clear() override; //////////////// inherit from mitk::BaseData //////////////////// /* NO support for regions ! */ void SetRequestedRegionToLargestPossibleRegion() override {} bool RequestedRegionIsOutsideOfTheBufferedRegion() override { return false; } bool VerifyRequestedRegion() override { return true; } void SetRequestedRegion(const itk::DataObject *) override {} /** \brief Update the OutputInformation of a ContourModel object The BoundingBox of the contour will be updated, if necessary. */ void UpdateOutputInformation() override; //////////////// END inherit from mitk::BaseData //////////////////// protected: mitkCloneMacro(Self); ContourModelSet(); ContourModelSet(const mitk::ContourModelSet &other); ~ContourModelSet() override; // inherit from BaseData. Initial state with no contours and a single timestep. void InitializeEmpty() override; ContourModelListType m_Contours; // only update the bounding geometry if necessary bool m_UpdateBoundingBox; }; } // namespace mitk #endif // _mitkContourModelSet_H_ diff --git a/Modules/ContourModel/IO/mitkContourModelWriter.h b/Modules/ContourModel/IO/mitkContourModelWriter.h index aa0190b395..e338c4eee8 100644 --- a/Modules/ContourModel/IO/mitkContourModelWriter.h +++ b/Modules/ContourModel/IO/mitkContourModelWriter.h @@ -1,169 +1,169 @@ /*============================================================================ 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 _MITK_CONTOURMODEL_WRITER__H_ #define _MITK_CONTOURMODEL_WRITER__H_ #include #include // DEPRECATED #include namespace mitk { /** * @brief XML-based writer for mitk::ContourModels * * XML-based writer for mitk::ContourModels. Multiple ContourModels can be written in * a single XML file by simply setting multiple inputs to the filter. * * The xml file will look like: * * * * * * * * * * * * * * * * * * * * * @ingroup MitkContourModelModule */ class TimeSlicedGeometry; class ContourModelWriter : public mitk::AbstractFileWriter { public: ContourModelWriter(); ~ContourModelWriter() override; using AbstractFileWriter::Write; void Write() override; protected: ContourModelWriter(const ContourModelWriter &other); mitk::ContourModelWriter *Clone() const override; /** * Converts an arbitrary type to a string. The type has to * support the << operator. This works fine at least for integral * data types as float, int, long etc. * @param value the value to convert * @returns the string representation of value */ template std::string ConvertToString(T value); /** * Writes an XML representation of the given point set to * an outstream. The XML-Header an root node is not included! * @param contourModel the point set to be converted to xml * @param out the stream to write to. */ void WriteXML(const mitk::ContourModel *contourModel, std::ostream &out); /** * Writes the geometry information of the TimeGeometry to an outstream. * The root tag is not included. * @param geometry the TimeGeometry of the contour. - * @param the stream to write to. + * @param out the stream to write to. */ void WriteGeometryInformation(const mitk::TimeGeometry *geometry, std::ostream &out); /** * Writes the geometry information of the TimeGeometry to an outstream. * The root tag is not included. * @param geometry the TimeGeometry of the contour. - * @param the stream to write to. + * @param out the stream to write to. * * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201 */ DEPRECATED(void WriteGeometryInformation(const mitk::TimeSlicedGeometry *geometry, std::ostream &out)); /** * Writes an standard xml header to the given stream. * @param file the stream in which the header is written. */ void WriteXMLHeader(std::ostream &file); /** Write a start element tag */ void WriteStartElement(const char *const tag, std::ostream &file); void WriteStartElementWithAttribut(const char *const tag, std::vector attributes, std::vector values, std::ostream &file); /** * Write an end element tag * End-Elements following character data should pass indent = false. */ void WriteEndElement(const char *const tag, std::ostream &file, const bool &indent = true); /** Write character data inside a tag. */ void WriteCharacterData(const char *const data, std::ostream &file); /** Write a start element tag */ void WriteStartElement(std::string &tag, std::ostream &file); /** Write an end element tag */ void WriteEndElement(std::string &tag, std::ostream &file, const bool &indent = true); /** Write character data inside a tag. */ void WriteCharacterData(std::string &data, std::ostream &file); /** Writes empty spaces to the stream according to m_IndentDepth and m_Indent */ void WriteIndent(std::ostream &file); unsigned int m_IndentDepth; unsigned int m_Indent; public: static const char *XML_CONTOURMODEL; static const char *XML_HEAD; static const char *XML_GEOMETRY_INFO; static const char *XML_DATA; static const char *XML_TIME_STEP; static const char *XML_CONTROL_POINTS; static const char *XML_POINT; static const char *XML_X; static const char *XML_Y; static const char *XML_Z; }; } #endif diff --git a/Modules/Core/include/mitkAbstractFileIO.h b/Modules/Core/include/mitkAbstractFileIO.h index b788599622..445d3ec0ba 100644 --- a/Modules/Core/include/mitkAbstractFileIO.h +++ b/Modules/Core/include/mitkAbstractFileIO.h @@ -1,158 +1,159 @@ /*============================================================================ 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 MITKABSTRACTFILEIO_H #define MITKABSTRACTFILEIO_H #include "mitkAbstractFileReader.h" #include "mitkAbstractFileWriter.h" namespace mitk { #ifndef DOXYGEN_SKIP // Skip this code during Doxygen processing, because it only // exists to resolve name clashes when inheriting from both // AbstractFileReader and AbstractFileWriter. class AbstractFileIOReader : public AbstractFileReader { public: virtual ConfidenceLevel GetReaderConfidenceLevel() const { return AbstractFileReader::GetConfidenceLevel(); } ConfidenceLevel GetConfidenceLevel() const override { return this->GetReaderConfidenceLevel(); } protected: AbstractFileIOReader() {} AbstractFileIOReader(const CustomMimeType &mimeType, const std::string &description) : AbstractFileReader(mimeType, description) { } private: virtual IFileReader *ReaderClone() const = 0; IFileReader *Clone() const override { return ReaderClone(); } }; struct AbstractFileIOWriter : public AbstractFileWriter { virtual ConfidenceLevel GetWriterConfidenceLevel() const { return AbstractFileWriter::GetConfidenceLevel(); } ConfidenceLevel GetConfidenceLevel() const override { return this->GetWriterConfidenceLevel(); } protected: AbstractFileIOWriter(const std::string &baseDataType) : AbstractFileWriter(baseDataType) {} AbstractFileIOWriter(const std::string &baseDataType, const CustomMimeType &mimeType, const std::string &description) : AbstractFileWriter(baseDataType, mimeType, description) { } private: virtual IFileWriter *WriterClone() const = 0; IFileWriter *Clone() const override { return WriterClone(); } }; #endif // DOXYGEN_SKIP /** * @ingroup IO * * @brief Abstract class for implementing a reader and writer. */ class MITKCORE_EXPORT AbstractFileIO : public AbstractFileIOReader, public AbstractFileIOWriter { public: Options GetReaderOptions() const; us::Any GetReaderOption(const std::string &name) const; void SetReaderOptions(const Options &options); void SetReaderOption(const std::string &name, const us::Any &value); Options GetWriterOptions() const; us::Any GetWriterOption(const std::string &name) const; void SetWriterOptions(const Options &options); void SetWriterOption(const std::string &name, const us::Any &value); ConfidenceLevel GetReaderConfidenceLevel() const override; ConfidenceLevel GetWriterConfidenceLevel() const override; std::pair, us::ServiceRegistration> RegisterService( us::ModuleContext *context = us::GetModuleContext()); protected: AbstractFileIO(const AbstractFileIO &other); AbstractFileIO(const std::string &baseDataType); /** * Associate this reader instance with the given MIME type. * * If the given MIME type has nothing but its name set, the according MIME type * is looked up in the service registry. * + * @param baseDataType * @param mimeType The MIME type this reader can read. * @param description A human readable description of this reader. * * @throws std::invalid_argument if \c mimeType is empty. * * @see RegisterService */ explicit AbstractFileIO(const std::string &baseDataType, const CustomMimeType &mimeType, const std::string &description); void SetMimeType(const CustomMimeType &mimeType); /** * @return The mime-type this reader can handle. */ const CustomMimeType *GetMimeType() const; void SetReaderDescription(const std::string &description); std::string GetReaderDescription() const; void SetWriterDescription(const std::string &description); std::string GetWriterDescription() const; void SetDefaultReaderOptions(const Options &defaultOptions); Options GetDefaultReaderOptions() const; void SetDefaultWriterOptions(const Options &defaultOptions); Options GetDefaultWriterOptions() const; /** * \brief Set the service ranking for this file reader. * * Default is zero and should only be chosen differently for a reason. * The ranking is used to determine which reader to use if several * equivalent readers have been found. * It may be used to replace a default reader from MITK in your own project. * E.g. if you want to use your own reader for nrrd files instead of the default, * implement it and give it a higher ranking than zero. */ void SetReaderRanking(int ranking); int GetReaderRanking() const; void SetWriterRanking(int ranking); int GetWriterRanking() const; private: AbstractFileIO &operator=(const AbstractFileIO &other); virtual AbstractFileIO *IOClone() const = 0; IFileReader *ReaderClone() const override; IFileWriter *WriterClone() const override; }; } #endif // MITKABSTRACTFILEIO_H diff --git a/Modules/Core/include/mitkAbstractFileReader.h b/Modules/Core/include/mitkAbstractFileReader.h index 83ab25d7f3..ee51b225f8 100644 --- a/Modules/Core/include/mitkAbstractFileReader.h +++ b/Modules/Core/include/mitkAbstractFileReader.h @@ -1,241 +1,239 @@ /*============================================================================ 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 AbstractFileReader_H_HEADER_INCLUDED_C1E7E521 #define AbstractFileReader_H_HEADER_INCLUDED_C1E7E521 // Macro #include // MITK #include #include #include // Microservices #include #include #include namespace us { struct PrototypeServiceFactory; } namespace mitk { class CustomMimeType; /** * @brief Base class for creating mitk::BaseData objects from files or streams. * @ingroup IO */ class MITKCORE_EXPORT AbstractFileReader : public mitk::IFileReader { public: void SetInput(const std::string &location) override; void SetInput(const std::string &location, std::istream *is) override; std::string GetInputLocation() const override; std::istream *GetInputStream() const override; MimeType GetRegisteredMimeType() const; /** * @brief Reads a path or stream and creates a list of BaseData objects. * * The default implementation of this method (1) calls DoRead() * (Implement the specific reader operation there) and (2) it addes general * meta information about the loading process. */ std::vector> Read() override; DataStorage::SetOfObjects::Pointer Read(mitk::DataStorage &ds) override; ConfidenceLevel GetConfidenceLevel() const override; Options GetOptions() const override; us::Any GetOption(const std::string &name) const override; void SetOptions(const Options &options) override; void SetOption(const std::string &name, const us::Any &value) override; void AddProgressCallback(const ProgressCallback &callback) override; void RemoveProgressCallback(const ProgressCallback &callback) override; /** * Associate this reader with the MIME type returned by the current IMimeTypeProvider * service for the provided extension if the MIME type exists, otherwise registers * a new MIME type when RegisterService() is called. * * If no MIME type for \c extension is already registered, a call to RegisterService() * will register a new MIME type and associate this reader instance with it. The MIME * type id can be set via SetMimeType() or it will be auto-generated using \c extension, * having the form "application/vnd.mitk.". * - * @param extension The file extension (without a leading period) for which a registered - * mime-type object is looked up and associated with this reader instance. - * @param description A human readable description of this reader. + * @param context */ us::ServiceRegistration RegisterService(us::ModuleContext *context = us::GetModuleContext()); void UnregisterService(); /** * @return A list of files that were loaded during the last call of Read. Has to be filled by the actual reader class. */ std::vector< std::string > GetReadFiles() override; protected: /** * @brief An input stream wrapper. * * If a reader can only work with input streams, use an instance * of this class to either wrap the specified input stream or * create a new input stream based on the input location in the * file system. */ class MITKCORE_EXPORT InputStream : public std::istream { public: InputStream(IFileReader *writer, std::ios_base::openmode mode = std::ios_base::in); ~InputStream() override; private: std::istream *m_Stream; }; AbstractFileReader(); ~AbstractFileReader() override; AbstractFileReader(const AbstractFileReader &other); /** * Associate this reader instance with the given MIME type. * * If \c mimeType does not provide an extension list, an already * registered mime-type object is used. Otherwise, the first entry in * the extensions list is used to construct a mime-type name and * register it as a new CustomMimeType service object in the default * implementation of RegisterMimeType(). * * @param mimeType The mime type this reader can read. * @param description A human readable description of this reader. * * @throws std::invalid_argument if \c mimeType is empty. * * @see RegisterService */ explicit AbstractFileReader(const CustomMimeType &mimeType, const std::string &description); /** Method that should be implemented by derived classes and does the real loading. * This method is called by Read(). * This method must be implemented for each specific reader. Call * GetInputStream() first and check for a non-null stream to read from. * If the input stream is \c nullptr, use GetInputLocation() to read from a local * file-system path. * * If the reader cannot use streams directly, use GetLocalFileName() instead. * * @return The created BaseData objects. * @throws mitk::Exception * * @see GetLocalFileName() * @see IFileReader::Read() */ virtual std::vector> DoRead() = 0; virtual us::ServiceProperties GetServiceProperties() const; /** * Registers a new CustomMimeType service object. * * This method is called from RegisterService and the default implementation * registers a new mime-type service object if all of the following conditions * are true: * * - TODO * * @param context * @return * @throws std::invalid_argument if \c context is nullptr. */ virtual us::ServiceRegistration RegisterMimeType(us::ModuleContext *context); void SetMimeType(const CustomMimeType &mimeType); /** * @return The mime-type this reader can handle. */ const CustomMimeType *GetMimeType() const; void SetMimeTypePrefix(const std::string &prefix); std::string GetMimeTypePrefix() const; void SetDescription(const std::string &description); std::string GetDescription() const; void SetDefaultOptions(const Options &defaultOptions); Options GetDefaultOptions() const; /** * \brief Set the service ranking for this file reader. * * Default is zero and should only be chosen differently for a reason. * The ranking is used to determine which reader to use if several * equivalent readers have been found. * It may be used to replace a default reader from MITK in your own project. * E.g. if you want to use your own reader for nrrd files instead of the default, * implement it and give it a higher ranking than zero. */ void SetRanking(int ranking); int GetRanking() const; /** * @brief Get a local file name for reading. * * This is a convenience method for readers which cannot work natively * with input streams. If no input stream has been been set, * this method just returns the result of GetLocation(). However, if * SetLocation(std::string, std::istream*) has been called with a non-null * input stream, this method writes the contents of the stream to a temporary * file and returns the name of the temporary file. * * The temporary file is deleted when either SetLocation(std::string, std::istream*) * is called again with a different input stream or the destructor of this * class is called. * * This method does not validate file names set via SetInput(std::string). * * @return A file path in the local file-system for reading. */ std::string GetLocalFileName() const; virtual void SetDefaultDataNodeProperties(DataNode *node, const std::string &filePath); std::vector< std::string > m_ReadFiles; private: AbstractFileReader &operator=(const AbstractFileReader &other); virtual mitk::IFileReader *Clone() const = 0; class Impl; std::unique_ptr d; }; } // namespace mitk #endif /* AbstractFileReader_H_HEADER_INCLUDED_C1E7E521 */ diff --git a/Modules/Core/include/mitkAnnotation.h b/Modules/Core/include/mitkAnnotation.h index 2dffee3c91..91b86cf65f 100644 --- a/Modules/Core/include/mitkAnnotation.h +++ b/Modules/Core/include/mitkAnnotation.h @@ -1,458 +1,458 @@ /*============================================================================ 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 Annotation_H #define Annotation_H #include "mitkServiceInterface.h" #include "usServiceRegistration.h" #include #include #include namespace mitk { /** \brief Base class for all Annotation * This class is to be implemented in order to create Annotation which are managed by a AbstractAnnotationRenderer. * This class contains an internal Propertylist for configuring the appearance of the implemented Overlay. */ class MITKCORE_EXPORT Annotation : public itk::Object { public: /** \brief Container for position and size on the display.*/ struct Bounds { itk::Point Position; itk::Point Size; }; /** \brief Base class for mapper specific rendering ressources. */ class MITKCORE_EXPORT BaseLocalStorage { public: bool IsGenerateDataRequired(mitk::BaseRenderer *renderer, mitk::Annotation *Annotation); inline void UpdateGenerateDataTime() { m_LastGenerateDataTime.Modified(); } inline itk::TimeStamp &GetLastGenerateDataTime() { return m_LastGenerateDataTime; } protected: /** \brief timestamp of last update of stored data */ itk::TimeStamp m_LastGenerateDataTime; }; /** * @brief Set the property (instance of BaseProperty) with key @a propertyKey in the PropertyList * of the @a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-value. * * @warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do * more with properties than just call SetProperty( "key", new SomeProperty("value") ). * * @sa GetProperty * @sa m_PropertyList * @sa m_MapOfPropertyLists */ void SetProperty(const std::string &propertyKey, const BaseProperty::Pointer &property); /** * @brief Replace the property (instance of BaseProperty) with key @a propertyKey in the PropertyList * of the @a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-reference. * * If @a renderer is @a nullptr the property is set in the BaseRenderer-independent * PropertyList of this Annotation. * @sa GetProperty * @sa m_PropertyList * @sa m_MapOfPropertyLists */ void ReplaceProperty(const std::string &propertyKey, const BaseProperty::Pointer &property); /** * @brief Add the property (instance of BaseProperty) if it does * not exist (or always if \a overwrite is \a true) * with key @a propertyKey in the PropertyList * of the @a renderer (if nullptr, use BaseRenderer-independent * PropertyList). This is set-by-value. * * For \a overwrite == \a false the property is \em not changed * if it already exists. For \a overwrite == \a true the method * is identical to SetProperty. * * @sa SetProperty * @sa GetProperty * @sa m_PropertyList * @sa m_MapOfPropertyLists */ void AddProperty(const std::string &propertyKey, const BaseProperty::Pointer &property, bool overwrite = false); /** * @brief Add values from another PropertyList. * * Overwrites values in m_PropertyList only when possible (i.e. when types are compatible). * If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty, - * set the @param replace. + * set \c replace. * - * @param replace true: if @param pList contains a property "visible" of type ColorProperty and our m_PropertyList + * @param pList + * @param replace true: if \c pList contains a property "visible" of type ColorProperty and our m_PropertyList * also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects * behind the pointer. * * @sa SetProperty * @sa ReplaceProperty * @sa m_PropertyList */ void ConcatenatePropertyList(PropertyList *pList, bool replace = false); /** * @brief Get the property (instance of BaseProperty) with key @a propertyKey from the PropertyList * of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If @a renderer is @a nullptr or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Annotation is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ mitk::BaseProperty *GetProperty(const std::string &propertyKey) const; /** * @brief Get the property of type T with key @a propertyKey from the PropertyList * of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If @a renderer is @a nullptr or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Annotation is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ template bool GetProperty(itk::SmartPointer &property, const std::string &propertyKey) const { property = dynamic_cast(GetProperty(propertyKey)); return property.IsNotNull(); } /** * @brief Get the property of type T with key @a propertyKey from the PropertyList * of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If @a renderer is @a nullptr or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Annotation is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ template bool GetProperty(T *&property, const std::string &propertyKey) const { property = dynamic_cast(GetProperty(propertyKey)); return property != nullptr; } /** * @brief Convenience access method for GenericProperty properties * (T being the type of the second parameter) * @return @a true property was found */ template bool GetPropertyValue(const std::string &propertyKey, T &value) const { GenericProperty *gp = dynamic_cast *>(GetProperty(propertyKey)); if (gp != nullptr) { value = gp->GetValue(); return true; } return false; } /** * @brief Convenience access method for bool properties (instances of * BoolProperty) * @return @a true property was found */ bool GetBoolProperty(const std::string &propertyKey, bool &boolValue) const; /** * @brief Convenience access method for int properties (instances of * IntProperty) * @return @a true property was found */ bool GetIntProperty(const std::string &propertyKey, int &intValue) const; /** * @brief Convenience access method for float properties (instances of * FloatProperty) * @return @a true property was found */ bool GetFloatProperty(const std::string &propertyKey, float &floatValue) const; /** * @brief Convenience access method for double properties (instances of * DoubleProperty) * @return @a true property was found */ bool GetDoubleProperty(const std::string &propertyKey, double &doubleValue) const; /** * @brief Convenience access method for string properties (instances of * StringProperty) * @return @a true property was found */ bool GetStringProperty(const std::string &propertyKey, std::string &string) const; /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetIntProperty(const std::string &propertyKey, int intValue); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetBoolProperty(const std::string &propertyKey, bool boolValue); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetFloatProperty(const std::string &propertyKey, float floatValue); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetDoubleProperty(const std::string &propertyKey, double doubleValue); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetStringProperty(const std::string &propertyKey, const std::string &string); /** * @brief Convenience access method for boolean properties (instances * of BoolProperty). Return value is the value of the property. If the property is * not found, the value of @a defaultIsOn is returned. * * Thus, the return value has a different meaning than in the * GetBoolProperty method! * @sa GetBoolProperty */ bool IsOn(const std::string &propertyKey, bool defaultIsOn = true) const { GetBoolProperty(propertyKey, defaultIsOn); return defaultIsOn; } /** * @brief Convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name") * @return @a true property was found */ bool GetName(std::string &nodeName, const std::string &propertyKey = "name") const; /** * @brief Extra convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name"). * * This method does not take the renderer specific * propertylists into account, because the name of an object should never be renderer specific. * @returns a std::string with the name of the object (content of "name" Property). * If there is no "name" Property, an empty string will be returned. */ virtual std::string GetName() const; /** * @brief Extra convenience access method to set the name of an object. * * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". */ virtual void SetName(const std::string &name); /** * @brief Convenience access method for color properties (instances of * ColorProperty) * @return @a true property was found */ bool GetColor(float rgb[], const std::string &propertyKey = "color") const; /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const mitk::Color &color, const std::string &propertyKey = "color"); /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(float red, float green, float blue, const std::string &propertyKey = "color"); /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const float rgb[], const std::string &propertyKey = "color"); /** * @brief Convenience access method for opacity properties (instances of * FloatProperty) * @return @a true property was found */ bool GetOpacity(float &opacity, const std::string &propertyKey = "opacity") const; /** * @brief Convenience method for setting opacity properties (instances of * FloatProperty) */ void SetOpacity(float opacity, const std::string &propertyKey = "opacity"); void SetText(std::string text); std::string GetText() const; void SetFontSize(int fontSize); int GetFontSize() const; /** * @brief Convenience access method for visibility properties (instances * of BoolProperty with property-key "visible") * @return @a true property was found * @sa IsVisible */ bool GetVisibility(bool &visible, const std::string &propertyKey = "visible") const; /** * @brief Convenience access method for visibility properties (instances * of BoolProperty). Return value is the visibility. Default is * visible==true, i.e., true is returned even if the property (@a * propertyKey) is not found. * * Thus, the return value has a different meaning than in the * GetVisibility method! * @sa GetVisibility * @sa IsOn */ bool IsVisible(const std::string &propertyKey = "visible", bool defaultIsOn = true) const; /** * @brief Convenience method for setting visibility properties (instances * of BoolProperty) * @param visible If set to true, the data will be rendered. If false, the render will skip this data. - * @param renderer Specify a renderer if the visibility shall be specific to a renderer - * @param propertykey Can be used to specify a user defined name of the visibility propery. + * @param propertyKey Can be used to specify a user defined name of the visibility propery. */ void SetVisibility(bool visible, const std::string &propertyKey = "visible"); /** \brief Adds the Annotation to the specified renderer. Update Annotation should be called soon in order to apply * all * properties*/ virtual void AddToBaseRenderer(BaseRenderer *renderer) = 0; /** \brief Adds the Annotation to the specified renderer. Update Annotation should be called soon in order to apply * all * properties*/ virtual void AddToRenderer(BaseRenderer *renderer, vtkRenderer *vtkrenderer) = 0; /** \brief Removes the Annotation from the specified renderer. It is not visible anymore then.*/ virtual void RemoveFromBaseRenderer(BaseRenderer *renderer) = 0; /** \brief Removes the Annotation from the specified renderer. It is not visible anymore then.*/ virtual void RemoveFromRenderer(BaseRenderer *renderer, vtkRenderer *vtkrenderer) = 0; /** \brief Applies all properties and should be called before the rendering procedure.*/ virtual void Update(BaseRenderer *renderer) = 0; /** \brief Returns position and size of the Annotation on the display.*/ virtual Bounds GetBoundsOnDisplay(BaseRenderer *renderer) const; /** \brief Sets position and size of the Annotation on the display.*/ virtual void SetBoundsOnDisplay(BaseRenderer *renderer, const Bounds &); void SetForceInForeground(bool forceForeground); bool IsForceInForeground() const; PropertyList *GetPropertyList() const; /** *\brief Returns the id that this device is registered with. The id will only be valid, if the * Annotation has been registered using RegisterAsMicroservice(). */ std::string GetMicroserviceID(); /** *\brief These Constants are used in conjunction with Microservices */ static const std::string US_INTERFACE_NAME; static const std::string US_PROPKEY_AnnotationNAME; static const std::string US_PROPKEY_ID; static const std::string US_PROPKEY_MODIFIED; static const std::string US_PROPKEY_RENDERER_ID; static const std::string US_PROPKEY_AR_ID; /** *\brief Registers this object as a Microservice, making it available to every module and/or plugin. * To unregister, call UnregisterMicroservice(). */ virtual void RegisterAsMicroservice(us::ServiceProperties props); /** *\brief Registers this object as a Microservice, making it available to every module and/or plugin. */ virtual void UnRegisterMicroservice(); void AnnotationModified(); mitkClassMacroItkParent(Annotation, itk::Object); protected: /** \brief explicit constructor which disallows implicit conversions */ Annotation(); /** \brief virtual destructor in order to derive from this class */ ~Annotation() override; /** * @brief BaseRenderer-independent PropertyList * * Properties herein can be overwritten specifically for each BaseRenderer * by the BaseRenderer-specific properties defined in m_MapOfPropertyLists. */ PropertyList::Pointer m_PropertyList; /** * @brief Timestamp of the last change of m_Data */ itk::TimeStamp m_DataReferenceChangedTime; void SetUSProperty(const std::string &propertyKey, us::Any value); private: /** \brief render this Annotation on a foreground renderer */ bool m_ForceInForeground; /** \brief copy constructor */ Annotation(const Annotation &); /** \brief assignment operator */ Annotation &operator=(const Annotation &); private: us::ServiceRegistration m_ServiceRegistration; unsigned long m_PropertyListModifiedObserverTag; void PropertyListModified(const itk::Object *, const itk::EventObject &); }; } // namespace mitk MITK_DECLARE_SERVICE_INTERFACE(mitk::Annotation, "org.mitk.services.Annotation") #endif // Annotation_H diff --git a/Modules/Core/include/mitkApplyTransformMatrixOperation.h b/Modules/Core/include/mitkApplyTransformMatrixOperation.h index 472e147166..649b2dd3f7 100644 --- a/Modules/Core/include/mitkApplyTransformMatrixOperation.h +++ b/Modules/Core/include/mitkApplyTransformMatrixOperation.h @@ -1,50 +1,48 @@ /*============================================================================ 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 mitkApplyTransformMatrixOperation_h_Included #define mitkApplyTransformMatrixOperation_h_Included #include "mitkCommon.h" #include "mitkPointOperation.h" #include #include namespace mitk { class MITKCORE_EXPORT ApplyTransformMatrixOperation : public Operation { public: - //##Documentation - //##@brief Operation that applies a new vtk transform matrix. - //## - //## @param operationType is the type of the operation (see mitkOperation.h; e.g. move or add; Information for - // StateMachine::ExecuteOperation()); - //## @param matrix is the vtk 4x4 vtk matrix of the transformation - //## @param refPoint is the reference point for realigning the plane stack - + /** @brief Operation that applies a new vtk transform matrix. + * + * @param operationType is the type of the operation (see mitkOperation.h; e.g. move or add; Information for StateMachine::ExecuteOperation()); + * @param matrix is the vtk 4x4 vtk matrix of the transformation + * @param refPoint is the reference point for realigning the plane stack + */ ApplyTransformMatrixOperation(OperationType operationType, vtkSmartPointer matrix, mitk::Point3D refPoint); ~ApplyTransformMatrixOperation() override; vtkSmartPointer GetMatrix(); mitk::Point3D GetReferencePoint(); private: vtkSmartPointer m_vtkMatrix; mitk::Point3D m_referencePoint; }; } // namespace mitk #endif diff --git a/Modules/Core/include/mitkArray.h b/Modules/Core/include/mitkArray.h index 73d6b34d26..7709718692 100644 --- a/Modules/Core/include/mitkArray.h +++ b/Modules/Core/include/mitkArray.h @@ -1,143 +1,143 @@ /*============================================================================ 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 MITKARRAY_H_ #define MITKARRAY_H_ #include #include "mitkEqual.h" #include "mitkNumericConstants.h" namespace mitk { /** * Methods to copy from itk::FixedArray s (like mitk::Vector and mitk::Point) into ArrayTypes and vice versa. * ArrayTypes here are all types who implement operator[]. * The two templated methods were made free floating so you may specialize them * for your concrete type. */ /** * @brief Copies elements of an array to this Vector * @param[in] array the array whose values will be copied into the Vector. Must be of a type which overrides the [] * operator * @param[out] toArray the FixedArrray (e.g., mitk::Vector or mitk::Point) which should hold the elements of array. * @attention array must be of dimension NVectorDimension! * @attention this method implicitly converts between data types. */ template void FillArray(itk::FixedArray &toArray, const ArrayType &array) { itk::FixedArray vectorOrPoint; for (unsigned short int var = 0; var < NVectorDimension; ++var) { toArray[var] = array[var]; } } /** * @brief Copies elements of an array to this Vector * @param[in] array the array whose values will be copied into the Vector. Must be of a type which overrides the [] * operator - * @param return the FixedArrray (e.g., mitk::Vector or mitk::Point) which should hold the elements of array. + * @return the FixedArray (e.g., mitk::Vector or mitk::Point) which should hold the elements of array. * @attention array must be of dimension NVectorDimension! * @attention this method implicitly converts between data types. */ template itk::FixedArray FillArray(const ArrayType &array) { itk::FixedArray vectorOrPoint; mitk::FillArray(vectorOrPoint, array); return vectorOrPoint; } /** * @brief Copies the elements of this into an array * @param[in] vectorOrPoint the itk::FixedArray which shall be copied into the array. Can e.g. be of type * mitk::Vector * or mitk::Point * @param[out] array the array which will hold the elements. Must be of a type which overrides the [] operator. * @attention array must be of dimension NVectorDimension! * @attention this method implicitly converts between data types. */ template void ToArray(ArrayType &array, const itk::FixedArray &vectorOrPoint) { for (unsigned short int var = 0; var < NVectorDimension; ++var) { array[var] = vectorOrPoint[var]; } } /** * @brief Copies the elements of this into an array * @param[in] vectorOrPoint the itk::FixedArray which shall be copied into the array. Can e.g. be of type * mitk::Vector * or mitk::Point * @return the array which will hold the elements. Must be of a type which overrides the [] operator. * @attention array must be of dimension NVectorDimension! * @attention this method implicitly converts between data types. */ template ArrayType ToArray(const itk::FixedArray &vectorOrPoint) { ArrayType result; mitk::ToArray(result, vectorOrPoint); return result; } // The FillVector3D and FillVector4D methods are implemented for all common array types here template inline void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z) { out[0] = x; out[1] = y; out[2] = z; } template inline void FillVector4D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z, mitk::ScalarType t) { out[0] = x; out[1] = y; out[2] = z; out[3] = t; } /** * Compares two ArrayTypes of size size. * ArrayTypes are all Objects/Types who have a [] operator. Pay attention not to set size higher * than the actual size of the ArrayType as this will lead to unexpected results. */ template inline bool EqualArray( TArrayType1 &arrayType1, TArrayType2 &arrayType2, int size, ScalarType eps = mitk::eps, bool verbose = false) { bool isEqual = true; for (int var = 0; var < size; ++var) { isEqual = isEqual && Equal(arrayType1[var], arrayType2[var], eps); } ConditionalOutputOfDifference(arrayType1, arrayType2, eps, verbose, isEqual); return isEqual; } } #endif /* MITKARRAY_H_ */ diff --git a/Modules/Core/include/mitkColorProperty.h b/Modules/Core/include/mitkColorProperty.h index 2de38d55e9..70de0bc487 100644 --- a/Modules/Core/include/mitkColorProperty.h +++ b/Modules/Core/include/mitkColorProperty.h @@ -1,96 +1,96 @@ /*============================================================================ 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 MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 #define MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 #include "mitkBaseProperty.h" #include #include namespace mitk { #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4522) #endif /** * @brief Color Standard RGB color typedef (float) * * Standard RGB color typedef to get rid of template argument (float). * Color range is from 0.0f to 1.0f for each component. * * @ingroup Property */ typedef itk::RGBPixel Color; /** * @brief The ColorProperty class RGB color property * @ingroup DataManagement * * @note If you want to apply the mitk::ColorProperty to an mitk::Image * make sure to set the mitk::RenderingModeProperty to a mode which * supports color (e.g. LEVELWINDOW_COLOR). For an example how to use * the mitk::ColorProperty see mitkImageVtkMapper2DColorTest.cpp in - * Core\Code\Rendering. + * Core/Code/Rendering. */ class MITKCORE_EXPORT ColorProperty : public BaseProperty { protected: mitk::Color m_Color; ColorProperty(); ColorProperty(const ColorProperty &other); ColorProperty(const float red, const float green, const float blue); ColorProperty(const float color[3]); ColorProperty(const mitk::Color &color); public: mitkClassMacro(ColorProperty, BaseProperty); itkFactorylessNewMacro(Self); itkCloneMacro(Self) mitkNewMacro1Param(ColorProperty, const float *); mitkNewMacro1Param(ColorProperty, const mitk::Color &); mitkNewMacro3Param(ColorProperty, const float, const float, const float); typedef mitk::Color ValueType; const mitk::Color &GetColor() const; const mitk::Color &GetValue() const; std::string GetValueAsString() const override; void SetColor(const mitk::Color &color); void SetValue(const mitk::Color &color); void SetColor(float red, float green, float blue); using BaseProperty::operator=; private: // purposely not implemented ColorProperty &operator=(const ColorProperty &); itk::LightObject::Pointer InternalClone() const override; bool IsEqual(const BaseProperty &property) const override; bool Assign(const BaseProperty &property) override; }; #ifdef _MSC_VER #pragma warning(pop) #endif } // namespace mitk #endif /* MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 */ diff --git a/Modules/Core/include/mitkCoreServices.h b/Modules/Core/include/mitkCoreServices.h index 1e3f179acd..833cc313c8 100644 --- a/Modules/Core/include/mitkCoreServices.h +++ b/Modules/Core/include/mitkCoreServices.h @@ -1,177 +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 MITKCORESERVICES_H #define MITKCORESERVICES_H #include "MitkCoreExports.h" #include #include #include #include #include #include #include namespace mitk { struct IMimeTypeProvider; class IPropertyAliases; class IPropertyDescriptions; class IPropertyExtensions; class IPropertyFilters; class IPropertyPersistence; class IPropertyRelations; /** * @brief Access MITK core services. * * This class can be used to conveniently access common * MITK Core service objects. Some getter methods where implementations * exist in the core library are guaranteed to return a non-nullptr service object. * * To ensure that CoreServices::Unget() is called after the caller * has finished using a service object, you should use the CoreServicePointer * helper class which calls Unget() when it goes out of scope: * * \code * CoreServicePointer shaderRepo(CoreServices::GetShaderRepository()); * // Do something with shaderRepo * \endcode * * @see CoreServicePointer */ class MITKCORE_EXPORT CoreServices { public: /** * @brief Get an IPropertyAliases instance. * @param context The module context of the module getting the service. * @return A non-nullptr IPropertyAliases instance. */ static IPropertyAliases *GetPropertyAliases(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IPropertyDescriptions instance. * @param context The module context of the module getting the service. * @return A non-nullptr IPropertyDescriptions instance. */ static IPropertyDescriptions *GetPropertyDescriptions(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IPropertyExtensions instance. * @param context The module context of the module getting the service. * @return A non-nullptr IPropertyExtensions instance. */ static IPropertyExtensions *GetPropertyExtensions(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IPropertyFilters instance. * @param context The module context of the module getting the service. * @return A non-nullptr IPropertyFilters instance. */ static IPropertyFilters *GetPropertyFilters(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IPropertyPersistence instance. * @param context The module context of the module getting the service. * @return A non-nullptr IPropertyPersistence instance. */ static IPropertyPersistence *GetPropertyPersistence(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IPropertyRelations instance. * @param context The module context of the module getting the service. * @return A non-nullptr IPropertyRelations instance. */ static IPropertyRelations *GetPropertyRelations(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IMimeTypeProvider instance. * @param context The module context of the module getting the service. * @return A non-nullptr IMimeTypeProvider instance. */ static IMimeTypeProvider *GetMimeTypeProvider(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Unget a previously acquired service instance. * @param service The service instance to be released. + * @param context * @return \c true if ungetting the service was successful, \c false otherwise. */ template static bool Unget(S *service, us::ModuleContext *context = us::GetModuleContext()) { return Unget(context, us_service_interface_iid(), service); } private: static bool Unget(us::ModuleContext *context, const std::string &interfaceId, void *service); // purposely not implemented CoreServices(); CoreServices(const CoreServices &); CoreServices &operator=(const CoreServices &); }; /** * @brief A RAII helper class for core service objects. * * This is class is intended for usage in local scopes; it calls * CoreServices::Unget(S*) in its destructor. You should not construct * multiple CoreServicePointer instances using the same service pointer, * unless it is retrieved by a new call to a CoreServices getter method. * * @see CoreServices */ template class MITK_LOCAL CoreServicePointer { public: explicit CoreServicePointer(S *service, us::ModuleContext* context = us::GetModuleContext()) : m_Service(service), m_Context(context) { assert(service); } ~CoreServicePointer() { try { CoreServices::Unget(m_Service, m_Context); } catch (const std::exception &e) { MITK_ERROR << e.what(); } catch (...) { MITK_ERROR << "Ungetting core service failed."; } } S *operator->() const { return m_Service; } private: S *const m_Service; us::ModuleContext* m_Context; }; } #endif // MITKCORESERVICES_H diff --git a/Modules/Core/include/mitkDataNode.h b/Modules/Core/include/mitkDataNode.h index 13f64e52b6..24f5890c5b 100644 --- a/Modules/Core/include/mitkDataNode.h +++ b/Modules/Core/include/mitkDataNode.h @@ -1,597 +1,597 @@ /*============================================================================ 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 DATATREENODE_H_HEADER_INCLUDED_C1E14338 #define DATATREENODE_H_HEADER_INCLUDED_C1E14338 #include "mitkBaseData.h" //#include "mitkMapper.h" #include "mitkDataInteractor.h" #include "mitkIdentifiable.h" #include "mitkIPropertyOwner.h" #include #include #include "mitkColorProperty.h" #include "mitkPropertyList.h" #include "mitkStringProperty.h" //#include "mitkMapper.h" #include "mitkGeometry3D.h" #include "mitkLevelWindow.h" #include #include class vtkLinearTransform; namespace mitk { class BaseRenderer; class Mapper; /** * \brief Class for nodes of the DataTree * * Contains the data (instance of BaseData), a list of mappers, which can * draw the data, a transform (vtkTransform) and a list of properties * (PropertyList). * \ingroup DataManagement * * \todo clean up all the GetProperty methods. There are too many different flavours... Can most probably be reduced * to * bool GetProperty(type&) * * \warning Change in semantics of SetProperty() since Aug 25th 2006. Check your usage of this method if you do * more with properties than just call SetProperty( "key", new SomeProperty("value") ). */ class MITKCORE_EXPORT DataNode : public itk::DataObject, public IPropertyOwner { public: typedef mitk::Geometry3D::Pointer Geometry3DPointer; typedef std::vector> MapperVector; typedef std::map MapOfPropertyLists; typedef std::vector PropertyListKeyNames; typedef std::set GroupTagList; /** * \brief Definition of an itk::Event that is invoked when * a DataInteractor is set on this DataNode. */ itkEventMacro(InteractorChangedEvent, itk::AnyEvent) mitkClassMacroItkParent(DataNode, itk::DataObject); itkFactorylessNewMacro(Self); // IPropertyProvider BaseProperty::ConstPointer GetConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) const override; std::vector GetPropertyKeys(const std::string &contextName = "", bool includeDefaultContext = false) const override; std::vector GetPropertyContextNames() const override; // IPropertyOwner BaseProperty * GetNonConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) override; void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override; void RemoveProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override; mitk::Mapper *GetMapper(MapperSlotId id) const; /** * \brief Get the data object (instance of BaseData, e.g., an Image) * managed by this DataNode */ BaseData *GetData() const; /** * \brief Get the transformation applied prior to displaying the data as * a vtkTransform * \deprecated use GetData()->GetGeometry()->GetVtkTransform() instead */ vtkLinearTransform *GetVtkTransform(int t = 0) const; /** * \brief Set the data object (instance of BaseData, e.g., an Image) * managed by this DataNode * * Prior set properties are kept if previous data of the node already exists and has the same * type as the new data to be set. Otherwise, the default properties are used. * In case that previous data already exists, the property list of the data node is cleared * before setting new default properties. * * \warning the actor-mode of the vtkInteractor does not work any more, if the transform of the * data-tree-node is connected to the transform of the basedata via vtkTransform->SetInput. */ virtual void SetData(mitk::BaseData *baseData); /** * \brief Set the Interactor. */ virtual void SetDataInteractor(const DataInteractor::Pointer interactor); virtual DataInteractor::Pointer GetDataInteractor() const; mitk::DataNode &operator=(const DataNode &right); mitk::DataNode &operator=(BaseData *right); virtual void SetMapper(MapperSlotId id, mitk::Mapper *mapper); void UpdateOutputInformation() override; void SetRequestedRegionToLargestPossibleRegion() override; bool RequestedRegionIsOutsideOfTheBufferedRegion() override; bool VerifyRequestedRegion() override; void SetRequestedRegion(const itk::DataObject *data) override; void CopyInformation(const itk::DataObject *data) override; /** * \brief The "names" used for (renderer-specific) PropertyLists in GetPropertyList(string). * * All possible values for the "renderer" parameters of * the diverse GetProperty/List() methods. */ PropertyListKeyNames GetPropertyListNames() const; /** * \brief Set the property (instance of BaseProperty) with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-value. * * \warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do * more with properties than just call SetProperty( "key", new SomeProperty("value") ). * * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void SetProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Replace the property (instance of BaseProperty) with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-reference. * * If \a renderer is \a nullptr the property is set in the BaseRenderer-independent * PropertyList of this DataNode. * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void ReplaceProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Add the property (instance of BaseProperty) if it does * not exist (or always if\a overwrite is\a true) * with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent * PropertyList). This is set-by-value. * * For\a overwrite ==\a false the property is\em not changed * if it already exists. For\a overwrite ==\a true the method * is identical to SetProperty. * * \sa SetProperty * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void AddProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr, bool overwrite = false); /** * \brief Get the PropertyList of the \a renderer. If \a renderer is \a * nullptr, the BaseRenderer-independent PropertyList of this DataNode * is returned. * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ mitk::PropertyList *GetPropertyList(const mitk::BaseRenderer *renderer = nullptr) const; mitk::PropertyList *GetPropertyList(const std::string &rendererName) const; /** * \brief Add values from another PropertyList. * * Overwrites values in m_PropertyList only when possible (i.e. when types are compatible). * If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty, - * set the \param replace. + * set \c replace . * * \param replace true: if \param pList contains a property "visible" of type ColorProperty and our m_PropertyList * also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects * behind the pointer. * * \sa SetProperty * \sa ReplaceProperty * \sa m_PropertyList */ void ConcatenatePropertyList(PropertyList *pList, bool replace = false); /** * \brief Get the property (instance of BaseProperty) with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * * If \a fallBackOnDataProperties is true, the data property list is queried as a last resort. * * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ mitk::BaseProperty *GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr, bool fallBackOnDataProperties = true) const; /** * \brief Get the property of type T with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ template bool GetProperty(itk::SmartPointer &property, const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property.IsNotNull(); } /** * \brief Get the property of type T with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ template bool GetProperty(T *&property, const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property != nullptr; } /** * \brief Convenience access method for GenericProperty properties * (T being the type of the second parameter) * \return \a true property was found */ template bool GetPropertyValue(const char *propertyKey, T &value, const mitk::BaseRenderer *renderer = nullptr) const { GenericProperty *gp = dynamic_cast *>(GetProperty(propertyKey, renderer)); if (gp != nullptr) { value = gp->GetValue(); return true; } return false; } /// \brief Get a set of all group tags from this node's property list GroupTagList GetGroupTags() const; /** * \brief Convenience access method for bool properties (instances of * BoolProperty) * \return \a true property was found */ bool GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for int properties (instances of * IntProperty) * \return \a true property was found */ bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for float properties (instances of * FloatProperty) * \return \a true property was found */ bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for double properties (instances of * DoubleProperty) * * If there is no DoubleProperty for the given\c propertyKey argument, the method * looks for a corresponding FloatProperty instance. * * \return \a true property was found */ bool GetDoubleProperty(const char *propertyKey, double &doubleValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for string properties (instances of * StringProperty) * \return \a true property was found */ bool GetStringProperty(const char *propertyKey, std::string &string, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for color properties (instances of * ColorProperty) * \return \a true property was found */ bool GetColor(float rgb[3], const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color") const; /** * \brief Convenience access method for level-window properties (instances of * LevelWindowProperty) * \return \a true property was found */ bool GetLevelWindow(mitk::LevelWindow &levelWindow, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "levelwindow") const; /** * \brief set the node as selected */ void SetSelected(bool selected, const mitk::BaseRenderer *renderer = nullptr); /** * \brief set the node as selected * \return \a true node is selected */ bool IsSelected(const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name") * \return \a true property was found */ bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "name") const { return GetStringProperty(propertyKey, nodeName, renderer); } /** * \brief Extra convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name"). * * This method does not take the renderer specific * propertylists into account, because the name of an object should never be renderer specific. * \returns a std::string with the name of the object (content of "name" Property). * If there is no "name" Property, an empty string will be returned. */ virtual std::string GetName() const { mitk::StringProperty *sp = dynamic_cast(this->GetProperty("name")); if (sp == nullptr) return ""; return sp->GetValue(); } /** Value constant that is used indicate that node names are not set so far.*/ static std::string NO_NAME_VALUE() { return "No Name!"; } /** * \brief Extra convenience access method to set the name of an object. * * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". */ virtual void SetName(const char *name) { if (name == nullptr) return; this->SetProperty("name", StringProperty::New(name)); } /** * \brief Extra convenience access method to set the name of an object. * * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". */ virtual void SetName(const std::string name) { this->SetName(name.c_str()); } /** * \brief Convenience access method for visibility properties (instances * of BoolProperty with property-key "visible") * \return \a true property was found * \sa IsVisible */ bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey = "visible") const { return GetBoolProperty(propertyKey, visible, renderer); } /** * \brief Convenience access method for opacity properties (instances of * FloatProperty) * \return \a true property was found */ bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey = "opacity") const; /** * \brief Convenience access method for boolean properties (instances * of BoolProperty). Return value is the value of the property. If the property is * not found, the value of \a defaultIsOn is returned. * * Thus, the return value has a different meaning than in the * GetBoolProperty method! * \sa GetBoolProperty */ bool IsOn(const char *propertyKey, const mitk::BaseRenderer *renderer, bool defaultIsOn = true) const { if (propertyKey == nullptr) return defaultIsOn; GetBoolProperty(propertyKey, defaultIsOn, renderer); return defaultIsOn; } /** * \brief Convenience access method for visibility properties (instances * of BoolProperty). Return value is the visibility. Default is * visible==true, i.e., true is returned even if the property (\a * propertyKey) is not found. * * Thus, the return value has a different meaning than in the * GetVisibility method! * \sa GetVisibility * \sa IsOn */ bool IsVisible(const mitk::BaseRenderer *renderer, const char *propertyKey = "visible", bool defaultIsOn = true) const { return IsOn(propertyKey, renderer, defaultIsOn); } /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const mitk::Color &color, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(float red, float green, float blue, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const float rgb[3], const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting visibility properties (instances * of BoolProperty) * \param visible If set to true, the data will be rendered. If false, the render will skip this data. * \param renderer Specify a renderer if the visibility shall be specific to a renderer - * \param propertykey Can be used to specify a user defined name of the visibility propery. + * \param propertyKey Can be used to specify a user defined name of the visibility propery. */ void SetVisibility(bool visible, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "visible"); /** * \brief Convenience method for setting opacity properties (instances of * FloatProperty) */ void SetOpacity(float opacity, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "opacity"); /** * \brief Convenience method for setting level-window properties * (instances of LevelWindowProperty) */ void SetLevelWindow(mitk::LevelWindow levelWindow, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "levelwindow"); /** * \brief Convenience method for setting int properties (instances of * IntProperty) */ void SetIntProperty(const char *propertyKey, int intValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting boolean properties (instances of * BoolProperty) */ void SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting float properties (instances of * FloatProperty) */ void SetFloatProperty(const char *propertyKey, float floatValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting double properties (instances of * DoubleProperty) */ void SetDoubleProperty(const char *propertyKey, double doubleValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting string properties (instances of * StringProperty) */ void SetStringProperty(const char *propertyKey, const char *string, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Get the timestamp of the last change of the contents of this node or * the referenced BaseData. */ unsigned long GetMTime() const override; /** * \brief Get the timestamp of the last change of the reference to the * BaseData. */ unsigned long GetDataReferenceChangedTime() const { return m_DataReferenceChangedTime.GetMTime(); } protected: DataNode(); ~DataNode() override; /// Invoked when the property list was modified. Calls Modified() of the DataNode virtual void PropertyListModified(const itk::Object *caller, const itk::EventObject &event); /// \brief Mapper-slots mutable MapperVector m_Mappers; /** * \brief The data object (instance of BaseData, e.g., an Image) managed * by this DataNode */ BaseData::Pointer m_Data; /** * \brief BaseRenderer-independent PropertyList * * Properties herein can be overwritten specifically for each BaseRenderer * by the BaseRenderer-specific properties defined in m_MapOfPropertyLists. */ PropertyList::Pointer m_PropertyList; /// \brief Map associating each BaseRenderer with its own PropertyList mutable MapOfPropertyLists m_MapOfPropertyLists; DataInteractor::Pointer m_DataInteractor; /// \brief Timestamp of the last change of m_Data itk::TimeStamp m_DataReferenceChangedTime; unsigned long m_PropertyListModifiedObserverTag; }; MITKCORE_EXPORT std::istream &operator>>(std::istream &i, DataNode::Pointer &dtn); MITKCORE_EXPORT std::ostream &operator<<(std::ostream &o, DataNode::Pointer &dtn); } // namespace mitk #endif /* DATATREENODE_H_HEADER_INCLUDED_C1E14338 */ diff --git a/Modules/Core/include/mitkDataStorage.h b/Modules/Core/include/mitkDataStorage.h index 8e6771b65f..a860959317 100644 --- a/Modules/Core/include/mitkDataStorage.h +++ b/Modules/Core/include/mitkDataStorage.h @@ -1,443 +1,442 @@ /*============================================================================ 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 MITKDATASTORAGE_H #define MITKDATASTORAGE_H #include "itkObject.h" #include "itkSimpleFastMutexLock.h" #include "itkVectorContainer.h" #include "mitkDataNode.h" #include "mitkGeometry3D.h" #include "mitkMessage.h" #include #include namespace mitk { class NodePredicateBase; class DataNode; class BaseRenderer; //##Documentation //## @brief Data management class that handles 'was created by' relations //## //## The DataStorage provides data storage and management functionality. //## It handles a 'was created by' relation by associating each data object with a //## set of source objects, that this object was created from. //## Thus, nodes are stored in a noncyclical directed graph data structure. //## If a new node is added to the DataStorage, AddNodeEvent is emitted. //## If a node is removed, RemoveNodeEvent is emitted. //## //## //## \ingroup DataStorage class MITKCORE_EXPORT DataStorage : public itk::Object { public: mitkClassMacroItkParent(DataStorage, itk::Object); //##Documentation //## @brief A Container of objects that is used as a result set of GetSubset() query operations (Set of //SmartPointers // to DataNodes). typedef itk::VectorContainer SetOfObjects; //##Documentation //## @brief Adds a DataNode containing a data object to its internal storage //## //## This Method adds a new data object to the DataStorage. The new object is //## passed in the first parameter. The second parameter is a set //## of source objects, that were used to create this object. The new object will have //## a 'was created from' relation to its source objects. //## the addition of a new object will fire the notification mechanism. //## If the node parameter is nullptr or if the DataNode has already been added, //## an exception will be thrown. virtual void Add(DataNode *node, const DataStorage::SetOfObjects *parents = nullptr) = 0; //##Documentation //## @brief Convenience method to add a node that has one parent //## void Add(DataNode *node, DataNode *parent); //##Documentation //## @brief Removes node from the DataStorage //## virtual void Remove(const DataNode *node) = 0; //##Documentation //## @brief Checks if a node exists in the DataStorage //## virtual bool Exists(const DataNode *node) const = 0; //##Documentation //## @brief Removes a set of nodes from the DataStorage //## void Remove(const DataStorage::SetOfObjects *nodes); //##Documentation //## @brief returns a set of data objects that meet the given condition(s) //## //## GetSubset returns a set of objects with a specific data type that meet the condition(s) //## specified in the condition parameter. Conditions can be //## - data type of the data object //## - is source object of specific object (e.g. all source objects of node x) //## - has property with specific value (e.g. OrganType is Liver) //## - negation of any condition //## - conjunction of a set of conditions //## - disjunction of a set of conditions //## Conditions are implemented as predicates using the Composite Design Pattern //## (see definition of NodePredicateBase for details). //## The method returns a set of SmartPointers to the DataNodes that fulfill the //## conditions. A set of all objects can be retrieved with the GetAll() method; SetOfObjects::ConstPointer GetSubset(const NodePredicateBase *condition) const; //##Documentation //## @brief returns a set of source objects for a given node that meet the given condition(s). //## virtual SetOfObjects::ConstPointer GetSources(const DataNode *node, const NodePredicateBase *condition = nullptr, bool onlyDirectSources = true) const = 0; //##Documentation //## @brief returns a set of derived objects for a given node. //## //## GetDerivations() returns a set of objects that are derived from the DataNode node. //## This means, that node was used to create the returned objects. If the parameter //## onlyDirectDerivations is set to true (default value), only objects that directly have //## node as one of their source objects will be returned. Otherwise, objects that are //## derived from derivations of node are returned too. //## The derived objects can be filtered with a predicate object as described in the GetSubset() //## method by providing a predicate as the condition parameter. virtual SetOfObjects::ConstPointer GetDerivations(const DataNode *node, const NodePredicateBase *condition = nullptr, bool onlyDirectDerivations = true) const = 0; //##Documentation //## @brief returns a set of all data objects that are stored in the data storage //## virtual SetOfObjects::ConstPointer GetAll() const = 0; //##Documentation //## @brief Convenience method to get the first node that matches the predicate condition //## DataNode *GetNode(const NodePredicateBase *condition = nullptr) const; //##Documentation //## @brief Convenience method to get the first node with a given name //## DataNode *GetNamedNode(const char *name) const; //##Documentation //## @brief Convenience method to get the first node with a given name //## DataNode *GetNamedNode(const std::string name) const { return this->GetNamedNode(name.c_str()); } //##Documentation //## @brief Convenience method to get the first node with a given name that is derived from sourceNode //## DataNode *GetNamedDerivedNode(const char *name, const DataNode *sourceNode, bool onlyDirectDerivations = true) const; //##Documentation //## @brief Convenience method to get the first data object of a given data type with a given name //## template DataType *GetNamedObject(const char *name) const { if (name == nullptr) return nullptr; DataNode *n = this->GetNamedNode(name); if (n == nullptr) return nullptr; else return dynamic_cast(n->GetData()); } //##Documentation //## @brief Convenience method to get the first data object of a given data type with a given name //## template DataType *GetNamedObject(const std::string name) const { return this->GetNamedObject(name.c_str()); } //##Documentation //## @brief Convenience method to get the first data object of a given data type with a given name that is derived // from a specific node //## template DataType *GetNamedDerivedObject(const char *name, const DataNode *sourceNode, bool onlyDirectDerivations = true) const { if (name == nullptr) return nullptr; DataNode *n = this->GetNamedDerivedNode(name, sourceNode, onlyDirectDerivations); if (n == nullptr) return nullptr; else return dynamic_cast(n->GetData()); } //##Documentation //## @brief Returns a list of used grouptags //## const DataNode::GroupTagList GetGroupTags() const; /*ITK Mutex */ mutable itk::SimpleFastMutexLock m_MutexOne; /* Public Events */ typedef Message1 DataStorageEvent; //##Documentation //## @brief AddEvent is emitted whenever a new node has been added to the DataStorage. //## //## Observers should register to this event by calling myDataStorage->AddNodeEvent.AddListener(myObject, // MyObject::MyMethod). //## After registering, myObject->MyMethod() will be called every time a new node has been added to the DataStorage. //## Observers should unregister by calling myDataStorage->AddNodeEvent.RemoveListener(myObject, //MyObject::MyMethod). //## Note: AddEvents are _not_ emitted if a node is added to DataStorage by adding it to the the underlying //DataTree! // member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef // for // a Message1 object which is thread safe DataStorageEvent AddNodeEvent; //##Documentation //## @brief RemoveEvent is emitted directly before a node is removed from the DataStorage. //## //## Observers should register to this event by calling myDataStorage->RemoveNodeEvent.AddListener(myObject, // MyObject::MyMethod). //## After registering, myObject->MyMethod() will be called every time a new node has been added to the DataStorage. //## Observers should unregister by calling myDataStorage->RemoveNodeEvent.RemoveListener(myObject, // MyObject::MyMethod). //## Note: RemoveEvents are also emitted if a node was removed from the DataStorage by deleting it from the //underlying // DataTree // member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef // for // a Message1 object which is thread safe DataStorageEvent RemoveNodeEvent; //##Documentation //## @brief ChangedEvent is emitted directly after a node was changed. //## //## Observers should register to this event by calling myDataStorage->ChangedNodeEvent.AddListener(myObject, // MyObject::MyMethod). //## After registering, myObject->MyMethod() will be called every time a new node has been changed. //## Observers should unregister by calling myDataStorage->ChangedNodeEvent.RemoveListener(myObject, // MyObject::MyMethod). //## Internally the DataStorage listens to itk::ModifiedEvents on the nodes and forwards them //## to the listeners of this event. // member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef // for // a Message1 object which is thread safe DataStorageEvent ChangedNodeEvent; //##Documentation //## @brief DeleteNodeEvent is emitted directly before a node is deleted. //## //## Observers should register to this event by calling myDataStorage->DeleteNodeEvent.AddListener(myObject, // MyObject::MyMethod). //## After registering, myObject->MyMethod() will be called when a node is deleted. //## Observers should unregister by calling myDataStorage->DeleteNodeEvent.RemoveListener(myObject, // MyObject::MyMethod). //## Internally the DataStorage listens to itk::DeleteEvents on the nodes and forwards them //## to the listeners of this event. // member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef // for // a Message1 object which is thread safe DataStorageEvent DeleteNodeEvent; DataStorageEvent InteractorChangedNodeEvent; //##Documentation //## @brief Compute the axis-parallel bounding geometry of the input objects //## //## Throws std::invalid_argument exception if input is nullptr //## @param input set of objects of the DataStorage to be included in the bounding geometry //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer) //## and is set to @a false, the node is ignored for the bounding-box calculation. //## @param renderer see @a boolPropertyKey //## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey TimeGeometry::ConstPointer ComputeBoundingGeometry3D(const SetOfObjects *input, const char *boolPropertyKey = nullptr, const BaseRenderer *renderer = nullptr, const char *boolPropertyKey2 = nullptr) const; //##Documentation //## @brief Compute the axis-parallel bounding geometry of the data tree //## (bounding box, minimal spacing of the considered nodes, live-span) //## //## it -> an iterator to a data tree structure //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer) //## and is set to @a false, the node is ignored for the bounding-box calculation. //## @param renderer see @a boolPropertyKey //## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey TimeGeometry::ConstPointer ComputeBoundingGeometry3D(const char *boolPropertyKey = nullptr, const BaseRenderer *renderer = nullptr, const char *boolPropertyKey2 = nullptr) const; //##Documentation //## @brief Compute the axis-parallel bounding geometry of all visible parts of the //## data tree bounding box, minimal spacing of the considered nodes, live-span) //## //## Simply calls ComputeBoundingGeometry3D(it, "visible", renderer, boolPropertyKey). //## it -> an iterator of a data tree structure //## @param renderer the reference to the renderer //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer) //## and is set to @a false, the node is ignored for the bounding-box calculation. TimeGeometry::ConstPointer ComputeVisibleBoundingGeometry3D(const BaseRenderer *renderer = nullptr, const char *boolPropertyKey = nullptr); //##Documentation //## @brief Compute the bounding box of data tree structure //## it -> an iterator to a data tree structure //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer) //## and is set to @a false, the node is ignored for the bounding-box calculation. //## @param renderer see @a boolPropertyKey //## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey BoundingBox::Pointer ComputeBoundingBox(const char *boolPropertyKey = nullptr, const BaseRenderer *renderer = nullptr, const char *boolPropertyKey2 = nullptr); //##Documentation //## \brief Compute the bounding box of all visible parts of the data tree structure, for general //## rendering or renderer specific visibility property checking //## //## Simply calls ComputeBoundingBox(it, "visible", renderer, boolPropertyKey). //## it -> an iterator of a data tree structure //## @param renderer the reference to the renderer //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer) //## and is set to @a false, the node is ignored for the bounding-box calculation. BoundingBox::Pointer ComputeVisibleBoundingBox(const BaseRenderer *renderer = nullptr, const char *boolPropertyKey = nullptr) { return ComputeBoundingBox("visible", renderer, boolPropertyKey); } //##Documentation //## @brief Compute the time-bounds of the contents of a data tree structure //## //## The methods returns only [-infinity, +infinity], if all data-objects have an infinite live-span. Otherwise, //## all data-objects with infinite live-span are ignored. //## it -> an iterator to a data tree structure //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer) //## and is set to @a false, the node is ignored for the time-bounds calculation. //## @param renderer see @a boolPropertyKey //## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey TimeBounds ComputeTimeBounds(const char *boolPropertyKey, const BaseRenderer *renderer, const char *boolPropertyKey2); //##Documentation //## @brief Compute the time-bounds of all visible parts of the data tree structure, for general //## rendering or renderer specific visibility property checking //## //## The methods returns only [-infinity, +infinity], if all data-objects have an infinite live-span. Otherwise, //## all data-objects with infinite live-span are ignored. //## Simply calls ComputeTimeBounds(it, "visible", renderer, boolPropertyKey). - //## @param it an iterator to a data tree structure //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer) //## and is set to @a false, the node is ignored for the time-bounds calculation. //## @param renderer see @a boolPropertyKey TimeBounds ComputeTimeBounds(const BaseRenderer *renderer, const char *boolPropertyKey) { return ComputeTimeBounds("visible", renderer, boolPropertyKey); } //##Documentation //## @brief Defines whether or not NodeChangedEvent is invoked . //## //## This method can be used to set m_BlockNodeModifiedEvents. //## //## If this flag is true, NodeChangedEvent is not invoked when a //## DataNode is modified. This might be undesired when setting //## many properties on a datanode and you do not want anyone to //## react. void BlockNodeModifiedEvents(bool block); protected: //##Documentation //## @brief EmitAddNodeEvent emits the AddNodeEvent //## //## This method should be called by subclasses to emit the AddNodeEvent void EmitAddNodeEvent(const DataNode *node); //##Documentation //## @brief EmitRemoveNodeEvent emits the RemoveNodeEvent //## //## This method should be called by subclasses to emit the RemoveNodeEvent void EmitRemoveNodeEvent(const DataNode *node); void OnNodeInteractorChanged(itk::Object *caller, const itk::EventObject &event); //##Documentation //## @brief OnNodeModified listens to modified events of DataNodes. //## //## The node is hidden behind the caller parameter, which has to be casted first. //## If the cast succeeds the ChangedNodeEvent is emitted with this node. void OnNodeModifiedOrDeleted(const itk::Object *caller, const itk::EventObject &event); //##Documentation //## @brief Adds a Modified-Listener to the given Node. void AddListeners(const DataNode *_Node); //##Documentation //## @brief Removes a Modified-Listener from the given Node. void RemoveListeners(const DataNode *_Node); //##Documentation //## @brief Saves Modified-Observer Tags for each node in order to remove the event listeners again. std::map m_NodeModifiedObserverTags; std::map m_NodeInteractorChangedObserverTags; //##Documentation //## @brief Saves Delete-Observer Tags for each node in order to remove the event listeners again. std::map m_NodeDeleteObserverTags; //##Documentation //## @brief If this class changes nodes itself, set this to TRUE in order //## to suppress NodeChangedEvent to be emitted. bool m_BlockNodeModifiedEvents; DataStorage(); ~DataStorage() override; //##Documentation //## @brief Filters a SetOfObjects by the condition. If no condition is provided, the original set is returned SetOfObjects::ConstPointer FilterSetOfObjects(const SetOfObjects *set, const NodePredicateBase *condition) const; //##Documentation //## @brief Prints the contents of the DataStorage to os. Do not call directly, call ->Print() instead void PrintSelf(std::ostream &os, itk::Indent indent) const override; }; //##Documentation //## @brief returns the topmost visible node of a given list of nodes. //## The function returns a node that is visible and has the highest layer of a set of given nodes. //## The property list, which is used to find the visibility- and layer-property is is specified by the //## given base renderer. //## MITKCORE_EXPORT DataNode::Pointer FindTopmostVisibleNode(const DataStorage::SetOfObjects::ConstPointer nodes, const Point3D worldPosition, const TimePointType timePoint, const BaseRenderer* baseRender); } // namespace mitk #endif // MITKDATASTORAGE_H diff --git a/Modules/Core/include/mitkEqual.h b/Modules/Core/include/mitkEqual.h index 89539d640f..ad6d0b9745 100644 --- a/Modules/Core/include/mitkEqual.h +++ b/Modules/Core/include/mitkEqual.h @@ -1,84 +1,84 @@ /*============================================================================ 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. ============================================================================*/ /* * mitkEqual.h * * Created on: Apr 14, 2014 * Author: wirkert */ #ifndef MITKEQUAL_H_ #define MITKEQUAL_H_ #include #include "mitkLogMacros.h" #include "mitkNumericConstants.h" namespace mitk { /** * Helper method to check if the difference is bigger or equal to a given epsilon * * @param diff the difference to be checked against the epsilon - * @param the epsilon. The absolute difference needs to be smaller than this. + * @param epsilon The absolute difference needs to be smaller than this. * @return true if abs(diff) >= eps */ template inline bool DifferenceBiggerOrEqualEps(DifferenceType diff, mitk::ScalarType epsilon = mitk::eps) { return fabs(diff) >= epsilon; } /** * outputs elem1, elem2 and eps in case verbose and !isEqual. * Elem can e.g. be a mitk::Vector or an mitk::Point. * * @param elem1 first element to be output * @param elem2 second * @param eps the epsilon which their difference was bigger than * @param verbose tells the function if something shall be output * @param isEqual function will only output something if the two elements are not equal */ template inline void ConditionalOutputOfDifference( ElementToOutput1 elem1, ElementToOutput2 elem2, mitk::ScalarType eps, bool verbose, bool isEqual) { if (verbose && !isEqual) { MITK_INFO << typeid(ElementToOutput1).name() << " and " << typeid(ElementToOutput2).name() << " not equal. Lefthandside " << std::setprecision(12) << elem1 << " - Righthandside " << elem2 << " - epsilon " << eps; } } /** * @ingroup MITKTestingAPI * * @param scalar1 Scalar value to compare. * @param scalar2 Scalar value to compare. * @param eps Tolerance for floating point comparison. * @param verbose Flag indicating detailed console output. * @return True if scalars are equal. */ inline bool Equal(ScalarType scalar1, ScalarType scalar2, ScalarType eps = mitk::eps, bool verbose = false) { bool isEqual(!DifferenceBiggerOrEqualEps(scalar1 - scalar2, eps)); ConditionalOutputOfDifference(scalar1, scalar2, eps, verbose, isEqual); return isEqual; } } #endif /* MITKEQUAL_H_ */ diff --git a/Modules/Core/include/mitkEventRecorder.h b/Modules/Core/include/mitkEventRecorder.h index 2af1e6958f..a99f54fb56 100644 --- a/Modules/Core/include/mitkEventRecorder.h +++ b/Modules/Core/include/mitkEventRecorder.h @@ -1,83 +1,85 @@ /*============================================================================ 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 mitkEventRecorder_h #define mitkEventRecorder_h #include "iostream" #include "mitkInteractionEventObserver.h" #include namespace mitk { /** *\class EventRecorder *@brief Observer that enables recoding of all user interaction with the render windows and storing it in an XML - *file. + *file. * * @ingroup Interaction * - * XML file will look like + * XML file will look like: * - * - * + * \code{.unparsed} + * + * * - * - * - * + * + * + * * * - * - * - * - * - * + * + * + * + * + * * - * + * + * \endcode **/ class MITKCORE_EXPORT EventRecorder : public InteractionEventObserver { public: EventRecorder(); ~EventRecorder() override; /** * By this function the Observer gets notified about new events. */ void Notify(InteractionEvent *interactionEvent, bool) override; /** * @brief SetEventIgnoreList Optional. Provide a list of strings that describe which events are to be ignored */ void SetEventIgnoreList(std::vector list); void StartRecording(); void StopRecording(); bool IsActive() { return m_Active; } void SetOutputFile(std::string filename) { m_FileName = filename; } private: /** * @brief m_IgnoreList lists the names of events that are dropped */ std::vector m_IgnoreList; /** * @brief m_Active determindes if events are caught and written to file */ bool m_Active; std::string m_FileName; std::ofstream m_FileStream; }; } #endif diff --git a/Modules/Core/include/mitkException.h b/Modules/Core/include/mitkException.h index 0465afc949..c632970caf 100644 --- a/Modules/Core/include/mitkException.h +++ b/Modules/Core/include/mitkException.h @@ -1,115 +1,115 @@ /*============================================================================ 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 MITKEXCEPTION_H_INCLUDED #define MITKEXCEPTION_H_INCLUDED #include #include #include namespace mitk { /**Documentation * \brief An object of this class represents an exception of MITK. * Please don't instantiate exceptions manually, but use the * exception macros (file mitkExceptionMacro.h) instead. * Simple use in your code is: * * mitkThrow() << "optional exception message"; * * You can also define specialized exceptions which must inherit * from this class. Please always use the mitkExceptionClassMacro * when implementing specialized exceptions. A simple implementation * can look like: * * class MyException : public mitk::Exception * { * public: * mitkExceptionClassMacro(MyException,mitk::Exception); * }; * * You can then throw your specialized exceptions by using the macro * * mitkThrowException(MyException) << "optional exception message"; */ class MITKCORE_EXPORT Exception : public itk::ExceptionObject { public: Exception(const char *file, unsigned int lineNumber = 0, const char *desc = "None", const char *loc = "Unknown") : itk::ExceptionObject(file, lineNumber, desc, loc) { } ~Exception() throw() override {} itkTypeMacro(ClassName, SuperClassName); /** \brief Adds rethrow data to this exception. */ void AddRethrowData(const char *file, unsigned int lineNumber, const char *message); /** \return Returns how often the exception was rethrown. */ int GetNumberOfRethrows(); /** @return Returns the rethrow data of the specified rethrow number. Returns empty data, if the rethrowNumber * doesn't * exist. * @param rethrowNumber The internal number of the rethrow. * @param file (returnvalue) This varaiable will be filled with the file of the specified rethrow. - * @param file (returnvalue) This varaiable will be filled with the line of the specified rethrow. - * @param file (returnvalue) This varaiable will be filled with the message of the specified rethrow. + * @param line (returnvalue) This varaiable will be filled with the line of the specified rethrow. + * @param message (returnvalue) This varaiable will be filled with the message of the specified rethrow. */ void GetRethrowData(int rethrowNumber, std::string &file, int &line, std::string &message); /** \brief Definition of the bit shift operator for this class.*/ template inline Exception &operator<<(const T &data) { std::stringstream ss; ss << this->GetDescription() << data; this->SetDescription(ss.str()); return *this; } /** \brief Definition of the bit shift operator for this class (for non const data).*/ template inline Exception &operator<<(T &data) { std::stringstream ss; ss << this->GetDescription() << data; this->SetDescription(ss.str()); return *this; } /** \brief Definition of the bit shift operator for this class (for functions).*/ inline Exception &operator<<(std::ostream &(*func)(std::ostream &)) { std::stringstream ss; ss << this->GetDescription() << func; this->SetDescription(ss.str()); return *this; } protected: struct ReThrowData { std::string RethrowClassname; unsigned int RethrowLine; std::string RethrowMessage; }; std::vector m_RethrowData; }; MITKCORE_EXPORT std::ostream &operator<<(std::ostream &os, const mitk::Exception &e); } // namespace mitk #endif diff --git a/Modules/Core/include/mitkFileReaderRegistry.h b/Modules/Core/include/mitkFileReaderRegistry.h index 9e55cc156d..5ee1fc44c0 100644 --- a/Modules/Core/include/mitkFileReaderRegistry.h +++ b/Modules/Core/include/mitkFileReaderRegistry.h @@ -1,77 +1,77 @@ /*============================================================================ 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 FileReaderRegistry_H_HEADER_INCLUDED_C1E7E521 #define FileReaderRegistry_H_HEADER_INCLUDED_C1E7E521 #include #include #include // Microservices #include #include #include namespace mitk { class MimeType; /** * @ingroup IO * * Provides convenient access to mitk::IFileReader instances and reading * files into mitk::BaseData types. * * \note The life-time of all mitk::IFileReader objects returned by an * instance of this class ends with the destruction of that instance. */ class MITKCORE_EXPORT FileReaderRegistry { public: typedef us::ServiceReference ReaderReference; FileReaderRegistry(); ~FileReaderRegistry(); /** * @brief Get the highest ranked mime-type for the given file name. - * @param extension A file name extension without a leading dot. + * @param path * @param context * @return The highest ranked mime-type containing \c extension in * its extension list. */ static MimeType GetMimeTypeForFile(const std::string &path, us::ModuleContext *context = us::GetModuleContext()); static std::vector GetReferences(const MimeType &mimeType, us::ModuleContext *context = us::GetModuleContext()); mitk::IFileReader *GetReader(const ReaderReference &ref, us::ModuleContext *context = us::GetModuleContext()); std::vector GetReaders(const MimeType &mimeType, us::ModuleContext *context = us::GetModuleContext()); void UngetReader(mitk::IFileReader *reader); void UngetReaders(const std::vector &readers); private: // purposely not implemented FileReaderRegistry(const FileReaderRegistry &); FileReaderRegistry &operator=(const FileReaderRegistry &); std::map> m_ServiceObjects; }; } // namespace mitk #endif /* FileReaderRegistry_H_HEADER_INCLUDED_C1E7E521 */ diff --git a/Modules/Core/include/mitkGeometry3D.h b/Modules/Core/include/mitkGeometry3D.h index b342f6aa25..8b5645750e 100644 --- a/Modules/Core/include/mitkGeometry3D.h +++ b/Modules/Core/include/mitkGeometry3D.h @@ -1,77 +1,75 @@ /*============================================================================ 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 GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD #define GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD #include "mitkNumericTypes.h" #include #include #include "itkScalableAffineTransform.h" #include #include "mitkBaseGeometry.h" class vtkLinearTransform; namespace mitk { - //##Documentation - //## @brief Standard implementation of BaseGeometry. - //## - //## @ingroup Geometry + /** @brief Standard implementation of BaseGeometry. + * @ingroup Geometry + */ class MITKCORE_EXPORT Geometry3D : public BaseGeometry { public: mitkClassMacro(Geometry3D, mitk::BaseGeometry); typedef itk::QuaternionRigidTransform QuaternionTransformType; typedef QuaternionTransformType::VnlQuaternionType VnlQuaternionType; /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self); mitkNewMacro1Param(Self, const Self&); itkCloneMacro(Self); - // itkGetConstReferenceMacro(TimeBounds, TimeBounds); - - // virtual void SetTimeBounds(const TimeBounds& timebounds); protected : Geometry3D(); Geometry3D(const Geometry3D &); - //##Documentation - //## @brief clones the geometry - //## - //## Overwrite in all sub-classes. - //## Normally looks like: - //## \code - //## Self::Pointer newGeometry = new Self(*this); - //## newGeometry->UnRegister(); - //## return newGeometry.GetPointer(); - //## \endcode + /** + * @brief clones the geometry + * + * Overwrite in all sub-classes. + * Normally looks like: + * \code + * Self::Pointer newGeometry = new Self(*this); + * newGeometry->UnRegister(); + * return newGeometry.GetPointer(); + * \endcode + */ itk::LightObject::Pointer InternalClone() const override; ~Geometry3D() override; - //##Documentation - //## @brief PreSetSpacing - //## - //## These virtual function allows a different beahiour in subclasses. - //## Do implement them in every subclass of BaseGeometry. If not needed, use - //## {Superclass::PreSetSpacing();}; + /** + * @brief PreSetSpacing + * + * These virtual function allows a different beahiour in subclasses. + * Do implement them in every subclass of BaseGeometry. If not needed, use + * \c Superclass::PreSetSpacing(). + */ void PreSetSpacing(const mitk::Vector3D &aSpacing) override { Superclass::PreSetSpacing(aSpacing); }; }; } // namespace mitk #endif /* GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD */ diff --git a/Modules/Core/include/mitkImage.h b/Modules/Core/include/mitkImage.h index cdbbe2b5a7..fe8e646ebc 100644 --- a/Modules/Core/include/mitkImage.h +++ b/Modules/Core/include/mitkImage.h @@ -1,792 +1,799 @@ /*============================================================================ 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 MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 #define MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 #include "mitkBaseData.h" #include "mitkImageAccessorBase.h" #include "mitkImageDataItem.h" #include "mitkImageDescriptor.h" #include "mitkImageVtkAccessor.h" #include "mitkLevelWindow.h" #include "mitkPlaneGeometry.h" #include "mitkSlicedData.h" #include #include // DEPRECATED #include #ifndef __itkHistogram_h #include #endif class vtkImageData; namespace itk { template class MutexLockHolder; } namespace mitk { class SubImageSelector; class ImageTimeSelector; class ImageStatisticsHolder; - //##Documentation - //## @brief Image class for storing images - //## - //## Can be asked for header information, the data vector, - //## the mitkIpPicDescriptor struct or vtkImageData objects. If not the complete - //## data is required, the appropriate SubImageSelector class should be used - //## for access. - //## Image organizes sets of slices (s x 2D), volumes (t x 3D) and channels (n - //## x ND). Channels are for different kind of data, e.g., morphology in - //## channel 0, velocities in channel 1. All channels must have the same Geometry! In - //## particular, the dimensions of all channels are the same, only the pixel-type - //## may differ between channels. - //## - //## For importing ITK images use of mitk::ITKImageImport is recommended, see - //## \ref Adaptor. - //## - //## For ITK v3.8 and older: Converting coordinates from the ITK physical - //## coordinate system (which does not support rotated images) to the MITK world - //## coordinate system should be performed via the BaseGeometry of the Image, see - //## BaseGeometry::WorldToItkPhysicalPoint. - //## - //## For more information, see \ref MitkImagePage . - //## @ingroup Data + /** + * @brief Image class for storing images + * + * Can be asked for header information, the data vector, + * the mitkIpPicDescriptor struct or vtkImageData objects. If not the complete + * data is required, the appropriate SubImageSelector class should be used + * for access. + * Image organizes sets of slices (s x 2D), volumes (t x 3D) and channels (n + * x ND). Channels are for different kind of data, e.g., morphology in + * channel 0, velocities in channel 1. All channels must have the same Geometry! In + * particular, the dimensions of all channels are the same, only the pixel-type + * may differ between channels. + * + * For importing ITK images use of mitk::ITKImageImport is recommended, see + * \ref Adaptor. + * + * For ITK v3.8 and older: Converting coordinates from the ITK physical + * coordinate system (which does not support rotated images) to the MITK world + * coordinate system should be performed via the BaseGeometry of the Image, see + * BaseGeometry::WorldToItkPhysicalPoint. + * + * For more information, see \ref MitkImagePage . + * @ingroup Data + */ class MITKCORE_EXPORT Image : public SlicedData { friend class SubImageSelector; friend class ImageAccessorBase; friend class ImageVtkAccessor; friend class ImageVtkReadAccessor; friend class ImageVtkWriteAccessor; friend class ImageReadAccessor; friend class ImageWriteAccessor; public: mitkClassMacro(Image, SlicedData); itkFactorylessNewMacro(Self); itkCloneMacro(Self); - /** Smart Pointer type to a ImageDataItem. */ - typedef itk::SmartPointer ImageDataItemPointer; + /** Smart Pointer type to a ImageDataItem. */ + typedef itk::SmartPointer ImageDataItemPointer; typedef itk::Statistics::Histogram HistogramType; typedef mitk::ImageStatisticsHolder *StatisticsHolderPointer; - //## @param ImportMemoryManagementType This parameter is evaluated when setting new data to an image. - //## The different options are: - //## CopyMemory: Data to be set is copied and assigned to a new memory block. Data memory block will be freed on - // deletion of mitk::Image. - //## MamageMemory: Data to be set will be referenced, and Data memory block will be freed on deletion of - //mitk::Image. - //## Reference Memory: Data to be set will be referenced, but Data memory block will not be freed on deletion of - // mitk::Image. - //## DontManageMemory = ReferenceMemory. + /** This enum is evaluated when setting new data to an image. + */ enum ImportMemoryManagementType { - CopyMemory, - ManageMemory, - ReferenceMemory, + CopyMemory, /**< Data to be set is copied and assigned to a new memory block. Data memory block will be freed on deletion of mitk::Image. */ + ManageMemory, /**< Data to be set will be referenced, and Data memory block will be freed on deletion of mitk::Image. */ + ReferenceMemory, /**< Data to be set will be referenced, but Data memory block will not be freed on deletion of mitk::Image. */ DontManageMemory = ReferenceMemory }; - //##Documentation - //## @brief Vector container of SmartPointers to ImageDataItems; - //## Class is only for internal usage to allow convenient access to all slices over iterators; - //## See documentation of ImageDataItem for details. + /** + * @brief Vector container of SmartPointers to ImageDataItems; + * Class is only for internal usage to allow convenient access to all slices over iterators; + * See documentation of ImageDataItem for details. + */ typedef std::vector ImageDataItemPointerArray; public: - //##Documentation - //## @brief Returns the PixelType of channel @a n. + /** + * @brief Returns the PixelType of channel @a n. + */ const mitk::PixelType GetPixelType(int n = 0) const; - //##Documentation - //## @brief Get dimension of the image - //## + /** + * @brief Get dimension of the image + */ unsigned int GetDimension() const; - //##Documentation - //## @brief Get the size of dimension @a i (e.g., i=0 results in the number of pixels in x-direction). - //## - //## @sa GetDimensions() + /** + * @brief Get the size of dimension @a i (e.g., i=0 results in the number of pixels in x-direction). + * + * @sa GetDimensions() + */ unsigned int GetDimension(int i) const; /** @brief Get the data vector of the complete image, i.e., of all channels linked together. If you only want to access a slice, volume at a specific time or single channel use one of the SubImageSelector classes. \deprecatedSince{2012_09} Please use image accessors instead: See Doxygen/Related-Pages/Concepts/Image. This method can be replaced by ImageWriteAccessor::GetData() or ImageReadAccessor::GetData() */ DEPRECATED(virtual void *GetData()); public: /** @brief Get the pixel value at one specific index position. The pixel type is always being converted to double. \deprecatedSince{2012_09} Please use image accessors instead: See Doxygen/Related-Pages/Concepts/Image. This method can be replaced by a method from ImagePixelWriteAccessor or ImagePixelReadAccessor */ DEPRECATED(double GetPixelValueByIndex(const itk::Index<3> &position, unsigned int timestep = 0, unsigned int component = 0)); /** @brief Get the pixel value at one specific world position. The pixel type is always being converted to double. Please consider using image accessors instead: See Doxygen/Related-Pages/Concepts/Image. This method can be replaced by a templated method from ImagePixelWriteAccessor or ImagePixelReadAccessor */ double GetPixelValueByWorldCoordinate(const mitk::Point3D &position, unsigned int timestep = 0, unsigned int component = 0); - //##Documentation - //## @brief Get a volume at a specific time @a t of channel @a n as a vtkImageData. + /** + * @brief Get a volume at a specific time @a t of channel @a n as a vtkImageData. + */ virtual vtkImageData *GetVtkImageData(int t = 0, int n = 0); virtual const vtkImageData *GetVtkImageData(int t = 0, int n = 0) const; - //##Documentation - //## @brief Get the complete image, i.e., all channels linked together, as a @a mitkIpPicDescriptor. - //## - //## If you only want to access a slice, volume at a specific time or single channel - //## use one of the SubImageSelector classes. - // virtual mitkIpPicDescriptor* GetPic(); - - //##Documentation - //## @brief Check whether slice @a s at time @a t in channel @a n is set + /** + * @brief Check whether slice @a s at time @a t in channel @a n is set + */ bool IsSliceSet(int s = 0, int t = 0, int n = 0) const override; - //##Documentation - //## @brief Check whether volume at time @a t in channel @a n is set + /** + * @brief Check whether volume at time @a t in channel @a n is set + */ bool IsVolumeSet(int t = 0, int n = 0) const override; - //##Documentation - //## @brief Check whether the channel @a n is set + /** + * @brief Check whether the channel @a n is set + */ bool IsChannelSet(int n = 0) const override; - //##Documentation - //## @brief Set @a data as slice @a s at time @a t in channel @a n. It is in - //## the responsibility of the caller to ensure that the data vector @a data - //## is really a slice (at least is not smaller than a slice), since there is - //## no chance to check this. - //## - //## The data is copied to an array managed by the image. If the image shall - //## reference the data, use SetImportSlice with ImportMemoryManagementType - //## set to ReferenceMemory. For importing ITK images use of mitk:: - //## ITKImageImport is recommended. - //## @sa SetPicSlice, SetImportSlice, SetImportVolume + /** + * @brief Set @a data as slice @a s at time @a t in channel @a n. It is in + * the responsibility of the caller to ensure that the data vector @a data + * is really a slice (at least is not smaller than a slice), since there is + * no chance to check this. + * + * The data is copied to an array managed by the image. If the image shall + * reference the data, use SetImportSlice with ImportMemoryManagementType + * set to ReferenceMemory. For importing ITK images use of mitk:: + * ITKImageImport is recommended. + * @sa SetPicSlice, SetImportSlice, SetImportVolume + */ virtual bool SetSlice(const void *data, int s = 0, int t = 0, int n = 0); - //##Documentation - //## @brief Set @a data as volume at time @a t in channel @a n. It is in - //## the responsibility of the caller to ensure that the data vector @a data - //## is really a volume (at least is not smaller than a volume), since there is - //## no chance to check this. - //## - //## The data is copied to an array managed by the image. If the image shall - //## reference the data, use SetImportVolume with ImportMemoryManagementType - //## set to ReferenceMemory. For importing ITK images use of mitk:: - //## ITKImageImport is recommended. - //## @sa SetPicVolume, SetImportVolume + /** + * @brief Set @a data as volume at time @a t in channel @a n. It is in + * the responsibility of the caller to ensure that the data vector @a data + * is really a volume (at least is not smaller than a volume), since there is + * no chance to check this. + * + * The data is copied to an array managed by the image. If the image shall + * reference the data, use SetImportVolume with ImportMemoryManagementType + * set to ReferenceMemory. For importing ITK images use of mitk:: + * ITKImageImport is recommended. + * @sa SetPicVolume, SetImportVolume + */ virtual bool SetVolume(const void *data, int t = 0, int n = 0); - //##Documentation - //## @brief Set @a data in channel @a n. It is in - //## the responsibility of the caller to ensure that the data vector @a data - //## is really a channel (at least is not smaller than a channel), since there is - //## no chance to check this. - //## - //## The data is copied to an array managed by the image. If the image shall - //## reference the data, use SetImportChannel with ImportMemoryManagementType - //## set to ReferenceMemory. For importing ITK images use of mitk:: - //## ITKImageImport is recommended. - //## @sa SetPicChannel, SetImportChannel + /** + * @brief Set @a data in channel @a n. It is in + * the responsibility of the caller to ensure that the data vector @a data + * is really a channel (at least is not smaller than a channel), since there is + * no chance to check this. + * + * The data is copied to an array managed by the image. If the image shall + * reference the data, use SetImportChannel with ImportMemoryManagementType + * set to ReferenceMemory. For importing ITK images use of mitk:: + * ITKImageImport is recommended. + * @sa SetPicChannel, SetImportChannel + */ virtual bool SetChannel(const void *data, int n = 0); - //##Documentation - //## @brief Set @a data as slice @a s at time @a t in channel @a n. It is in - //## the responsibility of the caller to ensure that the data vector @a data - //## is really a slice (at least is not smaller than a slice), since there is - //## no chance to check this. - //## - //## The data is managed according to the parameter \a importMemoryManagement. - //## @sa SetPicSlice + /** + * @brief Set @a data as slice @a s at time @a t in channel @a n. It is in + * the responsibility of the caller to ensure that the data vector @a data + * is really a slice (at least is not smaller than a slice), since there is + * no chance to check this. + * + * The data is managed according to the parameter \a importMemoryManagement. + * @sa SetPicSlice + */ virtual bool SetImportSlice( void *data, int s = 0, int t = 0, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory); - //##Documentation - //## @brief Set @a data as volume at time @a t in channel @a n. It is in - //## the responsibility of the caller to ensure that the data vector @a data - //## is really a volume (at least is not smaller than a volume), since there is - //## no chance to check this. - //## - //## The data is managed according to the parameter \a importMemoryManagement. - //## @sa SetPicVolume + /** + * @brief Set @a data as volume at time @a t in channel @a n. It is in + * the responsibility of the caller to ensure that the data vector @a data + * is really a volume (at least is not smaller than a volume), since there is + * no chance to check this. + * + * The data is managed according to the parameter \a importMemoryManagement. + * @sa SetPicVolume + */ virtual bool SetImportVolume(void *data, int t = 0, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory); virtual bool SetImportVolume(const void *const_data, int t = 0, int n = 0); - //##Documentation - //## @brief Set @a data in channel @a n. It is in - //## the responsibility of the caller to ensure that the data vector @a data - //## is really a channel (at least is not smaller than a channel), since there is - //## no chance to check this. - //## - //## The data is managed according to the parameter \a importMemoryManagement. - //## @sa SetPicChannel + /** + * @brief Set @a data in channel @a n. It is in + * the responsibility of the caller to ensure that the data vector @a data + * is really a channel (at least is not smaller than a channel), since there is + * no chance to check this. + * + * The data is managed according to the parameter \a importMemoryManagement. + * @sa SetPicChannel + */ virtual bool SetImportChannel(void *data, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory); - //##Documentation - //## initialize new (or re-initialize) image information - //## @warning Initialize() by pic assumes a plane, evenly spaced geometry starting at (0,0,0). + /** + * initialize new (or re-initialize) image information + * @warning Initialize() by pic assumes a plane, evenly spaced geometry starting at (0,0,0). + */ virtual void Initialize(const mitk::PixelType &type, unsigned int dimension, const unsigned int *dimensions, unsigned int channels = 1); - //##Documentation - //## initialize new (or re-initialize) image information by a BaseGeometry - //## - //## @param tDim defines the number of time steps for which the Image should be initialized + /** + * initialize new (or re-initialize) image information by a BaseGeometry + * + * \param type + * \param geometry + * \param channels + * @param tDim defines the number of time steps for which the Image should be initialized + */ virtual void Initialize(const mitk::PixelType &type, const mitk::BaseGeometry &geometry, unsigned int channels = 1, int tDim = 1); /** * initialize new (or re-initialize) image information by a TimeGeometry * - * @param tDim defines the number of time steps for which the Image should be initialized * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201 */ DEPRECATED(virtual void Initialize(const mitk::PixelType & /*type*/, const mitk::TimeSlicedGeometry * /*geometry*/, unsigned int /*channels = 1*/, int /*tDim=1*/)) { } /** * \brief Initialize new (or re-initialize) image information by a TimeGeometry * + * \param type + * \param geometry + * \param channels * \param tDim override time dimension if the value is bigger than 0 (Default -1) */ virtual void Initialize(const mitk::PixelType &type, const mitk::TimeGeometry &geometry, unsigned int channels = 1, int tDim = -1); - //##Documentation - //## initialize new (or re-initialize) image information by a PlaneGeometry and number of slices - //## - //## Initializes the bounding box according to the width/height of the - //## PlaneGeometry and @a sDim via SlicedGeometry3D::InitializeEvenlySpaced. - //## The spacing is calculated from the PlaneGeometry. - //## \sa SlicedGeometry3D::InitializeEvenlySpaced - //## \deprecatedSince{2016_11} Use a left-handed or right-handed PlaneGeometry to define the - //## direction of the image stack instead of the flipped parameter + /** + * initialize new (or re-initialize) image information by a PlaneGeometry and number of slices + * + * Initializes the bounding box according to the width/height of the + * PlaneGeometry and @a sDim via SlicedGeometry3D::InitializeEvenlySpaced. + * The spacing is calculated from the PlaneGeometry. + * \sa SlicedGeometry3D::InitializeEvenlySpaced + * \deprecatedSince{2016_11} Use a left-handed or right-handed PlaneGeometry to define the + * direction of the image stack instead of the flipped parameter + */ DEPRECATED(virtual void Initialize(const mitk::PixelType &type, int sDim, const mitk::PlaneGeometry &geometry2d, bool flipped, unsigned int channels = 1, int tDim = 1)); virtual void Initialize(const mitk::PixelType &type, int sDim, const mitk::PlaneGeometry &geometry2d, unsigned int channels = 1, int tDim = 1); - //##Documentation - //## initialize new (or re-initialize) image information by another - //## mitk-image. - //## Only the header is used, not the data vector! - //## + /** + * initialize new (or re-initialize) image information by another + * mitk-image. + * Only the header is used, not the data vector! + */ virtual void Initialize(const mitk::Image *image); virtual void Initialize(const mitk::ImageDescriptor::Pointer inDesc); - //##Documentation - //## initialize new (or re-initialize) image information by @a pic. - //## Dimensions and @a Geometry3D /@a PlaneGeometry are set according - //## to the tags in @a pic. - //## Only the header is used, not the data vector! Use SetPicVolume(pic) - //## to set the data vector. - //## - //## @param tDim override time dimension (@a n[3]) in @a pic (if >0) - //## @param sDim override z-space dimension (@a n[2]) in @a pic (if >0) - //## @warning Initialize() by pic assumes a plane, evenly spaced geometry starting at (0,0,0). - // virtual void Initialize(const mitkIpPicDescriptor* pic, int channels = 1, int tDim = -1, int sDim = -1); - - //##Documentation - //## initialize new (or re-initialize) image information by @a vtkimagedata, - //## a vtk-image. - //## Only the header is used, not the data vector! Use - //## SetVolume(vtkimage->GetScalarPointer()) to set the data vector. - //## - //## @param tDim override time dimension in @a vtkimagedata (if >0 and <) - //## @param sDim override z-space dimension in @a vtkimagedata (if >0 and <) - //## @param pDim override y-space dimension in @a vtkimagedata (if >0 and <) + /** + * initialize new (or re-initialize) image information by @a vtkimagedata, + * a vtk-image. + * Only the header is used, not the data vector! Use + * SetVolume(vtkimage->GetScalarPointer()) to set the data vector. + * + * @param vtkimagedata + * @param channels + * @param tDim override time dimension in @a vtkimagedata (if >0 and <) + * @param sDim override z-space dimension in @a vtkimagedata (if >0 and <) + * @param pDim override y-space dimension in @a vtkimagedata (if >0 and <) + */ virtual void Initialize(vtkImageData *vtkimagedata, int channels = 1, int tDim = -1, int sDim = -1, int pDim = -1); - //##Documentation - //## initialize new (or re-initialize) image information by @a itkimage, - //## a templated itk-image. - //## Only the header is used, not the data vector! Use - //## SetVolume(itkimage->GetBufferPointer()) to set the data vector. - //## - //## @param tDim override time dimension in @a itkimage (if >0 and <) - //## @param sDim override z-space dimension in @a itkimage (if >0 and <) + /** + * initialize new (or re-initialize) image information by @a itkimage, + * a templated itk-image. + * Only the header is used, not the data vector! Use + * SetVolume(itkimage->GetBufferPointer()) to set the data vector. + * + * @param itkimage + * @param channels + * @param tDim override time dimension in @a itkimage (if >0 and <) + * @param sDim override z-space dimension in @a itkimage (if >0 and <) + */ template void InitializeByItk(const itkImageType *itkimage, int channels = 1, int tDim = -1, int sDim = -1) { if (itkimage == nullptr) return; MITK_DEBUG << "Initializing MITK image from ITK image."; // build array with dimensions in each direction with at least 4 entries m_Dimension = itkimage->GetImageDimension(); unsigned int i, *tmpDimensions = new unsigned int[m_Dimension > 4 ? m_Dimension : 4]; for (i = 0; i < m_Dimension; ++i) tmpDimensions[i] = itkimage->GetLargestPossibleRegion().GetSize().GetSize()[i]; if (m_Dimension < 4) { unsigned int *p; for (i = 0, p = tmpDimensions + m_Dimension; i < 4 - m_Dimension; ++i, ++p) *p = 1; } // overwrite number of slices if sDim is set if ((m_Dimension > 2) && (sDim >= 0)) tmpDimensions[2] = sDim; // overwrite number of time points if tDim is set if ((m_Dimension > 3) && (tDim >= 0)) tmpDimensions[3] = tDim; // rough initialization of Image // mitk::PixelType importType = ImportItkPixelType( itkimage::PixelType ); Initialize( MakePixelType(itkimage->GetNumberOfComponentsPerPixel()), m_Dimension, tmpDimensions, channels); const typename itkImageType::SpacingType &itkspacing = itkimage->GetSpacing(); MITK_DEBUG << "ITK spacing " << itkspacing; // access spacing of itk::Image Vector3D spacing; FillVector3D(spacing, itkspacing[0], 1.0, 1.0); if (m_Dimension >= 2) spacing[1] = itkspacing[1]; if (m_Dimension >= 3) spacing[2] = itkspacing[2]; // access origin of itk::Image Point3D origin; const typename itkImageType::PointType &itkorigin = itkimage->GetOrigin(); MITK_DEBUG << "ITK origin " << itkorigin; FillVector3D(origin, itkorigin[0], 0.0, 0.0); if (m_Dimension >= 2) origin[1] = itkorigin[1]; if (m_Dimension >= 3) origin[2] = itkorigin[2]; // access direction of itk::Imagm_PixelType = new mitk::PixelType(type);e and include spacing const typename itkImageType::DirectionType &itkdirection = itkimage->GetDirection(); MITK_DEBUG << "ITK direction " << itkdirection; mitk::Matrix3D matrix; matrix.SetIdentity(); unsigned int j, itkDimMax3 = (m_Dimension >= 3 ? 3 : m_Dimension); // check if spacing has no zero entry and itkdirection has no zero columns bool itkdirectionOk = true; mitk::ScalarType columnSum; for (j = 0; j < itkDimMax3; ++j) { columnSum = 0.0; for (i = 0; i < itkDimMax3; ++i) { columnSum += fabs(itkdirection[i][j]); } if (columnSum < mitk::eps) { itkdirectionOk = false; } if ((spacing[j] < -mitk::eps) // (normally sized) negative value && (j == 2) && (m_Dimensions[2] == 1)) { // Negative spacings can occur when reading single DICOM slices with ITK via GDCMIO // In these cases spacing is not determind by ITK correctly (because it distinguishes correctly // between slice thickness and inter slice distance -- slice distance is meaningless for // single slices). // I experienced that ITK produced something meaningful nonetheless because is is // evaluating the tag "(0018,0088) Spacing between slices" as a fallback. This tag is not // reliable (http://www.itk.org/pipermail/insight-users/2005-September/014711.html) // but gives at least a hint. // In real world cases I experienced that this tag contained the correct inter slice distance // with a negative sign, so we just invert such negative spacings. MITK_WARN << "Illegal value of itk::Image::GetSpacing()[" << j << "]=" << spacing[j] << ". Using inverted value " << -spacing[j]; spacing[j] = -spacing[j]; } else if (spacing[j] < mitk::eps) // value near zero { MITK_ERROR << "Illegal value of itk::Image::GetSpacing()[" << j << "]=" << spacing[j] << ". Using 1.0 instead."; spacing[j] = 1.0; } } if (itkdirectionOk == false) { MITK_ERROR << "Illegal matrix returned by itk::Image::GetDirection():" << itkdirection << " Using identity instead."; for (i = 0; i < itkDimMax3; ++i) for (j = 0; j < itkDimMax3; ++j) if (i == j) matrix[i][j] = spacing[j]; else matrix[i][j] = 0.0; } else { for (i = 0; i < itkDimMax3; ++i) for (j = 0; j < itkDimMax3; ++j) matrix[i][j] = itkdirection[i][j] * spacing[j]; } // re-initialize PlaneGeometry with origin and direction PlaneGeometry *planeGeometry = static_cast(GetSlicedGeometry(0)->GetPlaneGeometry(0)); planeGeometry->SetOrigin(origin); planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix); // re-initialize SlicedGeometry3D SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(0); slicedGeometry->InitializeEvenlySpaced(planeGeometry, m_Dimensions[2]); slicedGeometry->SetSpacing(spacing); // re-initialize TimeGeometry ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]); SetTimeGeometry(timeGeometry); // clean-up delete[] tmpDimensions; this->Initialize(); } - //##Documentation - //## @brief Check whether slice @a s at time @a t in channel @a n is valid, i.e., - //## is (or can be) inside of the image + /** + * @brief Check whether slice @a s at time @a t in channel @a n is valid, i.e., + * is (or can be) inside of the image + */ virtual bool IsValidSlice(int s = 0, int t = 0, int n = 0) const; - //##Documentation - //## @brief Check whether volume at time @a t in channel @a n is valid, i.e., - //## is (or can be) inside of the image + /** + * @brief Check whether volume at time @a t in channel @a n is valid, i.e., + * is (or can be) inside of the image + */ virtual bool IsValidVolume(int t = 0, int n = 0) const; - //##Documentation - //## @brief Check whether the channel @a n is valid, i.e., - //## is (or can be) inside of the image + /** + * @brief Check whether the channel @a n is valid, i.e., + * is (or can be) inside of the image + */ virtual bool IsValidChannel(int n = 0) const; - //##Documentation - //## @brief Returns true if an image is rotated, i.e. its geometry's - //## transformation matrix has nonzero elements besides the diagonal. - //## Non-diagonal elements are checked if larger then 1/1000 of the matrix' trace. + /** + * @brief Returns true if an image is rotated, i.e. its geometry's + * transformation matrix has nonzero elements besides the diagonal. + * Non-diagonal elements are checked if larger then 1/1000 of the matrix' trace. + */ bool IsRotated() const; - //##Documentation - //## @brief Get the sizes of all dimensions as an integer-array. - //## - //## @sa GetDimension(int i); + /** + * @brief Get the sizes of all dimensions as an integer-array. + * + * @sa GetDimension(int i); + */ unsigned int *GetDimensions() const; ImageDescriptor::Pointer GetImageDescriptor() const { return m_ImageDescriptor; } ChannelDescriptor GetChannelDescriptor(int id = 0) const { return m_ImageDescriptor->GetChannelDescriptor(id); } /** \brief Sets a geometry to an image. */ void SetGeometry(BaseGeometry *aGeometry3D) override; /** * @warning for internal use only */ virtual ImageDataItemPointer GetSliceData(int s = 0, int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; /** * @warning for internal use only */ virtual ImageDataItemPointer GetVolumeData(int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; /** * @warning for internal use only */ virtual ImageDataItemPointer GetChannelData(int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; /** \brief (DEPRECATED) Get the minimum for scalar images */ DEPRECATED(ScalarType GetScalarValueMin(int t = 0) const); /** \brief (DEPRECATED) Get the maximum for scalar images \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetScalarValueMax(int t = 0) const); /** \brief (DEPRECATED) Get the second smallest value for scalar images \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetScalarValue2ndMin(int t = 0) const); /** \brief (DEPRECATED) Get the smallest value for scalar images, but do not recompute it first \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetScalarValueMinNoRecompute(unsigned int t = 0) const); /** \brief (DEPRECATED) Get the second smallest value for scalar images, but do not recompute it first \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetScalarValue2ndMinNoRecompute(unsigned int t = 0) const); /** \brief (DEPRECATED) Get the second largest value for scalar images \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetScalarValue2ndMax(int t = 0) const); /** \brief (DEPRECATED) Get the largest value for scalar images, but do not recompute it first \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetScalarValueMaxNoRecompute(unsigned int t = 0) const); /** \brief (DEPRECATED) Get the second largest value for scalar images, but do not recompute it first \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetScalarValue2ndMaxNoRecompute(unsigned int t = 0) const); /** \brief (DEPRECATED) Get the count of voxels with the smallest scalar value in the dataset \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetCountOfMinValuedVoxels(int t = 0) const); /** \brief (DEPRECATED) Get the count of voxels with the largest scalar value in the dataset \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(ScalarType GetCountOfMaxValuedVoxels(int t = 0) const); /** \brief (DEPRECATED) Get the count of voxels with the largest scalar value in the dataset \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(unsigned int GetCountOfMaxValuedVoxelsNoRecompute(unsigned int t = 0) const); /** \brief (DEPRECATED) Get the count of voxels with the smallest scalar value in the dataset \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead */ DEPRECATED(unsigned int GetCountOfMinValuedVoxelsNoRecompute(unsigned int t = 0) const); /** \brief Returns a pointer to the ImageStatisticsHolder object that holds all statistics information for the image. All Get-methods for statistics properties formerly accessible directly from an Image object are now moved to the new \a ImageStatisticsHolder object. */ StatisticsHolderPointer GetStatistics() const { return m_ImageStatistics; } protected: mitkCloneMacro(Self); typedef itk::MutexLockHolder MutexHolder; int GetSliceIndex(int s = 0, int t = 0, int n = 0) const; int GetVolumeIndex(int t = 0, int n = 0) const; void ComputeOffsetTable(); virtual bool IsValidTimeStep(int t) const; void Expand(unsigned int timeSteps) override; virtual ImageDataItemPointer AllocateSliceData( int s = 0, int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; virtual ImageDataItemPointer AllocateVolumeData( int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; virtual ImageDataItemPointer AllocateChannelData( int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const; Image(); Image(const Image &other); ~Image() override; void Clear() override; - //## @warning Has to be called by every Initialize method! + /** @warning Has to be called by every Initialize method! */ void Initialize() override; void PrintSelf(std::ostream &os, itk::Indent indent) const override; mutable ImageDataItemPointerArray m_Channels; mutable ImageDataItemPointerArray m_Volumes; mutable ImageDataItemPointerArray m_Slices; mutable itk::SimpleFastMutexLock m_ImageDataArraysLock; unsigned int m_Dimension; unsigned int *m_Dimensions; ImageDescriptor::Pointer m_ImageDescriptor; size_t *m_OffsetTable; ImageDataItemPointer m_CompleteData; // Image statistics Holder replaces the former implementation directly inside this class friend class ImageStatisticsHolder; StatisticsHolderPointer m_ImageStatistics; private: ImageDataItemPointer GetSliceData_unlocked( int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer GetVolumeData_unlocked(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer GetChannelData_unlocked(int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer AllocateSliceData_unlocked( int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer AllocateVolumeData_unlocked(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const; ImageDataItemPointer AllocateChannelData_unlocked(int n, void *data, ImportMemoryManagementType importMemoryManagement) const; bool IsSliceSet_unlocked(int s, int t, int n) const; bool IsVolumeSet_unlocked(int t, int n) const; bool IsChannelSet_unlocked(int n) const; /** Stores all existing ImageReadAccessors */ mutable std::vector m_Readers; /** Stores all existing ImageWriteAccessors */ mutable std::vector m_Writers; /** Stores all existing ImageVtkAccessors */ mutable std::vector m_VtkReaders; /** A mutex, which needs to be locked to manage m_Readers and m_Writers */ itk::SimpleFastMutexLock m_ReadWriteLock; /** A mutex, which needs to be locked to manage m_VtkReaders */ itk::SimpleFastMutexLock m_VtkReadersLock; }; /** * @brief Equal A function comparing two images for beeing equal in meta- and imagedata * @warning This method is deprecated and will not be available in the future. Use the \a bool mitk::Equal(const * mitk::Image& i1, const mitk::Image& i2) instead. * * @ingroup MITKTestingAPI * * Following aspects are tested for equality: * - dimension of the images * - size of the images * - pixel type * - pixel values : pixel values are expected to be identical at each position ( for other options see * mitk::CompareImageFilter ) * * @param rightHandSide An image to be compared * @param leftHandSide An image to be compared * @param eps Tolarence for comparison. You can use mitk::eps in most cases. * @param verbose Flag indicating if the user wants detailed console output or not. * @return true, if all subsequent comparisons are true, false otherwise */ DEPRECATED(MITKCORE_EXPORT bool Equal( const mitk::Image *leftHandSide, const mitk::Image *rightHandSide, ScalarType eps, bool verbose)); /** * @brief Equal A function comparing two images for beeing equal in meta- and imagedata * * @ingroup MITKTestingAPI * * Following aspects are tested for equality: * - dimension of the images * - size of the images * - pixel type * - pixel values : pixel values are expected to be identical at each position ( for other options see * mitk::CompareImageFilter ) * * @param rightHandSide An image to be compared * @param leftHandSide An image to be compared * @param eps Tolarence for comparison. You can use mitk::eps in most cases. * @param verbose Flag indicating if the user wants detailed console output or not. * @return true, if all subsequent comparisons are true, false otherwise */ MITKCORE_EXPORT bool Equal(const mitk::Image &leftHandSide, const mitk::Image &rightHandSide, ScalarType eps, bool verbose); } // namespace mitk #endif /* MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 */ diff --git a/Modules/Core/include/mitkImagePixelAccessor.h b/Modules/Core/include/mitkImagePixelAccessor.h index 37565d4cc1..f15c77037f 100644 --- a/Modules/Core/include/mitkImagePixelAccessor.h +++ b/Modules/Core/include/mitkImagePixelAccessor.h @@ -1,138 +1,141 @@ /*============================================================================ 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 MITKIMAGEPIXELACCESSOR_H #define MITKIMAGEPIXELACCESSOR_H #include "mitkImage.h" #include "mitkImageDataItem.h" #include namespace mitk { /** * @brief Provides templated image access for all inheriting classes * @tparam TPixel defines the PixelType * @tparam VDimension defines the dimension for accessing data * @ingroup Data */ template class ImagePixelAccessor { public: typedef itk::Index IndexType; typedef ImagePixelAccessor ImagePixelAccessorType; typedef Image::ConstPointer ImageConstPointer; /** Get Dimensions from ImageDataItem */ int GetDimension(int i) const { return m_ImageDataItem->GetDimension(i); } private: friend class Image; protected: - /** \param ImageDataItem* specifies the allocated image part */ + /** + * \param iP + * \param iDI specifies the allocated image part + */ ImagePixelAccessor(ImageConstPointer iP, const mitk::ImageDataItem *iDI) : m_ImageDataItem(iDI) { if (iDI == nullptr) { m_ImageDataItem = iP->GetChannelData(); } CheckData(iP.GetPointer()); } /** Destructor */ virtual ~ImagePixelAccessor() {} void CheckData( const Image *image ) { // Check if Dimensions are correct if ( m_ImageDataItem == nullptr ) { if ( image->GetDimension() != VDimension ) { mitkThrow() << "Invalid ImageAccessor: The Dimensions of ImageAccessor and Image are not equal." << " They have to be equal if an entire image is requested." << " image->GetDimension(): " << image->GetDimension() << " , VDimension: " << VDimension; } } else { if ( m_ImageDataItem->GetDimension() != VDimension ) { mitkThrow() << "Invalid ImageAccessor: The Dimensions of ImageAccessor and ImageDataItem are not equal." << " m_ImageDataItem->GetDimension(): " << m_ImageDataItem->GetDimension() << " , VDimension: " << VDimension; } } if (!( image->GetPixelType() == mitk::MakePixelType< itk::Image< TPixel, VDimension > >() || image->GetPixelType() == mitk::MakePixelType< itk::VectorImage< TPixel, VDimension > > ( image->GetPixelType().GetNumberOfComponents() ) ) ) { mitkThrow() << "Invalid ImageAccessor: PixelTypes of Image and ImageAccessor are not equal." << " image->GetPixelType(): " << typeid(image->GetPixelType()).name() << "\n m_ImageDataItem->GetDimension(): " << m_ImageDataItem->GetDimension() << " , VDimension: " << VDimension << " , TPixel: " << typeid(TPixel).name() << " , NumberOfComponents: " << image->GetPixelType().GetNumberOfComponents() << std::endl; } } /** Holds the specified ImageDataItem */ const ImageDataItem *m_ImageDataItem; /** \brief Pointer to the used Geometry. * Since Geometry can be different to the Image (if memory was forced to be coherent) it is necessary to store * Geometry separately. */ BaseGeometry::Pointer m_Geometry; /** \brief A Subregion defines an arbitrary area within the image. * If no SubRegion is defined, the whole ImageDataItem or Image is regarded. * A subregion (e.g. subvolume) can lead to non-coherent memory access where every dimension has a start- and * end-offset. */ itk::ImageRegion *m_SubRegion; /** \brief Stores all extended properties of an ImageAccessor. * The different flags in mitk::ImageAccessorBase::Options can be unified by bitwise operations. */ int m_Options; /** Get memory offset for a given image index */ unsigned int GetOffset(const IndexType &idx) const { const unsigned int *imageDims = m_ImageDataItem->m_Dimensions; unsigned int offset = 0; switch (VDimension) { case 4: offset += idx[3] * imageDims[0] * imageDims[1] * imageDims[2]; /* FALLTHRU */ case 3: offset += idx[2] * imageDims[0] * imageDims[1]; /* FALLTHRU */ case 2: offset += idx[0] + idx[1] * imageDims[0]; /* FALLTHRU */ default: break; } return offset; } }; } #endif // MITKIMAGEACCESSOR_H diff --git a/Modules/Core/include/mitkImagePixelReadAccessor.h b/Modules/Core/include/mitkImagePixelReadAccessor.h index 5eb0a5ec6c..a4e4d1ad67 100644 --- a/Modules/Core/include/mitkImagePixelReadAccessor.h +++ b/Modules/Core/include/mitkImagePixelReadAccessor.h @@ -1,192 +1,192 @@ /*============================================================================ 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 MITKIMAGEPIXELREADACCESSOR_H #define MITKIMAGEPIXELREADACCESSOR_H #include "mitkImagePixelAccessor.h" #include "mitkImageReadAccessor.h" namespace mitk { class Image; /** * @brief Gives locked and index-based read access for a particular image part. * The class provides several set- and get-methods, which allow an easy pixel access. * It needs to know about pixel type and dimension of its image at compile time. * @tparam TPixel defines the PixelType * @tparam VDimension defines the dimension for accessing data * @ingroup Data */ template class ImagePixelReadAccessor : public ImagePixelAccessor { friend class Image; public: typedef ImagePixelAccessor ImagePixelAccessorType; typedef itk::SmartPointer ImagePointer; typedef itk::SmartPointer ImageConstPointer; /** \brief Instantiates a mitk::ImageReadAccessor (see its doxygen page for more details) - * \param Image::Pointer specifies the associated Image - * \param ImageDataItem* specifies the allocated image part + * \param iP specifies the associated Image + * \param iDI specifies the allocated image part * \param OptionFlags properties from mitk::ImageAccessorBase::Options can be chosen and assembled with bitwise * unification. * \throws mitk::Exception if the Constructor was created inappropriately * \throws mitk::MemoryIsLockedException if requested image area is exclusively locked and * mitk::ImageAccessorBase::ExceptionIfLocked is set in OptionFlags * * Includes a check if typeid of PixelType coincides with templated TPixel * and a check if VDimension equals to the Dimension of the Image. */ ImagePixelReadAccessor(ImageConstPointer iP, const ImageDataItem *iDI = nullptr, int OptionFlags = ImageAccessorBase::DefaultBehavior) : ImagePixelAccessor(iP, iDI), m_ReadAccessor(iP, iDI, OptionFlags) { } ImagePixelReadAccessor(ImagePointer iP, const ImageDataItem *iDI = nullptr, int OptionFlags = ImageAccessorBase::DefaultBehavior) : ImagePixelAccessor(iP.GetPointer(), iDI), m_ReadAccessor(iP, iDI, OptionFlags) { } ImagePixelReadAccessor(Image *iP, const ImageDataItem *iDI = nullptr, int OptionFlags = ImageAccessorBase::DefaultBehavior) : ImagePixelAccessor(iP, iDI), m_ReadAccessor(mitk::Image::ConstPointer(iP), iDI, OptionFlags) { } ImagePixelReadAccessor(const Image *iP, const ImageDataItem *iDI = nullptr, int OptionFlags = ImageAccessorBase::DefaultBehavior) : ImagePixelAccessor(iP, iDI), m_ReadAccessor(iP, iDI, OptionFlags) { } /** Destructor informs Image to unlock memory. */ ~ImagePixelReadAccessor() override {} /** Returns a const reference to the pixel at given index. */ const TPixel &GetPixelByIndex(const itk::Index &idx) const { unsigned int offset = ImagePixelAccessorType::GetOffset(idx); return *(((TPixel *)m_ReadAccessor.m_AddressBegin) + offset); } itk::VariableLengthVector GetConsecutivePixelsAsVector(const itk::Index &idx, int nrComponents) const { return itk::VariableLengthVector( (TPixel *)m_ReadAccessor.m_AddressBegin + ImagePixelAccessorType::GetOffset(idx) * m_ReadAccessor.GetImage()->GetPixelType().GetNumberOfComponents(), nrComponents); } /** Extends GetPixel by integrating index validation to prevent overflow. * \throws mitk::Exception in case of overflow */ const TPixel &GetPixelByIndexSafe(const itk::Index &idx) const { unsigned int offset = ImagePixelAccessorType::GetOffset(idx); TPixel *targetAddress = ((TPixel *)m_ReadAccessor.m_AddressBegin) + offset; if (!(targetAddress >= m_ReadAccessor.m_AddressBegin && targetAddress < m_ReadAccessor.m_AddressEnd)) { mitkThrow() << "ImageAccessor Overflow: image access exceeds the requested image area at " << idx << "."; } return *targetAddress; } /** Returns a const reference to the pixel at given world coordinate - works only with three-dimensional * ImageAccessor */ const TPixel &GetPixelByWorldCoordinates(mitk::Point3D position) { itk::Index<3> itkIndex; m_ReadAccessor.GetImage()->GetGeometry()->WorldToIndex(position, itkIndex); return GetPixelByIndex(itkIndex); } /** Returns a const reference to the pixel at given world coordinate - works only with four-dimensional * ImageAccessor */ const TPixel &GetPixelByWorldCoordinates(mitk::Point3D position, unsigned int timestep) { itk::Index<3> itkIndex; m_ReadAccessor.GetImage()->GetGeometry()->WorldToIndex(position, itkIndex); if (m_ReadAccessor.GetImage()->GetTimeSteps() < timestep) { timestep = m_ReadAccessor.GetImage()->GetTimeSteps(); } itk::Index<4> itk4Index; for (int i = 0; i < 3; ++i) itk4Index[i] = itkIndex[i]; itk4Index[3] = timestep; return GetPixelByIndex(itk4Index); } /** \brief Gives const access to the data. */ inline const TPixel *GetData() const { return static_cast(m_ReadAccessor.m_AddressBegin); } protected: // protected members private: ImageReadAccessor m_ReadAccessor; ImagePixelReadAccessor &operator=(const ImagePixelReadAccessor &); // Not implemented on purpose. ImagePixelReadAccessor(const ImagePixelReadAccessor &); }; /** Static method that gets direct access to a single pixel value. * The value is not guaranteed to be in a well-defined state and is automatically casted to mitk::ScalarType * The method can be called by the macros in mitkPixelTypeMultiplex.h */ template mitk::ScalarType FastSinglePixelAccess(mitk::PixelType, mitk::Image::Pointer im, ImageDataItem *item, itk::Index<3> idx, mitk::ScalarType &val, int component = 0) { ImagePixelReadAccessor imAccess(im, item, mitk::ImageAccessorBase::IgnoreLock); val = imAccess.GetConsecutivePixelsAsVector(idx, component + 1).GetElement(component); return val; } /** Const overload of FastSinglePixelAccess*/ template mitk::ScalarType FastSinglePixelAccess(mitk::PixelType, mitk::Image::ConstPointer im, const ImageDataItem* item, itk::Index<3> idx, mitk::ScalarType& val, int component = 0) { ImagePixelReadAccessor imAccess(im, item, mitk::ImageAccessorBase::IgnoreLock); val = imAccess.GetConsecutivePixelsAsVector(idx, component + 1).GetElement(component); return val; } } #endif // MITKIMAGEPIXELREADACCESSOR_H diff --git a/Modules/Core/include/mitkImagePixelWriteAccessor.h b/Modules/Core/include/mitkImagePixelWriteAccessor.h index 40b0e50cd2..25b3b20943 100644 --- a/Modules/Core/include/mitkImagePixelWriteAccessor.h +++ b/Modules/Core/include/mitkImagePixelWriteAccessor.h @@ -1,138 +1,138 @@ /*============================================================================ 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 MITKIMAGEPIXELWRITEACCESSOR_H #define MITKIMAGEPIXELWRITEACCESSOR_H #include "mitkImagePixelAccessor.h" #include "mitkImageWriteAccessor.h" namespace mitk { /** * @brief Gives locked and index-based write access for a particular image part. * The class provides several set- and get-methods, which allow an easy pixel access. * It needs to know about pixel type and dimension of its image at compile time. * @tparam TPixel defines the PixelType * @tparam VDimension defines the dimension for accessing data * @ingroup Data */ template class ImagePixelWriteAccessor : public ImagePixelAccessor { friend class Image; public: typedef ImagePixelAccessor ImagePixelAccessorType; typedef itk::SmartPointer ImagePointer; /** \brief Instantiates a mitk::ImageWriteAccessor (see its doxygen page for more details) - * \param Image::Pointer specifies the associated Image - * \param ImageDataItem* specifies the allocated image part + * \param iP specifies the associated Image + * \param iDI specifies the allocated image part * \param OptionFlags properties from mitk::ImageAccessorBase::Options can be chosen and assembled with bitwise * unification. * \throws mitk::Exception if the Constructor was created inappropriately * \throws mitk::MemoryIsLockedException if requested image area is exclusively locked and * mitk::ImageAccessorBase::ExceptionIfLocked is set in OptionFlags * * Includes a check if typeid of PixelType coincides with templated TPixel * and a check if VDimension equals to the Dimension of the Image. * * \note * To avoid intermittent Update() calls to a predecessing filter pipeline, a call to Modifed() method after the * access is finished is left to the developer. */ ImagePixelWriteAccessor(ImagePointer iP, const ImageDataItem *iDI = nullptr, int OptionFlags = ImageAccessorBase::DefaultBehavior) : ImagePixelAccessor(iP.GetPointer(), iDI), m_WriteAccessor(iP, iDI, OptionFlags) { } /** \brief Gives full data access. */ virtual inline TPixel *GetData() const { return static_cast(m_WriteAccessor.m_AddressBegin); } /// Sets a pixel value at given index. void SetPixelByIndex(const itk::Index &idx, const TPixel &value) { unsigned int offset = ImagePixelAccessor::GetOffset(idx); *(((TPixel *)m_WriteAccessor.m_AddressBegin) + offset) = value; } /** Extends SetPixel by integrating index validation to prevent overflow. */ void SetPixelByIndexSafe(const itk::Index &idx, const TPixel &value) { unsigned int offset = ImagePixelAccessorType::GetOffset(idx); TPixel *targetAddress = ((TPixel *)m_WriteAccessor.m_AddressBegin) + offset; if (targetAddress >= m_WriteAccessor.m_AddressBegin && targetAddress < m_WriteAccessor.m_AddressEnd) { *targetAddress = value; } else { // printf("image dimensions = %d, %d, %d\n", imageDims[0], imageDims[1], imageDims[2]); // printf("m_AddressBegin: %p, m_AddressEnd: %p, offset: %u\n", m_WriteAccessor.m_AddressBegin, // m_WriteAccessor.m_AddressEnd, offset); mitkThrow() << "ImageAccessor Overflow: image access exceeds the requested image area at " << idx << "."; } } /** Returns a const reference to the pixel at given index. */ const TPixel &GetPixelByIndex(const itk::Index &idx) const { unsigned int offset = ImagePixelAccessorType::GetOffset(idx); return *(((TPixel *)m_WriteAccessor.m_AddressBegin) + offset); } /** Extends GetPixel by integrating index validation to prevent overflow. * \throws mitk::Exception in case of overflow */ const TPixel &GetPixelByIndexSafe(const itk::Index &idx) const { unsigned int offset = ImagePixelAccessorType::GetOffset(idx); TPixel *targetAddress = ((TPixel *)m_WriteAccessor.m_AddressBegin) + offset; if (!(targetAddress >= m_WriteAccessor.m_AddressBegin && targetAddress < m_WriteAccessor.m_AddressEnd)) { mitkThrow() << "ImageAccessor Overflow: image access exceeds the requested image area at " << idx << "."; } return *targetAddress; } /** Returns a const reference to the pixel at given world coordinate - works only with three-dimensional * ImageAccessor */ const TPixel &GetPixelByWorldCoordinates(mitk::Point3D position) { itk::Index<3> itkIndex; m_WriteAccessor.GetImage()->GetGeometry()->WorldToIndex(position, itkIndex); return GetPixelByIndex(itkIndex); } /** Returns a reference to the pixel at given world coordinate */ void SetPixelByWorldCoordinates(const mitk::Point3D &, const TPixel &value, unsigned int timestep = 0); ~ImagePixelWriteAccessor() override {} private: ImageWriteAccessor m_WriteAccessor; ImagePixelWriteAccessor &operator=(const ImagePixelWriteAccessor &); // Not implemented on purpose. ImagePixelWriteAccessor(const ImagePixelWriteAccessor &); }; } #endif // MITKIMAGEWRITEACCESSOR_H diff --git a/Modules/Core/include/mitkImageReadAccessor.h b/Modules/Core/include/mitkImageReadAccessor.h index db2409d416..4cd1f30337 100644 --- a/Modules/Core/include/mitkImageReadAccessor.h +++ b/Modules/Core/include/mitkImageReadAccessor.h @@ -1,73 +1,73 @@ /*============================================================================ 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 MITKIMAGEREADACCESSOR_H #define MITKIMAGEREADACCESSOR_H #include "mitkImageAccessorBase.h" namespace mitk { class Image; class ImageDataItem; /** * @brief ImageReadAccessor class to get locked read access for a particular image part * @ingroup Data */ class MITKCORE_EXPORT ImageReadAccessor : public ImageAccessorBase { friend class Image; template friend class ImagePixelReadAccessor; public: typedef itk::SmartPointer ImagePointer; /** \brief Orders read access for a slice, volume or 4D-Image - * \param Image::Pointer specifies the associated Image - * \param ImageDataItem* specifies the allocated image part + * \param image specifies the associated Image + * \param iDI specifies the allocated image part * \param OptionFlags properties from mitk::ImageAccessorBase::Options can be chosen and assembled with bitwise * unification. * \throws mitk::Exception if the Constructor was created inappropriately * \throws mitk::MemoryIsLockedException if requested image area is exclusively locked and * mitk::ImageAccessorBase::ExceptionIfLocked is set in OptionFlags */ ImageReadAccessor(ImageConstPointer image, const ImageDataItem *iDI = nullptr, int OptionFlags = ImageAccessorBase::DefaultBehavior); ImageReadAccessor(ImagePointer image, const ImageDataItem *iDI = nullptr, int OptionFlags = ImageAccessorBase::DefaultBehavior); ImageReadAccessor(const Image *image, const ImageDataItem *iDI = nullptr); /** Destructor informs Image to unlock memory. */ ~ImageReadAccessor() override; protected: const Image *GetImage() const override; private: /** \brief manages a consistent read access and locks the ordered image part */ void OrganizeReadAccess(); ImageReadAccessor &operator=(const ImageReadAccessor &); // Not implemented on purpose. ImageReadAccessor(const ImageReadAccessor &); ImageConstPointer m_Image; }; } #endif // MITKIMAGEACCESSOR_H diff --git a/Modules/Core/include/mitkImageToSurfaceFilter.h b/Modules/Core/include/mitkImageToSurfaceFilter.h index 3a0b8eeab6..01c0d93c22 100644 --- a/Modules/Core/include/mitkImageToSurfaceFilter.h +++ b/Modules/Core/include/mitkImageToSurfaceFilter.h @@ -1,249 +1,247 @@ /*============================================================================ 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 _MITKIMAGETOSURFACEFILTER_h__ #define _MITKIMAGETOSURFACEFILTER_h__ #include "MitkCoreExports.h" #include #include #include #include #include #include #include #include namespace mitk { /** * @brief Converts pixel data to surface data by using a threshold * The mitkImageToSurfaceFilter is used to create a new surface out of an mitk image. The filter * uses a threshold to define the surface. It is based on the vtkMarchingCube algorithm. By default * a vtkPolyData surface based on an input threshold for the input image will be created. Optional * it is possible to reduce the number of triangles/polygones [SetDecimate(mitk::ImageToSurfaceFilter::DecimatePro) and * SetTargetReduction (float _arg)] * or smooth the surface-data [SetSmooth(true), SetSmoothIteration(int smoothIteration) and SetSmoothRelaxation(float * smoothRelaxation)]. * * The resulting vtk-surface has the same size as the input image. The surface * can be generally smoothed by vtkDecimatePro reduce complexity of triangles * and vtkSmoothPolyDataFilter to relax the mesh. Both are enabled by default * and connected in the common way of pipelining in ITK. It's also possible * to create time sliced surfaces. * * @ingroup ImageFilters * @ingroup Process */ class MITKCORE_EXPORT ImageToSurfaceFilter : public SurfaceSource { public: /* * To decide whether a reduction of polygons in the created surface shall be * done or not by using the vtkDecimatePro Filter. Till vtk 4.x an vtkDecimateFilter existed, * but was patented. So since vtk 5.x it was replaced by the (worser?) vtkDecimateProFilter * Maybe another Filter will come soon. */ enum DecimationType { NoDecimation, DecimatePro, QuadricDecimation }; mitkClassMacro(ImageToSurfaceFilter, SurfaceSource); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** * For each image time slice a surface will be created. This method is * called by Update(). */ void GenerateData() override; /** * Initializes the output information ( i.e. the geometry information ) of * the output of the filter */ void GenerateOutputInformation() override; /** * Returns a const reference to the input image (e.g. the original input image that ist used to create the surface) */ const mitk::Image *GetInput(void); /** * Set the source image to create a surface for this filter class. As input every mitk * 3D or 3D+t image can be used. */ using itk::ProcessObject::SetInput; virtual void SetInput(const mitk::Image *image); /** * Set the number of iterations that is used to smooth the surface. Used is the vtkSmoothPolydataFilter that uses * the * laplacian filter. The higher the number of iterations that stronger the smooth-result * * @param smoothIteration As smoothIteration default in that case 50 was choosen. The VTK documentation recommends * small relaxation factors and large numbers of iterations. */ void SetSmoothIteration(int smoothIteration); /** * Set number of relaxation. Specify the relaxation factor for Laplacian * smoothing. The VTK documentation recommends small relaxation factors * and large numbers of iterations. * * @param smoothRelaxation As smoothRelaxation default in that case 0.1 was choosen. The VTK documentation * recommends * small relaxation factors and large numbers of iterations. */ void SetSmoothRelaxation(float smoothRelaxation); /** * Threshold that is used to create the surface. All pixel in the input image that are higher than that * value will be considered in the surface. The threshold referees to * vtkMarchingCube. Default value is 1. See also SetThreshold (ScalarType _arg) */ itkSetMacro(Threshold, ScalarType); /** * Get Threshold from vtkMarchingCube. Threshold can be manipulated by * inherited classes. */ itkGetConstMacro(Threshold, ScalarType); /** * Enables vtkSmoothPolyDataFilter. With Laplacian smoothing this filter * will relax the surface. You can control the Filter by manipulating the * number of iterations and the relaxing factor. * */ itkSetMacro(Smooth, bool); /* * Enable/Disable surface smoothing. */ itkBooleanMacro(Smooth); /* * Returns if surface smoothing is enabled */ itkGetConstMacro(Smooth, bool); /** * Get the state of decimation mode to reduce triangle in the * surface represantation. Modes can only be NoDecimation or DecimatePro * (till vtk 4.x also Decimate) * */ itkGetConstMacro(Decimate, DecimationType); /** * Enable the decimation filter to reduce the number of triangles in the * mesh and produce a good approximation to the original image. The filter * has support for vtk-5 and earlier versions. More detailed information * check the vtkDecimatePro and vtkDecimate. * */ itkSetMacro(Decimate, DecimationType); /** * Set desired TargetReduction of triangles in the range from 0.0 to 1.0. * The destroyed triangles are in relation with the size of data. For example 0.9 * will reduce the data set to 10%. - * - * @param Set a TargetReduction float-value from 0.0 to 1.0 - * */ + */ itkSetMacro(TargetReduction, float); /** * Returns the reduction factor for the VtkDecimatePro Decimation Filter as a float value */ itkGetConstMacro(TargetReduction, float); /** * Transforms a point by a 4x4 matrix */ template inline void mitkVtkLinearTransformPoint(T1 matrix[4][4], T2 in[3], T3 out[3]) { T3 x = matrix[0][0] * in[0] + matrix[0][1] * in[1] + matrix[0][2] * in[2] + matrix[0][3]; T3 y = matrix[1][0] * in[0] + matrix[1][1] * in[1] + matrix[1][2] * in[2] + matrix[1][3]; T3 z = matrix[2][0] * in[0] + matrix[2][1] * in[1] + matrix[2][2] * in[2] + matrix[2][3]; out[0] = x; out[1] = y; out[2] = z; } protected: ImageToSurfaceFilter(); /** * Destructor * */ ~ImageToSurfaceFilter() override; /** * With the given threshold vtkMarchingCube creates the surface. By default nothing a * vtkPolyData surface based on a threshold of the input image will be created. Optional * it is possible to reduce the number of triangles/polygones [SetDecimate(mitk::ImageToSurfaceFilter::DecimatePro) * and * SetTargetReduction (float _arg)] * or smooth the data [SetSmooth(true), SetSmoothIteration(int smoothIteration) and SetSmoothRelaxation(float * smoothRelaxation)]. * * @param time selected slice or "0" for single * @param *vtkimage input image * @param *surface output * @param threshold can be different from SetThreshold() */ void CreateSurface(int time, vtkImageData *vtkimage, mitk::Surface *surface, const ScalarType threshold); /** * Flag whether the created surface shall be smoothed or not (default is "false"). SetSmooth (bool _arg) * */ bool m_Smooth; /** * Decimation mode, default mode is "NoDecimation". See also SetDecimate (DecimationType _arg) * */ DecimationType m_Decimate; /** * Threshold that is used to create the surface. All pixel in the input image that are higher than that * value will be considered in the surface. Default value is 1. See also SetThreshold (ScalarType _arg) * */ ScalarType m_Threshold; /** * The Reduction factor of the Decimation Filter for the created surface. See also SetTargetReduction (float _arg) * */ float m_TargetReduction; /** * The Iteration value for the Smooth Filter of the created surface. See also SetSmoothIteration (int * smoothIteration) * */ int m_SmoothIteration; /** * The Relaxation value for the Smooth Filter of the created surface. See also SetSmoothRelaxation (float * smoothRelaxation) * */ float m_SmoothRelaxation; }; } // namespace mitk #endif //_MITKIMAGETOSURFACEFILTER_h__ diff --git a/Modules/Core/include/mitkImageVtkMapper2D.h b/Modules/Core/include/mitkImageVtkMapper2D.h index 537b81c12a..2128a21b7c 100644 --- a/Modules/Core/include/mitkImageVtkMapper2D.h +++ b/Modules/Core/include/mitkImageVtkMapper2D.h @@ -1,323 +1,321 @@ /*============================================================================ 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 MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E #define MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E // MITK #include // MITK Rendering #include "mitkBaseRenderer.h" #include "mitkExtractSliceFilter.h" #include "mitkVtkMapper.h" // VTK #include #include class vtkActor; class vtkPolyDataMapper; class vtkPlaneSource; class vtkImageData; class vtkLookupTable; class vtkImageExtractComponents; class vtkImageReslice; class vtkImageChangeInformation; class vtkPoints; class vtkMitkThickSlicesFilter; class vtkPolyData; class vtkMitkApplyLevelWindowToRGBFilter; class vtkMitkLevelWindowFilter; namespace mitk { /** \brief Mapper to resample and display 2D slices of a 3D image. * * The following image gives a brief overview of the mapping and the involved parts. * * \image html imageVtkMapper2Darchitecture.png * * First, the image is resliced by means of vtkImageReslice. The volume image * serves as input to the mapper in addition to spatial placement of the slice and a few other * properties such as thick slices. This code was already present in the old version * (mitkImageMapperGL2D). * * Next, the obtained slice (m_ReslicedImage) is put into a vtkMitkLevelWindowFilter * and the scalar levelwindow, opacity levelwindow and optional clipping to * local image bounds are applied * * Next, the output of the vtkMitkLevelWindowFilter is used to create a texture * (m_Texture) and a plane onto which the texture is rendered (m_Plane). For * mapping purposes, a vtkPolyDataMapper (m_Mapper) is utilized. Orthographic * projection is applied to create the effect of a 2D image. The mapper and the * texture are assigned to the actor (m_Actor) which is passed to the VTK rendering * pipeline via the method GetVtkProp(). * * In order to transform the textured plane to the correct position in space, the * same transformation as used for reslicing is applied to both the camera and the * vtkActor. All important steps are explained in more detail below. The resulting * 2D image (by reslicing the underlying 3D input image appropriately) can either * be directly rendered in a 2D view or just be calculated to be used later by another * rendering entity, e.g. in texture mapping in a 3D view. * * Properties that can be set for images and influence the imageMapper2D are: * * - \b "opacity": (FloatProperty) Opacity of the image * - \b "color": (ColorProperty) Color of the image * - \b "LookupTable": (mitkLookupTableProperty) If this property is set, * the default lookuptable will be ignored and the "LookupTable" value * will be used instead. * - \b "Image Rendering.Mode": This property decides which mode is used to render images. (E.g. if a lookup table or a transferfunction is applied). Detailed documentation about the modes can be found here: \link mitk::RenderingModeProperty \endlink * - \b "Image Rendering.Transfer Function": (mitkTransferFunctionProperty) If this * property is set, a color transferfunction will be used to color the image. * - \b "binary": (BoolProperty) is the image a binary image or not * - \b "outline binary": (BoolProperty) show outline of the image or not * - \b "texture interpolation": (BoolProperty) texture interpolation of the image * - \b "reslice interpolation": (VtkResliceInterpolationProperty) reslice interpolation of the image * - \b "in plane resample extent by geometry": (BoolProperty) Do it or not * - \b "bounding box": (BoolProperty) Is the Bounding Box of the image shown or not * - \b "layer": (IntProperty) Layer of the image * - \b "volume annotation color": (ColorProperty) color of the volume annotation, TODO has to be reimplemented * - \b "volume annotation unit": (StringProperty) annotation unit as string (does not implicit convert the unit!) unit is ml or cm3, TODO has to be reimplemented * The default properties are: * - \b "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite ) * - \b "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ) * - \b "binary", mitk::BoolProperty::New( true ), renderer, overwrite ) * - \b "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite ) * - \b "texture interpolation", mitk::BoolProperty::New( false ) ) * - \b "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() ) * - \b "in plane resample extent by geometry", mitk::BoolProperty::New( false ) ) * - \b "bounding box", mitk::BoolProperty::New( false ) ) * - \b "layer", mitk::IntProperty::New(10), renderer, overwrite) * - \b "Image Rendering.Transfer Function": Default color transfer function for CTs * - \b "LookupTable": Rainbow color. * If the modality-property is set for an image, the mapper uses modality-specific default properties, * e.g. color maps, if they are defined. * \ingroup Mapper */ class MITKCORE_EXPORT ImageVtkMapper2D : public VtkMapper { public: /** Standard class typedefs. */ mitkClassMacro(ImageVtkMapper2D, VtkMapper); /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** \brief Get the Image to map */ const mitk::Image *GetInput(void); /** \brief Checks whether this mapper needs to update itself and generate * data. */ void Update(mitk::BaseRenderer *renderer) override; //### methods of MITK-VTK rendering pipeline vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override; //### end of methods of MITK-VTK rendering pipeline /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */ /** * To render transveral, coronal, and sagittal, the mapper is called three times. * For performance reasons, the corresponding data for each view is saved in the * internal helper class LocalStorage. This allows rendering n views with just * 1 mitkMapper using n vtkMapper. * */ class MITKCORE_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage { public: /** \brief Actor of the image in a 2D render window. */ vtkSmartPointer m_ImageActor; /** \brief Actor of the shadowimage in a 2D render window. */ vtkSmartPointer m_ShadowOutlineActor; /** Prop assembly containting everything for a regular display of the image.*/ vtkSmartPointer m_Actors; /** Prop assembly used if workspace is in an invalid state (e.g. invalid time point or * invalid world coordinate position is selected) and mapper has to "early out" * in Update() or GenerateDataForRenderer()*/ vtkSmartPointer m_EmptyActors; /** Prop assembly exposed publicly via ImagVtkMapper2D::GetVTKProp()*/ vtkProp* m_PublicActors = nullptr; /** \brief Mapper of a 2D render window. */ vtkSmartPointer m_Mapper; vtkSmartPointer m_VectorComponentExtractor; /** \brief Current slice of a 2D render window.*/ vtkSmartPointer m_ReslicedImage; /** \brief Empty vtkPolyData that is set when rendering geometry does not * intersect the image geometry. * \warning This member variable is set to nullptr, * if no image geometry is inside the plane geometry * of the respective render window. Any user of this * slice has to check whether it is set to nullptr! */ vtkSmartPointer m_EmptyPolyData; /** \brief Plane on which the slice is rendered as texture. */ vtkSmartPointer m_Plane; /** \brief The texture which is used to render the current slice. */ vtkSmartPointer m_Texture; /** \brief The lookuptables for colors and level window */ vtkSmartPointer m_DefaultLookupTable; vtkSmartPointer m_BinaryLookupTable; vtkSmartPointer m_ColorLookupTable; /** \brief The actual reslicer (one per renderer) */ mitk::ExtractSliceFilter::Pointer m_Reslicer; /** \brief Filter for thick slices */ vtkSmartPointer m_TSFilter; /** \brief PolyData object containg all lines/points needed for outlining the contour. This container is used to save a computed contour for the next rendering execution. For instance, if you zoom or pann, there is no need to recompute the contour. */ vtkSmartPointer m_OutlinePolyData; /** \brief Timestamp of last update of stored data. */ itk::TimeStamp m_LastUpdateTime; /** \brief mmPerPixel relation between pixel and mm. (World spacing).*/ mitk::ScalarType *m_mmPerPixel; /** \brief This filter is used to apply the level window to Grayvalue and RBG(A) images. */ vtkSmartPointer m_LevelWindowFilter; /** \brief Default constructor of the local storage. */ LocalStorage(); /** \brief Default deconstructor of the local storage. */ ~LocalStorage() override; }; /** \brief Get the LocalStorage corresponding to the current renderer. */ const LocalStorage *GetConstLocalStorage(mitk::BaseRenderer *renderer); /** \brief Set the default properties for general image rendering. */ static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false); /** \brief This method switches between different rendering modes (e.g. use a lookup table or a transfer function). * Detailed documentation about the modes can be found here: \link mitk::RenderingModeProperty \endlink */ void ApplyRenderingMode(mitk::BaseRenderer *renderer); protected: /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ mitk::LocalStorageHandler m_LSH; /** \brief Get the LocalStorage corresponding to the current renderer. */ LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer); /** \brief Transforms the actor to the actual position in 3D. * \param renderer The current renderer corresponding to the render window. */ void TransformActor(mitk::BaseRenderer *renderer); /** \brief Generates a plane according to the size of the resliced image in milimeters. - * - * \image html texturedPlane.png * * In VTK a vtkPlaneSource is defined through three points. The origin and two * points defining the axes of the plane (see VTK documentation). The origin is * set to (xMin; yMin; Z), where xMin and yMin are the minimal bounds of the * resliced image in space. Z is relevant for blending and the layer property. * The center of the plane (C) is also the center of the view plane (cf. the image above). * * \note For the standard MITK view with three 2D render windows showing three * different slices, three such planes are generated. All these planes are generated * in the XY-plane (even if they depict a YZ-slice of the volume). * */ void GeneratePlane(mitk::BaseRenderer *renderer, double planeBounds[6]); /** \brief Generates a vtkPolyData object containing the outline of a given binary slice. \param renderer: Pointer to the renderer containing the needed information \note This code is based on code from the iil library. */ template vtkSmartPointer CreateOutlinePolyData(mitk::BaseRenderer *renderer); /** Default constructor */ ImageVtkMapper2D(); /** Default deconstructor */ ~ImageVtkMapper2D() override; /** \brief Does the actual resampling, without rendering the image yet. * All the data is generated inside this method. The vtkProp (or Actor) * is filled with content (i.e. the resliced image). * * After generation, a 4x4 transformation matrix(t) of the current slice is obtained * from the vtkResliceImage object via GetReslicesAxis(). This matrix is * applied to each textured plane (actor->SetUserTransform(t)) to transform everything * to the actual 3D position (cf. the following image). * * \image html cameraPositioning3D.png * */ void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override; /** \brief This method uses the vtkCamera clipping range and the layer property * to calcualte the depth of the object (e.g. image or contour). The depth is used * to keep the correct order for the final VTK rendering.*/ float CalculateLayerDepth(mitk::BaseRenderer *renderer); /** \brief This method applies (or modifies) the lookuptable for all types of images. * \warning To use the lookup table, the property 'Lookup Table' must be set and a 'Image Rendering.Mode' * which uses the lookup table must be set. */ void ApplyLookuptable(mitk::BaseRenderer *renderer); /** \brief This method applies a color transfer function. * Internally, a vtkColorTransferFunction is used. This is usefull for coloring continous * images (e.g. float) * \warning To use the color transfer function, the property 'Image Rendering.Transfer Function' must be set and a * 'Image Rendering.Mode' which uses the color transfer function must be set. */ void ApplyColorTransferFunction(mitk::BaseRenderer *renderer); /** * @brief ApplyLevelWindow Apply the level window for the given renderer. * \warning To use the level window, the property 'LevelWindow' must be set and a 'Image Rendering.Mode' which uses * the level window must be set. * @param renderer Level window for which renderer? */ void ApplyLevelWindow(mitk::BaseRenderer *renderer); /** \brief Set the color of the image/polydata */ void ApplyColor(mitk::BaseRenderer *renderer); /** \brief Set the opacity of the actor. */ void ApplyOpacity(mitk::BaseRenderer *renderer); /** * \brief Calculates whether the given rendering geometry intersects the * given SlicedGeometry3D. * * This method checks if the given PlaneGeometry intersects the given * SlicedGeometry3D. It calculates the distance of the PlaneGeometry to all * 8 cornerpoints of the SlicedGeometry3D. If all distances have the same * sign (all positive or all negative) there is no intersection. * If the distances have different sign, there is an intersection. **/ bool RenderingGeometryIntersectsImage(const PlaneGeometry *renderingGeometry, SlicedGeometry3D *imageGeometry); /** Helper function to reset the local storage in order to indicate an invalid state.*/ void SetToInvalidState(mitk::ImageVtkMapper2D::LocalStorage* localStorage); }; } // namespace mitk #endif /* MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E */ diff --git a/Modules/Core/include/mitkImageVtkReadAccessor.h b/Modules/Core/include/mitkImageVtkReadAccessor.h index be0bd201a6..bf3207c890 100644 --- a/Modules/Core/include/mitkImageVtkReadAccessor.h +++ b/Modules/Core/include/mitkImageVtkReadAccessor.h @@ -1,53 +1,55 @@ /*============================================================================ 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 MITKIMAGEVTKREADACCESSOR_H #define MITKIMAGEVTKREADACCESSOR_H #include "mitkImageAccessorBase.h" class vtkImageData; namespace mitk { class Image; class ImageDataItem; /** * @brief ImageVtkReadAccessor class provides any image read access which is required by Vtk methods * @ingroup Data */ class MITKCORE_EXPORT ImageVtkReadAccessor : public ImageAccessorBase { public: /** \brief Creates an ImageVtkWriteAccessor for a whole Image - * \param Image::Pointer specifies the associated Image + * \param iP specifies the associated Image + * \param iDI + * \param imageDataVtk */ ImageVtkReadAccessor(ImageConstPointer iP, const ImageDataItem *iDI, const vtkImageData *imageDataVtk); ~ImageVtkReadAccessor() override; const vtkImageData *GetVtkImageData() const; // vtkTypeMacro(ImageVtkWriteAccessor,vtkDataSet) protected: const Image *GetImage() const override; private: // due to smart pointer issues, the image is only kept as a weak pointer. const Image *m_Image; const vtkImageData *m_ImageDataVtk; }; } #endif // MITKIMAGEVTKREADACCESSOR_H diff --git a/Modules/Core/include/mitkImageVtkWriteAccessor.h b/Modules/Core/include/mitkImageVtkWriteAccessor.h index 80493b7231..c71cfb220f 100644 --- a/Modules/Core/include/mitkImageVtkWriteAccessor.h +++ b/Modules/Core/include/mitkImageVtkWriteAccessor.h @@ -1,53 +1,55 @@ /*============================================================================ 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 MITKIMAGEVTKWRITEACCESSOR_H #define MITKIMAGEVTKWRITEACCESSOR_H #include "mitkImageAccessorBase.h" class vtkImageData; namespace mitk { class Image; class ImageDataItem; /** * @brief ImageVtkWriteAccessor class provides any image write access which is required by Vtk methods * @ingroup Data */ class MITKCORE_EXPORT ImageVtkWriteAccessor : public ImageAccessorBase { public: typedef itk::SmartPointer ImagePointer; /** \brief Creates an ImageVtkWriteAccessor for a whole Image - * \param Image::Pointer specifies the associated Image + * \param iP specifies the associated Image + * \param iDI + * \param imageDataVtk */ ImageVtkWriteAccessor(ImagePointer iP, const ImageDataItem *iDI, vtkImageData *imageDataVtk); ~ImageVtkWriteAccessor() override; vtkImageData *GetVtkImageData() const; protected: const Image *GetImage() const override; private: // due to smart pointer issues, the image is only kept as a weak pointer. Image *m_Image; vtkImageData *m_ImageDataVtk; }; } #endif // MITKIMAGEVTKWRITEACCESSOR_H diff --git a/Modules/Core/include/mitkImageWriteAccessor.h b/Modules/Core/include/mitkImageWriteAccessor.h index b48e3f9d52..14eb2d0a2b 100644 --- a/Modules/Core/include/mitkImageWriteAccessor.h +++ b/Modules/Core/include/mitkImageWriteAccessor.h @@ -1,64 +1,64 @@ /*============================================================================ 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 MITKIMAGEWRITEACCESSOR_H #define MITKIMAGEWRITEACCESSOR_H #include "mitkImage.h" #include "mitkImageAccessorBase.h" namespace mitk { /** * @brief ImageWriteAccessor class to get locked write-access for a particular image part. * @ingroup Data */ class MITKCORE_EXPORT ImageWriteAccessor : public ImageAccessorBase { template friend class ImagePixelReadAccessor; public: typedef Image::Pointer ImagePointer; /** \brief Orders write access for a slice, volume or 4D-Image - * \param Image::Pointer specifies the associated Image - * \param ImageDataItem* specifies the allocated image part + * \param image specifies the associated Image + * \param iDI specifies the allocated image part * \param OptionFlags properties from mitk::ImageAccessorBase::Options can be chosen and assembled with bitwise * unification. * \throws mitk::Exception if the Constructor was created inappropriately * \throws mitk::MemoryIsLockedException if requested image area is exclusively locked and * mitk::ImageAccessorBase::ExceptionIfLocked is set in OptionFlags */ ImageWriteAccessor(ImagePointer image, const ImageDataItem *iDI = nullptr, int OptionFlags = ImageAccessorBase::DefaultBehavior); /** \brief Gives full data access. */ inline void *GetData() { return m_AddressBegin; } /** \brief informs Image to unlock the represented image part */ ~ImageWriteAccessor() override; protected: const Image *GetImage() const override; private: /** \brief manages a consistent write access and locks the ordered image part */ void OrganizeWriteAccess(); ImageWriteAccessor &operator=(const ImageWriteAccessor &); // Not implemented on purpose. ImageWriteAccessor(const ImageWriteAccessor &); ImagePointer m_Image; }; } #endif // MITKIMAGEWRITEACCESSOR_H diff --git a/Modules/DICOM/doc/images/tilt-correction.jpg b/Modules/DICOM/doc/images/tilt-correction.jpg deleted file mode 100644 index 46712f6c86..0000000000 Binary files a/Modules/DICOM/doc/images/tilt-correction.jpg and /dev/null differ diff --git a/Modules/DICOM/include/mitkDICOMITKSeriesGDCMReader.h b/Modules/DICOM/include/mitkDICOMITKSeriesGDCMReader.h index 3e6c790bc4..743bb72645 100644 --- a/Modules/DICOM/include/mitkDICOMITKSeriesGDCMReader.h +++ b/Modules/DICOM/include/mitkDICOMITKSeriesGDCMReader.h @@ -1,377 +1,377 @@ /*============================================================================ 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 mitkDICOMITKSeriesGDCMReader_h #define mitkDICOMITKSeriesGDCMReader_h #include #include "itkMutexLock.h" #include "mitkDICOMFileReader.h" #include "mitkDICOMDatasetSorter.h" #include "mitkDICOMGDCMImageFrameInfo.h" #include "mitkEquiDistantBlocksSorter.h" #include "mitkNormalDirectionConsistencySorter.h" #include "MitkDICOMExports.h" namespace itk { class TimeProbesCollectorBase; } namespace mitk { /** \ingroup DICOMModule \brief Flexible reader based on itk::ImageSeriesReader and GDCM, for single-slice modalities like CT, MR, PET, CR, etc. Implements the loading processed as structured by DICOMFileReader offers configuration of its loading strategy. Documentation sections: - \ref DICOMITKSeriesGDCMReader_LoadingStrategy - \ref DICOMITKSeriesGDCMReader_ForcedConfiguration - \ref DICOMITKSeriesGDCMReader_UserConfiguration - \ref DICOMITKSeriesGDCMReader_GantryTilt - \ref DICOMITKSeriesGDCMReader_Testing - \ref DICOMITKSeriesGDCMReader_Internals - \ref DICOMITKSeriesGDCMReader_RelatedClasses - \ref DICOMITKSeriesGDCMReader_TiltInternals - \ref DICOMITKSeriesGDCMReader_Condensing \section DICOMITKSeriesGDCMReader_LoadingStrategy Loading strategy The set of input files is processed by a number of DICOMDatasetSorter objects which may do two sort of things: 1. split a list of input frames into multiple lists, based on DICOM tags such as "Rows", "Columns", which cannot be mixed within a single mitk::Image 2. sort the frames within the input lists, based on the values of DICOM tags such as "Image Position Patient" When the DICOMITKSeriesGDCMReader is configured with DICOMDatasetSorter%s, the list of input files is processed as follows: 1. build an initial set of output groups, simply by grouping all input files. 2. for each configured DICOMDatasetSorter, process: - for each output group: 1. set this group's files as input to the sorter 2. let the sorter sort (and split) 3. integrate the sorter's output groups with our own output groups \section DICOMITKSeriesGDCMReader_ForcedConfiguration Forced Configuration In all cases, the reader will add two DICOMDatasetSorter objects that are required to load mitk::Images properly via itk::ImageSeriesReader: 1. As a \b first step, the input files will be split into groups that are not compatible because they differ in essential aspects: - (0028,0010) Number of Rows - (0028,0011) Number of Columns - (0028,0030) Pixel Spacing - (0018,1164) Imager Pixel Spacing - (0020,0037) %Image Orientation (Patient) - (0018,0050) Slice Thickness - (0028,0008) Number of Frames - 2. As are two forced \b last steps: - 1. There will always be an instance of EquiDistantBlocksSorter, - which ensures that there is an equal distance between all the frames of an Image. - This is required to achieve correct geometrical positions in the mitk::Image, - i.e. it is essential to be able to make measurements in images. - - whether or not the distance is required to be orthogonal to the image planes is configured by SetFixTiltByShearing(). - - during this check, we need to tolerate some minor errors in documented vs. calculated image origins. - The amount of tolerance can be adjusted by SetToleratedOriginOffset() and SetToleratedOriginOffsetToAdaptive(). - Please see EquiDistantBlocksSorter for more details. The default should be good for most cases. - 2. There is always an instance of NormalDirectionConsistencySorter, - which makes the order of images go along the image normals (see NormalDirectionConsistencySorter) + 2. As are two forced \b last steps: + 1. There will always be an instance of EquiDistantBlocksSorter, + which ensures that there is an equal distance between all the frames of an Image. + This is required to achieve correct geometrical positions in the mitk::Image, + i.e. it is essential to be able to make measurements in images. + - whether or not the distance is required to be orthogonal to the image planes is configured by SetFixTiltByShearing(). + - during this check, we need to tolerate some minor errors in documented vs. calculated image origins. + The amount of tolerance can be adjusted by SetToleratedOriginOffset() and SetToleratedOriginOffsetToAdaptive(). + Please see EquiDistantBlocksSorter for more details. The default should be good for most cases. + 2. There is always an instance of NormalDirectionConsistencySorter, + which makes the order of images go along the image normals (see NormalDirectionConsistencySorter) \section DICOMITKSeriesGDCMReader_UserConfiguration User Configuration The user of this class can add more sorting steps (similar to the one described in above section) by calling AddSortingElement(). Usually, an application will add sorting by "Image Position Patient", by "Instance Number", and by other relevant tags here. \section DICOMITKSeriesGDCMReader_GantryTilt Gantry tilt handling When CT gantry tilt is used, the gantry plane (= X-Ray source and detector ring) and the vertical plane do not align anymore. This scanner feature is used for example to reduce metal artifacs (e.g. Lee C , Evaluation of Using CT Gantry Tilt Scan on Head and Neck Cancer Patients with Dental Structure: Scans Show Less Metal Artifacts. Presented at: Radiological Society of North America 2011 Scientific Assembly and Annual Meeting; November 27- December 2, 2011 Chicago IL.). The acquired planes of such CT series do not match the expectations of a orthogonal geometry in mitk::Image: if you stack the slices, they show a small shift along the Y axis: \verbatim without tilt with tilt |||||| ////// |||||| ////// -- |||||| --------- ////// -------- table orientation |||||| ////// |||||| ////// Stacked slices: without tilt with tilt -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- \endverbatim As such gemetries do not "work" in conjunction with mitk::Image, DICOMITKSeriesGDCMReader is able to perform a correction for such series. Whether or not such correction should be attempted is controlled by SetFixTiltByShearing(), the default being correction. For details, see "Internals" below. \section DICOMITKSeriesGDCMReader_Testing Testing A number of tests is implemented in module DICOMTesting, which is documented at \ref DICOMTesting. \section DICOMITKSeriesGDCMReader_Internals Class internals Internally, the class is based on GDCM and it depends heavily on the gdcm::Scanner class. Since the sorting elements (see DICOMDatasetSorter and DICOMSortCriterion) can access tags only via the DICOMDatasetAccess interface, BUT DICOMITKSeriesGDCMReader holds a list of more specific classes DICOMGDCMImageFrameInfo, we must convert between the two types sometimes. This explains the methods ToDICOMDatasetList(), FromDICOMDatasetList(). The intermediate result of all the sorting efforts is held in m_SortingResultInProgress, which is modified through InternalExecuteSortingStep(). \subsection DICOMITKSeriesGDCMReader_RelatedClasses Overview of related classes The following diagram gives an overview of the related classes: \image html implementeditkseriesgdcmreader.jpg \subsection DICOMITKSeriesGDCMReader_TiltInternals Details about the tilt correction The gantry tilt "correction" algorithm fixes two errors introduced by ITK's ImageSeriesReader: - the plane shift that is ignored by ITK's reader is recreated by applying a shearing transformation using itk::ResampleFilter. - the spacing is corrected (it is calculated by ITK's reader from the distance between two origins, which is NOT the slice distance in this special case) Both errors are introduced in itkImageSeriesReader.txx (ImageSeriesReader::GenerateOutputInformation(void)), lines 176 to 245 (as of ITK 3.20) For the correction, we examine two consecutive slices of a series, both described as a pair (origin/orientation): - we calculate if the first origin is on a line along the normal of the second slice - - if this is not the case, the geometry will not fit a normal mitk::Image/mitk::Geometry3D + - if this is not the case, the geometry will not fit a normal mitk::Image/mitk::%Geometry3D - we then project the second origin into the first slice's coordinate system to quantify the shift - both is done in class GantryTiltInformation with quite some comments. The geometry of image stacks with tilted geometries is illustrated below: - green: the DICOM images as described by their tags: origin as a point with the line indicating the orientation - red: the output of ITK ImageSeriesReader: wrong, larger spacing, no tilt - blue: how much a shear must correct - \image html tilt-correction.jpg + \image html Modules/DICOM/doc/Doxygen/tilt-correction.jpg \subsection DICOMITKSeriesGDCMReader_Condensing Sub-classes can condense multiple blocks into a single larger block The sorting/splitting process described above is helpful for at least two more DICOM readers, which either try to load 3D+t images or which load diffusion data. In both cases, a single pixel of the mitk::Image is made up of multiple values, in one case values over time, in the other case multiple measurements of a single point. The specialized readers for these cases (e.g. ThreeDnTDICOMSeriesReader) can reuse most of the methods in DICOMITKSeriesGDCMReader, except that they need an extra step after the usual sorting, in which they can merge already grouped 3D blocks. What blocks are merged depends on the specialized reader's understanding of these images. To allow for such merging, a method Condense3DBlocks() is called as an absolute last step of AnalyzeInputFiles(). Given this, a sub-class could implement only LoadImages() and Condense3DBlocks() instead repeating most of AnalyzeInputFiles(). */ class MITKDICOM_EXPORT DICOMITKSeriesGDCMReader : public DICOMFileReader { public: mitkClassMacro( DICOMITKSeriesGDCMReader, DICOMFileReader ); mitkCloneMacro( DICOMITKSeriesGDCMReader ); itkFactorylessNewMacro( DICOMITKSeriesGDCMReader ); mitkNewMacro1Param( DICOMITKSeriesGDCMReader, unsigned int ); mitkNewMacro2Param( DICOMITKSeriesGDCMReader, unsigned int, bool ); /** \brief Runs the sorting / splitting process described in \ref DICOMITKSeriesGDCMReader_LoadingStrategy. Method required by DICOMFileReader. */ void AnalyzeInputFiles() override; // void AllocateOutputImages(); /** \brief Loads images using itk::ImageSeriesReader, potentially applies shearing to correct gantry tilt. */ bool LoadImages() override; // re-implemented from super-class bool CanHandleFile(const std::string& filename) override; /** \brief Add an element to the sorting procedure described in \ref DICOMITKSeriesGDCMReader_LoadingStrategy. */ virtual void AddSortingElement(DICOMDatasetSorter* sorter, bool atFront = false); typedef const std::list ConstSorterList; ConstSorterList GetFreelyConfiguredSortingElements() const; /** \brief Controls whether to "fix" tilted acquisitions by shearing the output (see \ref DICOMITKSeriesGDCMReader_GantryTilt). */ void SetFixTiltByShearing(bool on); bool GetFixTiltByShearing() const; /** \brief Controls whether groups of only two images are accepted when ensuring consecutive slices via EquiDistantBlocksSorter. */ void SetAcceptTwoSlicesGroups(bool accept) const; bool GetAcceptTwoSlicesGroups() const; /** \brief See \ref DICOMITKSeriesGDCMReader_ForcedConfiguration. */ void SetToleratedOriginOffsetToAdaptive(double fractionOfInterSliceDistanct = 0.3) const; /** \brief See \ref DICOMITKSeriesGDCMReader_ForcedConfiguration. */ void SetToleratedOriginOffset(double millimeters = 0.005) const; /** \brief Ignore all dicom tags that are non-essential for simple 3D volume import. */ void SetSimpleVolumeReading(bool read) { m_SimpleVolumeReading = read; }; /** \brief Ignore all dicom tags that are non-essential for simple 3D volume import. */ bool GetSimpleVolumeReading() { return m_SimpleVolumeReading; }; double GetToleratedOriginError() const; bool IsToleratedOriginOffsetAbsolute() const; double GetDecimalPlacesForOrientation() const; bool operator==(const DICOMFileReader& other) const override; DICOMTagPathList GetTagsOfInterest() const override; static int GetDefaultDecimalPlacesForOrientation() { return m_DefaultDecimalPlacesForOrientation; } static bool GetDefaultSimpleVolumeImport() { return m_DefaultSimpleVolumeImport; } static bool GetDefaultFixTiltByShearing() { return m_DefaultFixTiltByShearing; } protected: void InternalPrintConfiguration(std::ostream& os) const override; /// \brief Return active C locale static std::string GetActiveLocale(); /** \brief Remember current locale on stack, activate "C" locale. "C" locale is required for correct parsing of numbers by itk::ImageSeriesReader */ void PushLocale() const; /** \brief Activate last remembered locale from locale stack "C" locale is required for correct parsing of numbers by itk::ImageSeriesReader */ void PopLocale() const; const static int m_DefaultDecimalPlacesForOrientation = 5; const static bool m_DefaultSimpleVolumeImport = false; const static bool m_DefaultFixTiltByShearing = true; DICOMITKSeriesGDCMReader(unsigned int decimalPlacesForOrientation = m_DefaultDecimalPlacesForOrientation, bool simpleVolumeImport = m_DefaultSimpleVolumeImport); ~DICOMITKSeriesGDCMReader() override; DICOMITKSeriesGDCMReader(const DICOMITKSeriesGDCMReader& other); DICOMITKSeriesGDCMReader& operator=(const DICOMITKSeriesGDCMReader& other); typedef std::vector SortingBlockList; /** \brief "Hook" for sub-classes, see \ref DICOMITKSeriesGDCMReader_Condensing \return REMAINING blocks */ virtual SortingBlockList Condense3DBlocks(SortingBlockList& resultOf3DGrouping); virtual DICOMTagCache::Pointer GetTagCache() const; void SetTagCache( const DICOMTagCache::Pointer& ) override; /// \brief Sorting step as described in \ref DICOMITKSeriesGDCMReader_LoadingStrategy static SortingBlockList InternalExecuteSortingStep( unsigned int sortingStepIndex, const DICOMDatasetSorter::Pointer& sorter, const SortingBlockList& input); /// \brief Loads the mitk::Image by means of an itk::ImageSeriesReader virtual bool LoadMitkImageForOutput(unsigned int o); virtual bool LoadMitkImageForImageBlockDescriptor(DICOMImageBlockDescriptor& block) const; /// \brief Describe this reader's confidence for given SOP class UID static ReaderImplementationLevel GetReaderImplementationLevel(const std::string sopClassUID); private: /// \brief Creates the required sorting steps described in \ref DICOMITKSeriesGDCMReader_ForcedConfiguration void EnsureMandatorySortersArePresent(unsigned int decimalPlacesForOrientation, bool simpleVolumeImport = false); protected: // NOT nice, made available to ThreeDnTDICOMSeriesReader due to lack of time bool m_FixTiltByShearing; // could be removed by ITKDICOMSeriesReader NOT flagging tilt unless requested to fix it! bool m_SimpleVolumeReading; private: SortingBlockList m_SortingResultInProgress; typedef std::list SorterList; SorterList m_Sorter; protected: // NOT nice, made available to ThreeDnTDICOMSeriesReader and ClassicDICOMSeriesReader due to lack of time mitk::EquiDistantBlocksSorter::Pointer m_EquiDistantBlocksSorter; mitk::NormalDirectionConsistencySorter::Pointer m_NormalDirectionConsistencySorter; private: static itk::MutexLock::Pointer s_LocaleMutex; mutable std::stack m_ReplacedCLocales; mutable std::stack m_ReplacedCinLocales; double m_DecimalPlacesForOrientation; DICOMTagCache::Pointer m_TagCache; bool m_ExternalCache; }; } #endif diff --git a/Modules/DICOM/include/mitkDICOMReaderConfigurator.h b/Modules/DICOM/include/mitkDICOMReaderConfigurator.h index f8e161e3a4..e098ee4b85 100644 --- a/Modules/DICOM/include/mitkDICOMReaderConfigurator.h +++ b/Modules/DICOM/include/mitkDICOMReaderConfigurator.h @@ -1,142 +1,142 @@ /*============================================================================ 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 mitkDICOMReaderConfigurator_h #define mitkDICOMReaderConfigurator_h #include "mitkClassicDICOMSeriesReader.h" #include "mitkDICOMTagBasedSorter.h" // to put into private implementation #include "tinyxml.h" namespace mitk { /** \ingroup DICOMModule \brief Too-simple factory to create DICOMFileReader%s. This class is able to instantiate and configure (where possible) DICOMFileReader%s from XML descriptions. \note This is a bad factory example, because the factory is not extensible and needs to know all the specific readers. A flexible implementation should be provided in a future version. In its current version, the XML input is meant to be structured like \verbatim \endverbatim - The root-tag \i names the class to be instantiated, currently this can be one of + The root-tag \c \ names the class to be instantiated, currently this can be one of - DICOMITKSeriesGDCMReader - ThreeDnTDICOMSeriesReader Both classes bring simple configuration flags with them and a description of how images are sorted prior to loading. Flag for DICOMITKSeriesGDCMReader:
fixTiltByShearing="true|false"
Determines whether a potential gantry tilt should be "fixed" by shearing the output image. Flag for ThreeDnTDICOMSeriesReader:
group3DnT="true|false"
Determines whether images at the same spatial position should be interpreted as 3D+t images. - The tags and describe the basic loading strategy of both - reader mentioned above: first images are divided into incompatible groups (), + The tags \c \ and \c \ describe the basic loading strategy of both + reader mentioned above: first images are divided into incompatible groups (\c \), and afterwards the images within each group are sorted by means of DICOMSortCriterion, which most commonly mentions a tag. Tag element and group are interpreted as the exadecimal numbers found all around the DICOM standard. The numbers can be prepended by a "0x" if this is preferred by the programmer (but they are taken as hexadecimal in all cases). \section DICOMReaderConfigurator_AboutTheFuture About the future evolution of this class This first version is hard coded for the current state of the implementation. If things should evolve in a way that needs us to splitt off readers for "old" versions, time should be taken to refactor this class. Basically, a serializer class should accompany each of the configurable classes. Such serializer classes should be registered and discovered via micro-services (to support extensions). A serializer should offer both methods to serialize a class and to desirialize it again. A "version" attribute at the top-level tag should be used to distinguish versions. Usually it should be enough to keep DE-serializers for all versions. Writers for the most recent version should be enough. */ class MITKDICOM_EXPORT DICOMReaderConfigurator : public itk::LightObject { public: mitkClassMacroItkParent( DICOMReaderConfigurator, itk::LightObject ); itkNewMacro( DICOMReaderConfigurator ); DICOMFileReader::Pointer CreateFromConfigFile(const std::string& filename) const; DICOMFileReader::Pointer CreateFromUTF8ConfigString(const std::string& xmlContents) const; std::string CreateConfigStringFromReader(DICOMFileReader::ConstPointer reader) const; protected: DICOMReaderConfigurator(); ~DICOMReaderConfigurator() override; private: DICOMFileReader::Pointer CreateFromTiXmlDocument(TiXmlDocument& doc) const; DICOMTag tagFromXMLElement(TiXmlElement*) const; std::string requiredStringAttribute(TiXmlElement* xmlElement, const std::string& key) const; unsigned int hexStringToUInt(const std::string& s) const; ThreeDnTDICOMSeriesReader::Pointer ConfigureThreeDnTDICOMSeriesReader(ThreeDnTDICOMSeriesReader::Pointer reader, TiXmlElement*) const; DICOMITKSeriesGDCMReader::Pointer ConfigureDICOMITKSeriesGDCMReader(DICOMITKSeriesGDCMReader::Pointer reader, TiXmlElement*) const; void ConfigureCommonPropertiesOfDICOMITKSeriesGDCMReader(DICOMITKSeriesGDCMReader::Pointer reader, TiXmlElement* element) const; void ConfigureCommonPropertiesOfThreeDnTDICOMSeriesReader(ThreeDnTDICOMSeriesReader::Pointer reader, TiXmlElement* element) const; DICOMSortCriterion::Pointer CreateDICOMSortByTag(TiXmlElement* xmlElement, DICOMSortCriterion::Pointer secondaryCriterion) const; DICOMSortCriterion::Pointer CreateSortByImagePositionPatient(TiXmlElement* xmlElement, DICOMSortCriterion::Pointer secondaryCriterion) const; mitk::DICOMTagBasedSorter::Pointer CreateDICOMTagBasedSorter(TiXmlElement* element) const; TiXmlElement* CreateConfigStringFromReader(const DICOMITKSeriesGDCMReader* reader) const; TiXmlElement* CreateConfigStringFromReader(const ThreeDnTDICOMSeriesReader* reader) const; TiXmlElement* CreateConfigStringFromReader(const ClassicDICOMSeriesReader* reader) const; TiXmlElement* CreateConfigStringFromDICOMDatasetSorter(const DICOMTagBasedSorter* sorter) const; TiXmlElement* CreateConfigStringFromDICOMTag(const DICOMTag& tag) const; TiXmlElement* CreateDICOMFileReaderTag(const DICOMFileReader* reader) const; const char* toString(bool) const; std::string toHexString(unsigned int i) const; /** Helper that queries an boolean xml attribute. If the attribute does not exist, the passed default value is used.*/ bool QueryBooleanAttribute(const TiXmlElement* element, const char* attributeName, bool defaultValue) const; }; } // namespace #endif // mitkDICOMReaderConfigurator_h diff --git a/Modules/DICOM/src/legacy/mitkDicomSeriesReader.h b/Modules/DICOM/src/legacy/mitkDicomSeriesReader.h index 12e83265e8..3a780617e0 100644 --- a/Modules/DICOM/src/legacy/mitkDicomSeriesReader.h +++ b/Modules/DICOM/src/legacy/mitkDicomSeriesReader.h @@ -1,1019 +1,1033 @@ /*============================================================================ 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 mitkDicomSeriesReader_h #define mitkDicomSeriesReader_h #include "mitkConfig.h" #include "mitkDataNode.h" #include #include #include #ifdef NOMINMAX #define DEF_NOMINMAX #undef NOMINMAX #endif #include #ifdef DEF_NOMINMAX #ifndef NOMINMAX #define NOMINMAX #endif #undef DEF_NOMINMAX #endif #include #include namespace mitk { /** \brief Loading DICOM images as MITK images. - \ref DicomSeriesReader_purpose - \ref DicomSeriesReader_limitations - \ref DicomSeriesReader_usage - \ref DicomSeriesReader_sorting - \ref DicomSeriesReader_sorting1 - \ref DicomSeriesReader_sorting2 - \ref DicomSeriesReader_sorting3 - \ref DicomSeriesReader_sorting4 - \ref DicomSeriesReader_gantrytilt - \ref DicomSeriesReader_pixelspacing - \ref DicomSeriesReader_nextworkitems - \ref DicomSeriesReader_whynotinitk - \ref DicomSeriesReader_tests \section DicomSeriesReader_purpose Purpose DicomSeriesReader serves as a central class for loading DICOM images as mitk::Image. As the term "DICOM image" covers a huge variety of possible modalities and implementations, and since MITK assumes that 3D images are made up of continuous blocks of slices without any gaps or changes in orientation, the loading mechanism must implement a number of decisions and compromises. The main intention of this implementation is not efficiency but correctness of generated slice positions and pixel spacings! \section DicomSeriesReader_limitations Assumptions and limitations The class is working only with GDCM 2.0.14 (or possibly newer). This version is the default of an MITK super-build. Support for other versions or ITK's DicomIO was dropped because of the associated complexity of DicomSeriesReader. \b Assumptions - expected to work with certain SOP Classes (mostly CT Image Storage and MR Image Storage) - see ImageBlockDescriptor.GetReaderImplementationLevel() method for the details - special treatment for a certain type of Philips 3D ultrasound (recogized by tag 3001,0010 set to "Philips3D") - loader will always attempt to read multiple single slices as a single 3D image volume (i.e. mitk::Image) - slices will be grouped by basic properties such as orientation, rows, columns, spacing and grouped into as large blocks as possible - images which do NOT report a position or orientation in space (Image Position Patient, Image Orientation) will be assigned defaults - image position (0,0,0) - image orientation (1,0,0), (0,1,0) - such images will always be grouped separately since spatial grouping / sorting makes no sense for them \b Options - images that cover the same piece of space (i.e. position, orientation, and dimensions are equal) can be interpreted as time-steps of the same image, i.e. a series will be loaded as 3D+t \b Limitations - the 3D+t assumption only works if all time-steps have an equal number of slices and if all have the Acquisition Time attribute set to meaningful values \section DicomSeriesReader_usage Usage The starting point for an application is a set of DICOM files that should be loaded. For convenience, DicomSeriesReader can also parse a whole directory for DICOM files, but an application should better know exactly what to load. Loading is then done in two steps: 1. Group the files into spatial blocks by calling GetSeries(). This method will sort all passed files into meaningful blocks that could fit into an mitk::Image. Sorting for 3D+t loading is optional but default. The \b return value of this function is a list of descriptors, which describe a grouped list of files with its most basic properties: - SOP Class (CT Image Storage, Secondary Capture Image Storage, etc.) - Modality - What type of pixel spacing can be read from the provided DICOM tags - How well DicomSeriesReader is prepared to load this type of data 2. Load a sorted set of files by calling LoadDicomSeries(). This method expects go receive the sorting output of GetSeries(). The method will then invoke ITK methods configured with GDCM-IO classes to actually load the files into memory and put them into mitk::Images. Again, loading as 3D+t is optional. Example: \code // only a directory is known at this point: /home/who/dicom DicomSeriesReader::FileNamesGrouping allImageBlocks = DicomSeriesReader::GetSeries("/home/who/dicom/"); // file now divided into groups of identical image size, orientation, spacing, etc. // each of these lists should be loadable as an mitk::Image. DicomSeriesReader::StringContainer seriesToLoad = allImageBlocks[...]; // decide what to load // final step: load into DataNode (can result in 3D+t image) DataNode::Pointer node = DicomSeriesReader::LoadDicomSeries( oneBlockSorted ); itk::SmartPointer image = dynamic_cast( node->GetData() ); \endcode \section DicomSeriesReader_sorting Logic for sorting 2D slices from DICOM images into 3D+t blocks for mitk::Image The general sorting mechanism (implemented in GetSeries) groups and sorts a set of DICOM files, each assumed to contain a single CT/MR slice. In the following we refer to those file groups as "blocks", since this is what they are meant to become when loaded into an mitk::Image. \subsection DicomSeriesReader_sorting1 Step 1: Avoiding pure non-sense A first pass separates slices that cannot possibly be loaded together because of restrictions of mitk::Image. After this steps, each block contains only slices that match in all of the following DICOM tags: - (0020,000e) Series Instance UID - (0020,0037) Image Orientation - (0028,0030) Pixel Spacing - (0018,1164) Imager Pixel Spacing - (0018,0050) Slice Thickness - (0028,0010) Number Of Rows - (0028,0011) Number Of Columns - (0028,0008) Number Of Frames \subsection DicomSeriesReader_sorting2 Step 2: Sort slices spatially Before slices are further analyzed, they are sorted spatially. As implemented by GdcmSortFunction(), slices are sorted by 1. distance from origin (calculated using (0020,0032) Image Position Patient and (0020,0037) Image Orientation) 2. when distance is equal, (0020,0012) Aquisition Number, (0008,0032) Acquisition Time and (0018,1060) Trigger Time are used as a backup criterions (necessary for meaningful 3D+t sorting) \subsection DicomSeriesReader_sorting3 Step 3: Ensure equal z spacing Since inter-slice distance is not recorded in DICOM tags, we must ensure that blocks are made up of slices that have equal distances between neighboring slices. This is especially necessary because itk::ImageSeriesReader is later used for the actual loading, and this class expects (and does nocht verify) equal inter-slice distance (see \ref DicomSeriesReader_whatweknowaboutitk). To achieve such grouping, the inter-slice distance is calculated from the first two different slice positions of a block. Following slices are added to a block as long as they can be added by adding the calculated inter-slice distance to the last slice of the block. Slices that do not fit into the expected distance pattern, are set aside for further analysis. This grouping is done until each file has been assigned to a group. Slices that share a position in space are also sorted into separate blocks during this step. So the result of this step is a set of blocks that contain only slices with equal z spacing and uniqe slices at each position. \subsection DicomSeriesReader_sorting4 Step 4 (optional): group 3D blocks as 3D+t when possible This last step depends on an option of GetSeries(). When requested, image blocks from the previous step are merged again whenever two blocks occupy the same portion of space (i.e. same origin, number of slices and z-spacing). \section DicomSeriesReader_gantrytilt Handling of gantry tilt When CT gantry tilt is used, the gantry plane (= X-Ray source and detector ring) and the vertical plane do not align anymore. This scanner feature is used for example to reduce metal artifacs (e.g. Lee C , Evaluation of Using CT Gantry Tilt Scan on Head and Neck Cancer Patients with Dental Structure: Scans Show Less Metal Artifacts. Presented at: Radiological Society of North America 2011 Scientific Assembly and Annual Meeting; November 27- December 2, 2011 Chicago IL.). The acquired planes of such CT series do not match the expectations of a orthogonal geometry in mitk::Image: if you stack the slices, they show a small shift along the Y axis: \verbatim without tilt with tilt |||||| ////// |||||| ////// -- |||||| --------- ////// -------- table orientation |||||| ////// |||||| ////// Stacked slices: without tilt with tilt -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- \endverbatim As such gemetries do not in conjunction with mitk::Image, DicomSeriesReader performs a correction for such series if the groupImagesWithGantryTilt or correctGantryTilt flag in GetSeries and LoadDicomSeries is set (default = on). The correction algorithms undoes two errors introduced by ITK's ImageSeriesReader: - the plane shift that is ignored by ITK's reader is recreated by applying a shearing transformation using itk::ResampleFilter. - the spacing is corrected (it is calculated by ITK's reader from the distance between two origins, which is NOT the slice distance in this special case) Both errors are introduced in itkImageSeriesReader.txx (ImageSeriesReader::GenerateOutputInformation(void)), lines 176 to 245 (as of ITK 3.20) For the correction, we examine two consecutive slices of a series, both described as a pair (origin/orientation): - we calculate if the first origin is on a line along the normal of the second slice - if this is not the case, the geometry will not fit a normal mitk::Image/mitk::Geometry3D - we then project the second origin into the first slice's coordinate system to quantify the shift - both is done in class GantryTiltInformation with quite some comments. The geometry of image stacks with tilted geometries is illustrated below: - green: the DICOM images as described by their tags: origin as a point with the line indicating the orientation - red: the output of ITK ImageSeriesReader: wrong, larger spacing, no tilt - blue: how much a shear must correct - \image tilt-correction.jpg + \image html Modules/DICOM/doc/Doxygen/tilt-correction.jpg \section DicomSeriesReader_whatweknowaboutitk The actual image loading process When calling LoadDicomSeries(), this method "mainly" uses an instance of itk::ImageSeriesReader, configured with an itk::GDCMImageIO object. Because DicomSeriesReader works around some of the behaviors of these classes, the following is a list of features that we find in the code and need to work with: - itk::ImageSeriesReader::GenerateOutputInformation() does the z-spacing handling + spacing is directly determined by comparing (euclidean distance) the origins of the first two slices of a series * this is GOOD because there is no reliable z-spacing information in DICOM images * this is bad because it does not work with gantry tilt, in which case the slice distance is SMALLER than the distance between two origins (see section on tilt) - origin and spacing are calculated by GDCMImageIO and re-used in itk::ImageSeriesReader + the origins are read from appropriate tags, nothing special about that + the spacing is read by gdcm::ImageReader, gdcm::ImageHelper::GetSpacingValue() from a tag determined by gdcm::ImageHelper::GetSpacingTagFromMediaStorage(), which basically determines ONE appropriate pixel spacing tag for each media storage type (ct image, mr image, secondary capture image, etc.) * this is fine for modalities such as CT/MR where the "Pixel Spacing" tag is mandatory, but for other modalities such as CR or Secondary Capture, the tag "Imager Pixel Spacing" is taken, which is no only optional but also has a more complicated relation with the "Pixel Spacing" tag. For this reason we check/modify the pixel spacing reported by itk::ImageSeriesReader after loading the image (see \ref DicomSeriesReader_pixelspacing) AFTER loading, DicomSeriesReader marks some of its findings as mitk::Properties to the loaded Image and DataNode: - dicomseriesreader.SOPClass : DICOM SOP Class as readable string (instead of a UID) - dicomseriesreader.ReaderImplementationLevelString : Confidence /Support level of the reader for this image as readable string - dicomseriesreader.ReaderImplementationLevel : Confidence /Support level of the reader for this image as enum value of type ReaderImplementationLevel - dicomseriesreader.PixelSpacingInterpretationString : Appropriate interpreteation of pixel spacing for this Image as readable string - dicomseriesreader.PixelSpacingInterpretation : Appropriate interpreteation of pixel spacing for this Image as enum value of type PixelSpacingInterpretation - dicomseriesreader.MultiFrameImage : bool flag to mark multi-frame images - dicomseriesreader.GantyTiltCorrected : bool flag to mark images where a gantry tilt was corrected to fit slices into an mitk::Image - dicomseriesreader.3D+t : bool flag to mark images with a time dimension (multiple 3D blocks of the same size at the same position in space) \section DicomSeriesReader_pixelspacing Handling of pixel spacing The reader implementes what is described in DICOM Part 3, chapter 10.7 (Basic Pixel Spacing Calibration Macro): Both tags - (0028,0030) Pixel Spacing and - (0018,1164) Imager Pixel Spacing are evaluated and the pixel spacing is set to the spacing within the patient when tags allow that. The result of pixel spacing interpretation can be read from a property "dicomseriesreader.PixelSpacingInterpretation", which refers to one of the enumerated values of type PixelSpacingInterpretation; \section DicomSeriesReader_supportedmodalities Limitations for specific modalities - Enhanced Computed Tomography / Magnetic Resonance Images are currently NOT supported at all, because we lack general support for multi-frame images. - Nuclear Medicine Images are not supported fully supported, only the single-frame variants are loaded properly. \section DicomSeriesReader_nextworkitems Possible enhancements This is a short list of ideas for enhancement: - Class has historically grown and should be reviewed again. There is probably too many duplicated scanning code - Multi-frame images don't mix well with the curent assumption of "one file - one slice", which is assumed by our code - It should be checked how well GDCM and ITK support these files (some load, some don't) - Specializations such as the Philips 3D code should be handled in a more generic way. The current handling of Philips 3D images is not nice at all \section DicomSeriesReader_whynotinitk Why is this not in ITK? Some of this code would probably be better located in ITK. It is just a matter of resources that this is not the case yet. Any attempts into this direction are welcome and can be supported. At least the gantry tilt correction should be a simple addition to itk::ImageSeriesReader. \section DicomSeriesReader_tests Tests regarding DICOM loading A number of tests have been implemented to check our assumptions regarding DICOM loading. Please see \ref DICOMTesting \todo refactor all the protected helper objects/methods into a separate header so we compile faster */ class Image; class DicomSeriesReader { public: /** \brief Lists of filenames. */ typedef std::vector StringContainer; /** \brief Interface for the progress callback. */ typedef void (*UpdateCallBackMethod)(float); /** \brief Describes how well the reader is tested for a certain file type. Applications should not rely on the outcome for images which are reported ReaderImplementationLevel_Implemented or ReaderImplementationLevel_Unsupported. Errors to load images which are reported as ReaderImplementationLevel_Supported are considered bugs. For ReaderImplementationLevel_PartlySupported please check the appropriate paragraph in \ref DicomSeriesReader_supportedmodalities */ typedef enum { ReaderImplementationLevel_Supported, /// loader code and tests are established ReaderImplementationLevel_PartlySupported, /// loader code and tests are establised for specific parts of a SOP /// Class ReaderImplementationLevel_Implemented, /// loader code is implemented but not accompanied by tests ReaderImplementationLevel_Unsupported, /// loader code is not working with this SOP Class } ReaderImplementationLevel; /** \brief How the mitk::Image spacing should be interpreted. Compare DICOM PS 3.3 10.7 (Basic Pixel Spacing Calibration Macro). */ typedef enum { PixelSpacingInterpretation_SpacingInPatient, /// distances are mm within a patient PixelSpacingInterpretation_SpacingAtDetector, /// distances are mm at detector surface PixelSpacingInterpretation_SpacingUnknown /// NO spacing information is present, we use (1,1) as default } PixelSpacingInterpretation; /** \brief Return type of GetSeries, describes a logical group of files. Files grouped into a single 3D or 3D+t block are described by an instance of this class. Relevant descriptive properties can be used to provide the application user with meaningful choices. */ class ImageBlockDescriptor { public: /// List of files in this group StringContainer GetFilenames() const; /// A unique ID describing this bloc (enhanced Series Instance UID). std::string GetImageBlockUID() const; /// The Series Instance UID. std::string GetSeriesInstanceUID() const; /// Series Modality (CT, MR, etc.) std::string GetModality() const; /// SOP Class UID as readable string (Computed Tomography Image Storage, Secondary Capture Image Storage, etc.) std::string GetSOPClassUIDAsString() const; /// SOP Class UID as DICOM UID std::string GetSOPClassUID() const; /// Confidence of the reader that this block can be read successfully. ReaderImplementationLevel GetReaderImplementationLevel() const; /// Whether or not the block contains a gantry tilt which will be "corrected" during loading bool HasGantryTiltCorrected() const; /// Whether or not mitk::Image spacing relates to the patient bool PixelSpacingRelatesToPatient() const; /// Whether or not mitk::Image spacing relates to the detector surface bool PixelSpacingRelatesToDetector() const; /// Whether or not mitk::Image spacing is of unknown origin bool PixelSpacingIsUnknown() const; /// How the mitk::Image spacing can meaningfully be interpreted. PixelSpacingInterpretation GetPixelSpacingType() const; /// 3D+t or not bool HasMultipleTimePoints() const; /// Multi-frame image(s) or not bool IsMultiFrameImage() const; ImageBlockDescriptor(); ~ImageBlockDescriptor(); private: friend class DicomSeriesReader; ImageBlockDescriptor(const StringContainer &files); void AddFile(const std::string &file); void AddFiles(const StringContainer &files); void SetImageBlockUID(const std::string &uid); void SetSeriesInstanceUID(const std::string &uid); void SetModality(const std::string &modality); void SetNumberOfFrames(const std::string &); void SetSOPClassUID(const std::string &mediaStorageSOPClassUID); void SetHasGantryTiltCorrected(bool); void SetPixelSpacingInformation(const std::string &pixelSpacing, const std::string &imagerPixelSpacing); void SetHasMultipleTimePoints(bool); void GetDesiredMITKImagePixelSpacing(ScalarType &spacingX, ScalarType &spacingY) const; StringContainer m_Filenames; std::string m_ImageBlockUID; std::string m_SeriesInstanceUID; std::string m_Modality; std::string m_SOPClassUID; bool m_HasGantryTiltCorrected; std::string m_PixelSpacing; std::string m_ImagerPixelSpacing; bool m_HasMultipleTimePoints; bool m_IsMultiFrameImage; }; typedef std::map FileNamesGrouping; /** \brief Provide combination of preprocessor defines that was active during compilation. Since this class is a combination of several possible implementations, separated only by ifdef's, calling instances might want to know which flags were active at compile time. */ static std::string GetConfigurationString(); /** \brief Checks if a specific file contains DICOM data. */ static bool IsDicom(const std::string &filename); /** \brief see other GetSeries(). Find all series (and sub-series -- see details) in a particular directory. */ static FileNamesGrouping GetSeries(const std::string &dir, bool groupImagesWithGantryTilt, const StringContainer &restrictions = StringContainer()); /** \brief see other GetSeries(). \warning Untested, could or could not work. This differs only by having an additional restriction to a single known DICOM series. Internally, it uses the other GetSeries() method. */ static StringContainer GetSeries(const std::string &dir, const std::string &series_uid, bool groupImagesWithGantryTilt, const StringContainer &restrictions = StringContainer()); /** \brief PREFERRED version of this method - scan and sort DICOM files. Parse a list of files for images of DICOM series. For each series, an enumeration of the files contained in it is created. \return The resulting maps UID-like keys (based on Series Instance UID and slice properties) to sorted lists of file names. SeriesInstanceUID will be enhanced to be unique for each set of file names that is later loadable as a single mitk::Image. This implies that Image orientation, slice thickness, pixel spacing, rows, and columns must be the same for each file (i.e. the image slice contained in the file). If this separation logic requires that a SeriesInstanceUID must be made more specialized, it will follow the same logic as itk::GDCMSeriesFileNames to enhance the UID with more digits and dots. Optionally, more tags can be used to separate files into different logical series by setting the restrictions parameter. \warning Adding restrictions is not yet implemented! */ static FileNamesGrouping GetSeries(const StringContainer &files, bool sortTo3DPlust, bool groupImagesWithGantryTilt, const StringContainer &restrictions = StringContainer()); /** \brief See other GetSeries(). Use GetSeries(const StringContainer& files, bool sortTo3DPlust, const StringContainer &restrictions) instead. */ static FileNamesGrouping GetSeries(const StringContainer &files, bool groupImagesWithGantryTilt, const StringContainer &restrictions = StringContainer()); /** Loads a DICOM series composed by the file names enumerated in the file names container. If a callback method is supplied, it will be called after every progress update with a progress value in [0,1]. \param filenames The filenames to load. \param sort Whether files should be sorted spatially (true) or not (false - maybe useful if presorted) \param load4D Whether to load the files as 3D+t (if possible) + \param correctGantryTilt + \param callback + \param preLoadedImageBlock */ static DataNode::Pointer LoadDicomSeries(const StringContainer &filenames, bool sort = true, bool load4D = true, bool correctGantryTilt = true, UpdateCallBackMethod callback = nullptr, itk::SmartPointer preLoadedImageBlock = nullptr); /** \brief See LoadDicomSeries! Just a slightly different interface. - If \p preLoadedImageBlock is provided, the reader will only "fake" loading and create appropriate - mitk::Properties. + If \p preLoadedImageBlock is provided, the reader will only "fake" loading and create appropriate mitk::Properties. + + \param filenames + \param node + \param sort + \param load4D + \param correctGantryTilt + \param callback + \param preLoadedImageBlock */ static bool LoadDicomSeries(const StringContainer &filenames, DataNode &node, bool sort = true, bool load4D = true, bool correctGantryTilt = true, UpdateCallBackMethod callback = nullptr, itk::SmartPointer preLoadedImageBlock = nullptr); protected: /** \brief Return type of DicomSeriesReader::AnalyzeFileForITKImageSeriesReaderSpacingAssumption. Class contains the grouping result of method DicomSeriesReader::AnalyzeFileForITKImageSeriesReaderSpacingAssumption, which takes as input a number of images, which are all equally oriented and spatially sorted along their normal direction. The result contains of two blocks: a first one is the grouping result, all of those images can be loaded into one image block because they have an equal origin-to-origin distance without any gaps in-between. */ class SliceGroupingAnalysisResult { public: SliceGroupingAnalysisResult(); /** \brief Grouping result, all same origin-to-origin distance w/o gaps. */ StringContainer GetBlockFilenames(); /** \brief Remaining files, which could not be grouped. */ StringContainer GetUnsortedFilenames(); /** \brief Wheter or not the grouped result contain a gantry tilt. */ bool ContainsGantryTilt(); /** \brief Meant for internal use by AnalyzeFileForITKImageSeriesReaderSpacingAssumption only. */ void AddFileToSortedBlock(const std::string &filename); /** \brief Meant for internal use by AnalyzeFileForITKImageSeriesReaderSpacingAssumption only. */ void AddFileToUnsortedBlock(const std::string &filename); void AddFilesToUnsortedBlock(const StringContainer &filenames); /** \brief Meant for internal use by AnalyzeFileForITKImageSeriesReaderSpacingAssumption only. \todo Could make sense to enhance this with an instance of GantryTiltInformation to store the whole result! */ void FlagGantryTilt(); /** \brief Only meaningful for use by AnalyzeFileForITKImageSeriesReaderSpacingAssumption. */ void UndoPrematureGrouping(); protected: StringContainer m_GroupedFiles; StringContainer m_UnsortedFiles; bool m_GantryTilt; }; /** \brief Gantry tilt analysis result. Takes geometry information for two slices of a DICOM series and calculates whether these fit into an orthogonal block or not. If NOT, they can either be the result of an acquisition with gantry tilt OR completly broken by some shearing transformation. Most calculations are done in the constructor, results can then be read via the remaining methods. */ class GantryTiltInformation { public: // two types to avoid any rounding errors typedef itk::Point Point3Dd; typedef itk::Vector Vector3Dd; /** \brief Just so we can create empty instances for assigning results later. */ GantryTiltInformation(); /** \brief THE constructor, which does all the calculations. Determining the amount of tilt is done by checking the distances of origin1 from planes through origin2. Two planes are considered: - normal vector along normal of slices (right x up): gives the slice distance - normal vector along orientation vector "up": gives the shift parallel to the plane orientation The tilt angle can then be calculated from these distances \param origin1 origin of the first slice \param origin2 origin of the second slice \param right right/up describe the orientatation of borth slices \param up right/up describe the orientatation of borth slices \param numberOfSlicesApart how many slices are the given origins apart (1 for neighboring slices) */ GantryTiltInformation(const Point3D &origin1, const Point3D &origin2, const Vector3D &right, const Vector3D &up, unsigned int numberOfSlicesApart); /** \brief Whether the slices were sheared. True if any of the shifts along right or up vector are non-zero. */ bool IsSheared() const; /** \brief Whether the shearing is a gantry tilt or more complicated. Gantry tilt will only produce shifts in ONE orientation, not in both. Since the correction code currently only coveres one tilt direction AND we don't know of medical images with two tilt directions, the loading code wants to check if our assumptions are true. */ bool IsRegularGantryTilt() const; /** \brief The offset distance in Y direction for each slice in mm (describes the tilt result). */ double GetMatrixCoefficientForCorrectionInWorldCoordinates() const; /** \brief The z / inter-slice spacing. Needed to correct ImageSeriesReader's result. */ double GetRealZSpacing() const; /** \brief The shift between first and last slice in mm. Needed to resize an orthogonal image volume. */ double GetTiltCorrectedAdditionalSize() const; /** \brief Calculated tilt angle in degrees. */ double GetTiltAngleInDegrees() const; protected: /** \brief Projection of point p onto line through lineOrigin in direction of lineDirection. */ Point3D projectPointOnLine(Point3Dd p, Point3Dd lineOrigin, Vector3Dd lineDirection); double m_ShiftUp; double m_ShiftRight; double m_ShiftNormal; double m_ITKAssumedSliceSpacing; unsigned int m_NumberOfSlicesApart; }; /** \brief for internal sorting. */ typedef std::pair TwoStringContainers; /** \brief Maps DICOM tags to MITK properties. */ typedef std::map TagToPropertyMapType; /** \brief Ensure an equal z-spacing for a group of files. Takes as input a number of images, which are all equally oriented and spatially sorted along their normal direction. Internally used by GetSeries. Returns two lists: the first one contins slices of equal inter-slice spacing. The second list contains remaining files, which need to be run through AnalyzeFileForITKImageSeriesReaderSpacingAssumption again. Relevant code that is matched here is in itkImageSeriesReader.txx (ImageSeriesReader::GenerateOutputInformation(void)), lines 176 to 245 (as of ITK 3.20) */ static SliceGroupingAnalysisResult AnalyzeFileForITKImageSeriesReaderSpacingAssumption( const StringContainer &files, bool groupsOfSimilarImages, const gdcm::Scanner::MappingType &tagValueMappings_); /** \brief Safely convert const char* to std::string. */ static std::string ConstCharStarToString(const char *s); /** \brief Safely convert a string into pixel spacing x and y. */ static bool DICOMStringToSpacing(const std::string &s, ScalarType &spacingX, ScalarType &spacingY); /** \brief Convert DICOM string describing a point to Point3D. DICOM tags like ImagePositionPatient contain a position as float numbers separated by backslashes: \verbatim 42.7131\13.77\0.7 \endverbatim */ static Point3D DICOMStringToPoint3D(const std::string &s, bool &successful); /** \brief Convert DICOM string describing a point two Vector3D. DICOM tags like ImageOrientationPatient contain two vectors as float numbers separated by backslashes: \verbatim 42.7131\13.77\0.7\137.76\0.3 \endverbatim */ static void DICOMStringToOrientationVectors(const std::string &s, Vector3D &right, Vector3D &up, bool &successful); template static typename ImageType::Pointer // TODO this is NOT inplace! InPlaceFixUpTiltedGeometry(ImageType *input, const GantryTiltInformation &tiltInfo); /** \brief Sort a set of file names in an order that is meaningful for loading them into an mitk::Image. \warning This method assumes that input files are similar in basic properties such as slice thicknes, image orientation, pixel spacing, rows, columns. It should always be ok to put the result of a call to GetSeries(..) into this method. Sorting order is determined by 1. image position along its normal (distance from world origin) 2. acquisition time If P denotes a position and T denotes a time step, this method will order slices from three timesteps like this: \verbatim P1T1 P1T2 P1T3 P2T1 P2T2 P2T3 P3T1 P3T2 P3T3 \endverbatim */ static StringContainer SortSeriesSlices(const StringContainer &unsortedFilenames); public: /** \brief Checks if a specific file is a Philips3D ultrasound DICOM file. */ static bool IsPhilips3DDicom(const std::string &filename); static std::string ReaderImplementationLevelToString(const ReaderImplementationLevel &enumValue); static std::string PixelSpacingInterpretationToString(const PixelSpacingInterpretation &enumValue); protected: /** \brief Read a Philips3D ultrasound DICOM file and put into an mitk::Image. */ static bool ReadPhilips3DDicom(const std::string &filename, itk::SmartPointer output_image); /** \brief Construct a UID that takes into account sorting criteria from GetSeries(). */ static std::string CreateMoreUniqueSeriesIdentifier(gdcm::Scanner::TagToValue &tagValueMap); /** \brief Helper for CreateMoreUniqueSeriesIdentifier */ static std::string CreateSeriesIdentifierPart(gdcm::Scanner::TagToValue &tagValueMap, const gdcm::Tag &tag); /** \brief Helper for CreateMoreUniqueSeriesIdentifier */ static std::string IDifyTagValue(const std::string &value); typedef itk::GDCMImageIO DcmIoType; /** \brief Progress callback for DicomSeriesReader. */ class CallbackCommand : public itk::Command { public: CallbackCommand(UpdateCallBackMethod callback) : m_Callback(callback) {} void Execute(const itk::Object *caller, const itk::EventObject &) override { (*this->m_Callback)(static_cast(caller)->GetProgress()); } void Execute(itk::Object *caller, const itk::EventObject &) override { (*this->m_Callback)(static_cast(caller)->GetProgress()); } protected: UpdateCallBackMethod m_Callback; }; static void FixSpacingInformation(Image *image, const ImageBlockDescriptor &imageBlockDescriptor); /** \brief Scan for slice image information */ static void ScanForSliceInformation(const StringContainer &filenames, gdcm::Scanner &scanner); /** \brief Performs actual loading of a series and creates an image having the specified pixel type. */ static void LoadDicom(const StringContainer &filenames, DataNode &node, bool sort, bool check_4d, bool correctTilt, UpdateCallBackMethod callback, itk::SmartPointer preLoadedImageBlock); /** \brief Feed files into itk::ImageSeriesReader and retrieve a 3D MITK image. + \param correctTilt + \param tiltInfo + \param io \param command can be used for progress reporting + \param preLoadedImageBlock */ template static itk::SmartPointer LoadDICOMByITK(const StringContainer &, bool correctTilt, const GantryTiltInformation &tiltInfo, DcmIoType::Pointer &io, CallbackCommand *command, itk::SmartPointer preLoadedImageBlock); static itk::SmartPointer MultiplexLoadDICOMByITK(const StringContainer &, bool correctTilt, const GantryTiltInformation &tiltInfo, DcmIoType::Pointer &io, CallbackCommand *command, itk::SmartPointer preLoadedImageBlock); static itk::SmartPointer MultiplexLoadDICOMByITKScalar(const StringContainer &, bool correctTilt, const GantryTiltInformation &tiltInfo, DcmIoType::Pointer &io, CallbackCommand *command, itk::SmartPointer preLoadedImageBlock); static itk::SmartPointer MultiplexLoadDICOMByITKRGBPixel(const StringContainer &, bool correctTilt, const GantryTiltInformation &tiltInfo, DcmIoType::Pointer &io, CallbackCommand *command, itk::SmartPointer preLoadedImageBlock); template static itk::SmartPointer LoadDICOMByITK4D(std::list &imageBlocks, ImageBlockDescriptor imageBlockDescriptor, bool correctTilt, const GantryTiltInformation &tiltInfo, DcmIoType::Pointer &io, CallbackCommand *command, itk::SmartPointer preLoadedImageBlock); static itk::SmartPointer MultiplexLoadDICOMByITK4D(std::list &imageBlocks, ImageBlockDescriptor imageBlockDescriptor, bool correctTilt, const GantryTiltInformation &tiltInfo, DcmIoType::Pointer &io, CallbackCommand *command, itk::SmartPointer preLoadedImageBlock); static itk::SmartPointer MultiplexLoadDICOMByITK4DScalar(std::list &imageBlocks, ImageBlockDescriptor imageBlockDescriptor, bool correctTilt, const GantryTiltInformation &tiltInfo, DcmIoType::Pointer &io, CallbackCommand *command, itk::SmartPointer preLoadedImageBlock); static itk::SmartPointer MultiplexLoadDICOMByITK4DRGBPixel(std::list &imageBlocks, ImageBlockDescriptor imageBlockDescriptor, bool correctTilt, const GantryTiltInformation &tiltInfo, DcmIoType::Pointer &io, CallbackCommand *command, itk::SmartPointer preLoadedImageBlock); /** \brief Sort files into time step blocks of a 3D+t image. Called by LoadDicom. Expects to be fed a single list of filenames that have been sorted by GetSeries previously (one map entry). This method will check how many timestep can be filled with given files. Assumption is that the number of time steps is determined by how often the first position in space repeats. I.e. if the first three files in the input parameter all describe the same location in space, we'll construct three lists of files. and sort the remaining files into them. \todo We can probably remove this method if we somehow transfer 3D+t information from GetSeries to LoadDicomSeries. */ static std::list SortIntoBlocksFor3DplusT(const StringContainer &presortedFilenames, const gdcm::Scanner::MappingType &tagValueMappings_, bool sort, bool &canLoadAs4D); /** \brief Defines spatial sorting for sorting by GDCM 2. Sorts by image position along image normal (distance from world origin). In cases of conflict, acquisition time is used as a secondary sort criterium. */ static bool GdcmSortFunction(const gdcm::DataSet &ds1, const gdcm::DataSet &ds2); /** \brief Copy information about files and DICOM tags from ITK's MetaDataDictionary and from the list of input files to the PropertyList of mitk::Image. \todo Tag copy must follow; image level will cause some additional files parsing, probably. */ static void CopyMetaDataToImageProperties(StringContainer filenames, const gdcm::Scanner::MappingType &tagValueMappings_, DcmIoType *io, const ImageBlockDescriptor &blockInfo, Image *image); static void CopyMetaDataToImageProperties(std::list imageBlock, const gdcm::Scanner::MappingType &tagValueMappings_, DcmIoType *io, const ImageBlockDescriptor &blockInfo, Image *image); /** \brief Map between DICOM tags and MITK properties. Uses as a positive list for copying specified DICOM tags (from ITK's ImageIO) to MITK properties. ITK provides MetaDataDictionary entries of form "gggg|eeee" (g = group, e = element), e.g. "0028,0109" (Largest Pixel in Series), which we want to sort as dicom.series.largest_pixel_in_series". */ static const TagToPropertyMapType &GetDICOMTagsToMITKPropertyMap(); }; } #endif /* mitkDicomSeriesReader_h */ diff --git a/Modules/DICOMweb/include/mitkDICOMweb.h b/Modules/DICOMweb/include/mitkDICOMweb.h index ad34d51290..36643d4f6a 100644 --- a/Modules/DICOMweb/include/mitkDICOMweb.h +++ b/Modules/DICOMweb/include/mitkDICOMweb.h @@ -1,137 +1,137 @@ /*============================================================================ 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 mitkDICOMweb_h #define mitkDICOMweb_h #include #include "cpprest/asyncrt_utils.h" #include "cpprest/http_client.h" #include #include #include #include #include #include /** * @brief This class represents the implementation of the RESTful DICOMweb standard * (http://dicom.nema.org/medical/dicom/current/output/html/part18.html). It is used to communicate DICOM data over HTTP * to a DICOMweb enabled PACS server. * * @author Tobias Stein */ namespace mitk { class MITKDICOMWEB_EXPORT DICOMweb { public: typedef web::http::uri_builder MitkUriBuilder; typedef web::http::http_request MitkRequest; typedef web::http::http_response MitkResponse; typedef web::http::methods MitkRESTMethods; DICOMweb(); /** * @brief Creates a DICOMweb service instance which allow basic DICOM operations on the given base URI. * * @param baseURI the uri for the PACS server: for example a dcm4chee * http:///dcm4chee-arc/aets/DCM4CHEE/ */ DICOMweb(utility::string_t baseURI); /** * @brief Sends a STOW request with the file in the given path to the study given bei its UID. * * @param filePath the path to a valid DICOM file which should be send * @param studyUID the DICOM study uid - * @param the task to wait for + * @return the task to wait for */ pplx::task SendSTOW(utility::string_t filePath, utility::string_t studyUID); /** * @brief Sends a WADO request for an DICOM object instance matching the given uid parameters and stores it at the * given file path. * * @param filePath the path at which the retrieved DICOM object instance will be stored * @param studyUID the DICOM study uid * @param seriesUID the DICOM series uid * @param instanceUID the DICOM instance uid * @return the task to wait for, which unfolds no value when finished */ pplx::task SendWADO(utility::string_t filePath, utility::string_t studyUID, utility::string_t seriesUID, utility::string_t instanceUID); /** * @brief Sends a WADO request for an DICOM object series matching the given uid parameters and stores all the * containing instances at the given folder path. * * @param folderPath the path at which the retrieved DICOM object instances of the retrieved series will be stored * @param studyUID the DICOM study uid * @param seriesUID the DICOM series uid * @return the task to wait for, which unfolds the name of the first DICOM object file within the folder path */ pplx::task SendWADO(utility::string_t folderPath, utility::string_t studyUID, utility::string_t seriesUID); /** * @brief Sends a QIDO request containing the given parameters to filter the query. * * Example Map: * * mitk::RESTUtil::ParamMap seriesInstancesParams; * seriesInstancesParams.insert(mitk::RESTUtil::ParamMap::value_type(U("limit"), U("1"))); * * * @param map the map of parameters to filter the query * @return the task to wait for, which unfolds the result JSON response for the request when finished */ pplx::task SendQIDO(mitk::RESTUtil::ParamMap map); private: /** * @brief Creates a QIDO request URI with the given parameter map */ utility::string_t CreateQIDOUri(mitk::RESTUtil::ParamMap map); /** * @brief Creates a WADO request URI with the given parameter */ utility::string_t CreateWADOUri(utility::string_t studyUID, utility::string_t seriesUID, utility::string_t instanceUID); /** * @brief Creates a STOW request URI with the study uid */ utility::string_t CreateSTOWUri(utility::string_t studyUID); /** * @brief Initializes the rest manager for this service instance. Should be called in constructor to make sure the * public API can work properly. */ void InitializeRESTManager(); utility::string_t m_BaseURI; mitk::IRESTManager *m_RESTManager; }; } #endif // DICOMweb_h diff --git a/Modules/DataTypesExt/include/mitkApplyDiffImageOperation.h b/Modules/DataTypesExt/include/mitkApplyDiffImageOperation.h index 884dbf7e12..ee25cbea9b 100644 --- a/Modules/DataTypesExt/include/mitkApplyDiffImageOperation.h +++ b/Modules/DataTypesExt/include/mitkApplyDiffImageOperation.h @@ -1,84 +1,88 @@ /*============================================================================ 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 mitkApplyDiffImageIIncluded #define mitkApplyDiffImageIIncluded #include "MitkDataTypesExtExports.h" #include "mitkCompressedImageContainer.h" #include "mitkOperation.h" namespace mitk { /** @brief Operation, that holds information about some image difference This class stores undo information for DiffImageApplier. Instances of this class are created e.g. by OverwriteSliceImageFilter. This works only for images with 1 channel (gray scale images, no color images). ApplyDiffImageOperation of course refers to an image (a segmentation usually). The refered image is observed for itk::DeleteEvent, because there is no SmartPointer used to keep the image alive -- the purpose of this class is undo and the undo stack should not keep things alive forever. To save memory, zlib compression is used via CompressedImageContainer. @ingroup Undo @ingroup ToolManagerEtAl */ class MITKDATATYPESEXT_EXPORT ApplyDiffImageOperation : public Operation { protected: void OnImageDeleted(); Image *m_Image; unsigned int m_SliceIndex; unsigned int m_SliceDimension; unsigned int m_TimeStep; double m_Factor; bool m_ImageStillValid; unsigned long m_DeleteTag; CompressedImageContainer::Pointer zlibContainer; public: /** Pass only 2D images here. + \param operationType + \param image + \param diffImage + \param timeStep \param sliceIndex brief Which slice to extract (first one has index 0). \param sliceDimension Number of the dimension which is constant for all pixels of the desired slice (e.g. 0 for axial) */ ApplyDiffImageOperation(OperationType operationType, Image *image, Image *diffImage, unsigned int timeStep = 0, unsigned int sliceDimension = 2, unsigned int sliceIndex = 0); ~ApplyDiffImageOperation() override; // Unfortunately cannot use itkGet/SetMacros here, since Operation does not inherit itk::Object unsigned int GetSliceIndex() { return m_SliceIndex; } unsigned int GetSliceDimension() { return m_SliceDimension; } unsigned int GetTimeStep() { return m_TimeStep; } void SetFactor(double factor) { m_Factor = factor; } double GetFactor() { return m_Factor; } Image *GetImage() { return m_Image; } Image::Pointer GetDiffImage(); bool IsImageStillValid() { return m_ImageStillValid; } }; } // namespace mitk #endif diff --git a/Modules/DataTypesExt/include/mitkCellOperation.h b/Modules/DataTypesExt/include/mitkCellOperation.h index 24c08df4b5..87aa1a48c0 100644 --- a/Modules/DataTypesExt/include/mitkCellOperation.h +++ b/Modules/DataTypesExt/include/mitkCellOperation.h @@ -1,51 +1,50 @@ /*============================================================================ 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 MITKCELLOPERATION_H_INCLUDED #define MITKCELLOPERATION_H_INCLUDED #include "MitkDataTypesExtExports.h" #include "mitkCommon.h" #include "mitkOperation.h" #include "mitkVector.h" namespace mitk { //##Documentation //## @brief Operation, that holds everything necessary for an operation on a cell. //## //## @ingroup Undo class MITKDATATYPESEXT_EXPORT CellOperation : public Operation { public: mitkClassMacro(CellOperation, Operation); //##Documentation //##@brief constructor //## - //## @param - //## operationType is the type of that operation (see mitkOperation.h; e.g. move or add; Information for - //StateMachine::ExecuteOperation()); - //## cellId: Id of the cell and a vector if needed + //## @param operationType is the type of that operation (see mitkOperation.h; e.g. move or add; Information for StateMachine::ExecuteOperation()); + //## @param cellId Id of the cell and a vector if needed + //## @param vector CellOperation(OperationType operationType, int cellId, Vector3D vector); CellOperation(OperationType operationType, int cellId); ~CellOperation() override{}; int GetCellId() { return m_CellId; }; Vector3D GetVector() { return m_Vector; }; protected: int m_CellId; Vector3D m_Vector; }; } // namespace mitk #endif /* MITKCELLOPERATION_H_INCLUDED*/ diff --git a/Modules/ImageStatistics/itkMultiGaussianImageSource.h b/Modules/ImageStatistics/itkMultiGaussianImageSource.h index 42e428a2ab..794809c8fc 100644 --- a/Modules/ImageStatistics/itkMultiGaussianImageSource.h +++ b/Modules/ImageStatistics/itkMultiGaussianImageSource.h @@ -1,374 +1,374 @@ /*========================================================================= * * Copyright Insight Software Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ /*========================================================================= * * Portions of this file are subject to the VTK Toolkit Version 3 copyright. * * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen * * For complete copyright, license and disclaimer of warranty information * please refer to the NOTICE file at the top of the ITK source tree. * *=========================================================================*/ #ifndef __itkMultiGaussianImageSource_h #define __itkMultiGaussianImageSource_h #include "itkImageSource.h" #include "itkNumericTraits.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkImageFileWriter.h" #include namespace itk { /** \class MultiGaussianImageSource \brief Generate an 3-dimensional multigaussian image. This class defines an 3-dimensional Image, in which the value at one voxel equals the value of a multigaussian function evaluated at the voxel's coordinates. The multigaussian function is built as a sum of N gaussian function and is defined by the following parameters (\ref Generation-of-a-multigauss-image): 1. CenterX, CenterY, CenterZ - vectors of the size of N determining the expectancy value at the x-, y- and the z-axis. That means: The i-th gaussian bell curve takes its maximal value at the voxel with index [CenterX(i); CenterY(i); Centerz(i)]. 2. SigmaX, SigmaY, SigmaZ - vectors of the size of N determining the deviation at the x-, y- and the z-axis. That means: The width of the i-th gaussian bell curve is determined by the deviation in the x-axis, which is SigmaX(i), in the y-axis is SigmaY(i) and in the z-axis is SigmaZ(i). 3. Altitude - vector of the size of N determining the altitude: the i-th gaussian bell curve has a height of Altitude(i). This class allows by the method CalculateMidpointAndMeanValue() to find a sphere with a specified radius that has a maximal mean value over all sphere with that radius with midpoint inside or on the boundary of the image. Furthermore it can calculate the maximal und minimal pixel intensities and whose indices in the founded sphere. To serve as a test tool for ImageStatisticsCalculator, esp. the "hotspot search" feature of this class, MultiGaussianImageSource is also able to calculate the position of a sphere that maximizes the mean value of the voxels within the sphere (\ref Algorithm-for-calculating-statistic-in-a-sphere). \section Generation-of-a-multigauss-image Generation of a multigauss image -A multigauss function consists of the sum of \f$ N \f$ gauss function. The \f$ i \f$-th \linebreak (\f$0 \leq i \leq N \f$) gaussian is described with the following seven parameters (see above): +A multigauss function consists of the sum of \f$ N \f$ gauss function. The \f$ i \f$-th \n (\f$0 \leq i \leq N \f$) gaussian is described with the following seven parameters (see above): - \f$ x_0^{(i)} \f$ is the expectancy value in the \f$ x \f$-Axis - \f$ y_0^{(i)} \f$ is the expectancy value in the \f$ y \f$-Axis - \f$ z_0^{(i)} \f$ is the expectancy value in the \f$ z \f$-Axis - \f$ \sigma_x^{(i)} \f$ is the deviation in the \f$ x \f$-Axis - \f$ \sigma_y^{(i)} \f$ is the deviation in the \f$ y \f$-Axis - \f$ \sigma_z^{(i)} \f$ is the deviation in the \f$ z \f$-Axis - \f$ a^{(i)} \f$ is the altitude of the gaussian. A gauss function has the following form: \f{eqnarray}{ \nonumber f^{(i)}(x,y,z) = a^{(i)} exp \left[ - \left( \frac{(x - x_0^{(i)})^2}{2 (\sigma_x^{(i)})^2} + \frac{(y - y_0^{(i)})^2}{2 (\sigma_y^{(i)})^2} + \frac{(z - z_0^{(i)})^2}{2 (\sigma_z^{(i)})^2} \right) \right]. \f} A multigauss function has then the form: \f{align*}{ f_N(x,y,z) =& \sum_{i=0}^{N}f^{(i)}(x,y,z)\\ =&\sum_{0}^{N} a^{(i)} exp \left[ - \left( \frac{(x - x_0^{(i)})^2}{2 (\sigma_x^{(i)})^2} + \frac{(y - y_0^{(i)})^2}{2 (\sigma_y^{(i)})^2} + \frac{(z - z_0^{(i)})^2}{2 (\sigma_z^{(i)})^2} \right) \right]. \f} The multigauss function \f$f_N\f$ will be evaluated at each voxel coordinate to become the voxel intensity. \section Algorithm-for-calculating-statistic-in-a-sphere Algorithm for calculating statistic in a sphere This section explains how we can find a sphere region which has a maximal mean value over all sphere regions with a fixed radius. Furthermore we want to calculate the maximal and minimal value in the wanted sphere. To calculate the mean value in a sphere we integrate the gaussians over the whole sphere. The antiderivative is unknown as an explicit function, but we have a value table for the distribution function of the normal distribution \f$ \Phi(x) \f$ for \f$ x \f$ between \f$ -3.99 \f$ and \f$ 3.99 \f$ with step size \f$ 0.01 \f$. The only problem is that we cannot integrate over a spherical region, because we have an 3-dim integral and therefore are the integral limits dependent from each other and we cannot evaluate \f$ \Phi \f$. So we approximate the sphere with cuboids inside the sphere and prisms on the boundary of the sphere. We calculate these cuboids with the octree recursive method: We start by subdividing the wrapping box of the sphere in eight cuboids. Further we subdivide each cuboid in eight cuboids and check for each of them, whether it is inside or outside the sphere or whether it intersects the sphere surface. We save those of them, which are inside the sphere and continue to subdivide the cuboids that intersect the sphere until the recursion breaks. In the last step we take the half of the cuboids on the boundary and this are the prisms. Now we can calculate and sum the integrals over the cuboids and divide through the volume of the body to obtain the mean value. For each cuboid \f$ Q = [a_1, b_1]\times[a_2, b_2]\times[a_3, b_3] \f$ we apply Fubini's theorem for integrable functions and become for the integral the following: \f{align*}{ m_k =& \sum_{i=0}^{N} \int_{Q} f^{(i)}(x,y,z)dx\\ =&\sum_{i=0}^{N} a^{(i)} \int_{Q} exp \left[ - \left( \frac{(x - x_0^{(i)})^2}{2 (\sigma_x^{(i)})^2} + \frac{(y - y_0^{(i)})^2}{2 (\sigma_y^{(i)})^2} + \frac{(z - z_0^{(i)})^2}{2 (\sigma_z^{(i)})^2} \right) \right] dx \\ =& \sum_{i=0}^{N} a^{(i)} \int_{a_1}^{b_1} exp \left[ - \frac{(x - x_0^{(i)})^2}{2 (\sigma_x^{(i)})^2} \right] dx \int_{a_2}^{b_2}exp \left[ -\frac{(y - y_0^{(i)})^2}{2 (\sigma_y^{(i)})^2} \right]dx \int_{a_3}^{b_3}exp \left[ -\frac{(z - z_0^{(i)})^2}{2 (\sigma_z^{(i)})^2} \right]dx. \f} So we calculate three one dimensional integrals: \f{align*}{ \int_{a}^{b} & exp \left[ - \frac{(x - x_0^{(i)})^2}{2 (\sigma_x^{(i)})^2} \right] dx \\ =&\int_{-\infty}^{b} exp \left[ - \frac{(x - x_0^{(i)})^2}{2 (\sigma_x^{(i)})^2} \right] dx - \int_{-\infty}^{a} exp \left[ - \frac{(x - x_0^{(i)})^2}{2 (\sigma_x^{(i)})^2} \right] dx \\ =& \sigma_x^{(i)} \left[\int_{-\infty}^{(a - x_0^{(i)})/ \sigma_x^{(i)}} e^{-\frac{t^2}{2}} dt - \int_{-\infty}^{(b - x_0^{(i)})/ \sigma_x^{(i)}} e^{-\frac{t^2}{2}}dt \right] \\ =&\sigma_x^{(i)} \sqrt{(\pi)} \left[ \Phi \left( \frac{(a - x_0^{(i)})^2}{\sigma_x^{(i)}} \right) - \Phi \left ( \frac{(b - x_0^{(i)})^2}{\sigma_x^{(i)}} \right) \right]. \f} and become for the integral over \f$ Q \f$: \f{align*}{ m_k =& \sum_{i=0}^{N} \sigma_x^{(i)} \sigma_y^{(i)} \sigma_z^{(i)} \pi^{1.5} \left[ \Phi \left( \frac{(a_1 - x_0^{(i)})^2}{\sigma_x^{(i)}} \right) - \Phi \left ( \frac{(b_1 - x_0^{(i)})^2}{\sigma_x^{(i)}} \right) \right]\times \\ &\left[ \Phi \left( \frac{(a_2 - y_0^{(i)})^2}{\sigma_y^{(i)}} \right) - \Phi \left ( \frac{(b_2 - y_0^{(i)})^2}{\sigma_y^{(i)}} \right) \right]\times \left[ \Phi \left( \frac{(a_3 - z_0^{(i)})^2}{\sigma_z^{(i)}} \right) - \Phi \left ( \frac{(b_3 - z_0^{(i)})^2}{\sigma_z^{(i)}} \right) \right]. \f} For the integral over the prism we take the half of the integral over the corresponding cuboid. Altogether we find the mean value in the sphere as: \f{align*}{ \left( \sum_{Q_k \text{ Cuboid}} m_k + \sum_{P_l \text{ Prism}} 0.5 m_l \right )/Volume(B), \f} where Volume(B) is the volume of the body that approximate the sphere. Now we know how to calculate the mean value in a sphere for given midpoint and radius. So we assume each voxel in the given image to be the sphere midpoint and we calculate the mean value as described above. If the new mean value is greater than the "maximum-until-now", we take the new value to be the "maximum-until-now". Then we go to the next voxel and make the same calculation and so on. At the same time we save the coordinates of the midpoint voxel. After we found the midpoint and the maximal mean value, we can calculate the maximum and the minimum in the sphere: we just traverse all the voxels in the region and take the maximum and minimum value and the respective coordinates. \section Input-and-output Input and output An example for an input in the command-line is: \verbatim mitkMultiGaussianTest C:/temp/outputFile C:/temp/inputFile.xml \endverbatim Here is outputFile the name of the gaussian image with extension .nrrd and at the same time the name of the output file with extension .xml, which is the same as the inputFile, only added the calculated mean value, max and min and the corresponding indexes in the statistic tag. Here we see an example for the input and output .xml file: \verbatim INPUT: \endverbatim \verbatim OUTPUT: \endverbatim \subsection Parameter-for-the-input Parameter for the input In the tag \a testimage we describe the image that we generate. Image rows/columns/slices gives the number of rows/columns/slices of the image; \a numberOfGaussians is the number of gauss functions (\f$ N \f$); spacing defines the extend of one voxel for each direction. The parameter \a entireHotSpotInImage determines whether the whole sphere is in the image included (\f$ = 1 \f$) or only the midpoint of the sphere is inside the image. NOTE: When the \a entireHotSpotInImage \f$ = 0 \f$ it is possible that we find the midpoint of the sphere on the border of the image. In this case we cut the approximation of the sphere, so that we become a body, which is completely inside the image, but not a "sphere" anymore. To that effect is the volume of the body decreased and that could lead to unexpected results. In the subtag \a gaussian we describe each gauss function as mentioned in the second section. In the tag \a segmentation we define the radius of the wanted sphere in mm (\a hotspotRadiusInMM ). We can also set the number of labels (\a numberOfLabels ) to be an positive number and this determines the number of regions of interest (ROI). In each ROI we find the sphere with the wanted properties and midpoint inside the ROI, but not necessarily the whole sphere. In the subtag \a roi we set label number and the index coordinates for the borders of the roi. */ template< typename TOutputImage > class ITK_EXPORT MultiGaussianImageSource:public ImageSource< TOutputImage > { public: /** Standard class typedefs. */ typedef MultiGaussianImageSource Self; typedef ImageSource< TOutputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Typedef for the output image PixelType. */ typedef typename TOutputImage::PixelType OutputImagePixelType; /** Typedef to describe the output image region type. */ typedef typename TOutputImage::RegionType OutputImageRegionType; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Basic types from the OutputImageType */ typedef typename TOutputImage::SizeType SizeType; typedef typename TOutputImage::IndexType IndexType; typedef typename TOutputImage::SpacingType SpacingType; typedef typename TOutputImage::PointType PointType; typedef typename SizeType::SizeValueType SizeValueType; typedef SizeValueType SizeValueArrayType[TOutputImage::ImageDimension]; typedef typename TOutputImage::SpacingValueType SpacingValueType; typedef SpacingValueType SpacingValueArrayType[TOutputImage::ImageDimension]; typedef typename TOutputImage::PointValueType PointValueType; typedef PointValueType PointValueArrayType[TOutputImage::ImageDimension]; typedef typename itk::ImageRegion<3> ::SizeValueType SizeRegionType; /** Typedef to describe the sphere radius type. */ typedef double RadiusType; /** Typedef to describe the standard vector type. */ typedef std::vector VectorType; /** Typedef to describe the itk vector type. */ typedef Vector ItkVectorType; /** Typedef to describe the ImageRegionIteratorWithIndex type. */ typedef ImageRegionIteratorWithIndex IteratorType; /** Typedef to describe the Poiner type at the output image. */ typedef typename TOutputImage::Pointer ImageType; typedef MapContainer MapContainerPoints; typedef MapContainer MapContainerRadius; /** Set/Get size of the output image. */ itkSetMacro(Size, SizeType); virtual void SetSize(SizeValueArrayType sizeArray); virtual const SizeValueType * GetSize() const; /** Set/Get spacing of the output image. */ itkSetMacro(Spacing, SpacingType); virtual void SetSpacing(SpacingValueArrayType spacingArray); virtual const SpacingValueType * GetSpacing() const; /** Set/Get origin of the output image. This programm works proper only with origin [0.0, 0.0, 0.0] */ itkSetMacro(Origin, PointType); virtual void SetOrigin(PointValueArrayType originArray); virtual const PointValueType * GetOrigin() const; /** Get the number of gaussian functions in the output image. */ virtual unsigned int GetNumberOfGaussians() const; /** Set the number of gaussian function. */ virtual void SetNumberOfGausssians( unsigned int ); /** Set/Get the radius of the sphere. */ virtual RadiusType GetRadius() const; virtual void SetRadius( RadiusType radius ); /** Get the maximal mean value in a sphere over all possible spheres with midpoint in the image. */ virtual const OutputImagePixelType GetMaxMeanValue() const; /** Get the index of the midpoint of a sphere with the maximal mean value.*/ virtual const IndexType GetSphereMidpoint() const; /** Calculates the value of the multigaussian function at a Point given by its coordinates [x, y, z]. */ virtual double MultiGaussianFunctionValueAtPoint(double , double, double); /** Adds a multigaussian defined by the parameter: CenterX, CenterY, CenterZ, SigmaX, SigmaY, SigmaZ, Altitude. All parameters should have the same size, which determinates the number of the gaussian added. */ virtual void AddGaussian( VectorType centerX, VectorType centerY, VectorType centerZ, VectorType sigmaX, VectorType sigmaY, VectorType sigmaZ, VectorType altitude); /** Calculates and set the index of the midpoint of the sphere with the maximal mean value as well as the mean value. */ virtual void CalculateTheMidpointAndTheMeanValueWithOctree(); /** Calculates and set the index an the value of maximulm and minimum in the wanted sphere. */ virtual void CalculateMaxAndMinInSphere(); /** Get the index in the sphere with maximal value. */ virtual const IndexType GetMaxValueIndexInSphere() const; /** Get the maximal value in the sphere. */ virtual const OutputImagePixelType GetMaxValueInSphere() const; /** Get the index in the sphere with minimal value. */ virtual const IndexType GetMinValueIndexInSphere() const; /** Get the minimal value in the sphere. */ virtual const OutputImagePixelType GetMinValueInSphere() const; /** Set the region of interest. */ virtual void SetRegionOfInterest(ItkVectorType, ItkVectorType); /** Write a .mps file to visualise the point in the sphere. */ virtual void WriteXMLToTestTheCuboidInsideTheSphere(); /**This recursive method realise the octree method. It subdivide a cuboid in eight cuboids, when this cuboid crosses the boundary of sphere. If the cuboid is inside the sphere, it calculates the integral. */ virtual void CalculateEdgesInSphere( PointType globalCoordinateMidpointCuboid, PointType globalCoordinateMidpointSphere, double cuboidRadius, int level); /**Calculate and return value of the integral of the gaussian in a cuboid region with the dimension 3: in the x-axis between xMin and xMax and in the y-axis between yMin and yMax and in the z-axis also between zMin and zMax. */ virtual double MultiGaussianFunctionValueAtCuboid(double xMin, double xMax, double yMin, double yMax, double zMin, double zMax); /** Inseret the midpoints of cuboid in a vector m_Midpoints, so that we can visualise it. */ virtual void InsertPoints( PointType globalCoordinateMidpointCuboid, double cuboidRadius); /** Start the octree recursion in eigth directions for the sphere with midpoint globalCoordinateMidpointSphere. */ virtual void GenerateCuboidSegmentationInSphere( PointType globalCoordinateMidpointSphere ); /** Get the the values of the cumulative distribution function of the normal distribution. */ virtual double FunctionPhi(double value); /** Check if a cuboid with midpoint globalCoordinateMidpointCuboid and side length sideLength intersect the sphere with midpoint globalCoordinateMidpointSphere boundary. */ virtual unsigned int IntersectTheSphere( PointType globalCoordinateMidpointCuboid, PointType globalCoordinateMidpointSphere, double sideLength); /** Set the tabel values of the distribution function of the normal distribution. */ void SetNormalDistributionValues(); /** Set the minimum possible pixel value. By default, it is * NumericTraits::min(). */ itkSetClampMacro( Min, OutputImagePixelType, NumericTraits< OutputImagePixelType >::NonpositiveMin(), NumericTraits< OutputImagePixelType >::max() ); /** Check if a index is inside the image*/ bool IsInImage(IndexType index); /** Get the minimum possible pixel value. */ itkGetConstMacro(Min, OutputImagePixelType); /** Set the maximum possible pixel value. By default, it is * NumericTraits::max(). */ itkSetClampMacro( Max, OutputImagePixelType, NumericTraits< OutputImagePixelType >::NonpositiveMin(), NumericTraits< OutputImagePixelType >::max() ); /** Get the maximum possible pixel value. */ itkGetConstMacro(Max, OutputImagePixelType); protected: MultiGaussianImageSource(); ~MultiGaussianImageSource() override; void PrintSelf(std::ostream & os, Indent indent) const override; void GenerateData() override; void GenerateOutputInformation() override; private: MultiGaussianImageSource(const MultiGaussianImageSource &); //purposely not implemented void operator=(const MultiGaussianImageSource &); //purposely not implemented SizeType m_Size; //size of the output image SpacingType m_Spacing; //spacing PointType m_Origin; //origin OutputImagePixelType m_MaxValueInSphere; //maximal value in the wanted sphere IndexType m_MaxValueIndexInSphere; //index of the maximal value in the wanted sphere OutputImagePixelType m_MinValueInSphere; //minimal value in the wanted sphere IndexType m_MinValueIndexInSphere; //index of the minimal value in the wanted sphere unsigned int m_NumberOfGaussians; //number of Gaussians RadiusType m_Radius; //radius of the sphere unsigned int m_RadiusStepNumber; //number of steps to traverse the sphere radius OutputImagePixelType m_MeanValue; //mean value in the wanted sphere OutputImagePixelType m_ValueAtMidpoint; //value at the midpoint of the wanted sphere IndexType m_SphereMidpoint; //midpoint of the wanted sphere VectorType m_SigmaX; //deviation in the x-axis VectorType m_SigmaY; //deviation in the y-axis VectorType m_SigmaZ; //deviation in the z-axis VectorType m_CenterX; //x-coordinate of the mean value of Gaussians VectorType m_CenterY; //y-coordinate of the mean value of Gaussians VectorType m_CenterZ; //z-coordinate of the mean value of Gaussians VectorType m_Altitude; //amplitude ItkVectorType m_RegionOfInterestMax; //maximal values for the coordinates in the region of interest ItkVectorType m_RegionOfInterestMin; //minimal values for the coordinates in the region of interest typename TOutputImage::PixelType m_Min; //minimum possible value typename TOutputImage::PixelType m_Max; //maximum possible value PointType m_GlobalCoordinate; //physical coordiante of the sphere midpoint bool m_WriteMPS; //1 = write a MPS File to visualise the cuboid midpoints of one approximation of the sphere MapContainerPoints m_Midpoints; //the midpoints of the cuboids MapContainerRadius m_RadiusCuboid; //the radius ( = 0.5 * side length) of the cuboids (in the same order as the midpoints in m_Midpoints) double m_Volume; //the volume of the body, that approximize the sphere double m_NormalDistValues [410];//normal distribution values double m_meanValueTemp; //= m_Volume * meanValue in each sphere // The following variables are deprecated, and provided here just for // backward compatibility. It use is discouraged. mutable PointValueArrayType m_OriginArray; mutable SpacingValueArrayType m_SpacingArray; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkMultiGaussianImageSource.hxx" #endif #endif diff --git a/Modules/ImageStatistics/mitkImageStatisticsContainerManager.h b/Modules/ImageStatistics/mitkImageStatisticsContainerManager.h index cab786019e..88de6ebd04 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsContainerManager.h +++ b/Modules/ImageStatistics/mitkImageStatisticsContainerManager.h @@ -1,60 +1,63 @@ /*============================================================================ 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 QmitkImageStatisticsContainerManager_H__INCLUDED #define QmitkImageStatisticsContainerManager_H__INCLUDED #include "MitkImageStatisticsExports.h" #include #include #include #include #include #include namespace mitk { static const std::string STATS_HISTOGRAM_BIN_PROPERTY_NAME = "MITK.statistic.histogram_bins"; static const std::string STATS_IGNORE_ZERO_VOXEL_PROPERTY_NAME = "MITK.statistic.ignore_zero_voxel"; static const std::string STATS_GENERATION_STATUS_PROPERTY_NAME = "MITK.statistic.generation.status"; static const std::string STATS_GENERATION_STATUS_VALUE_WORK_IN_PROGRESS = "workInProgress"; static const std::string STATS_GENERATION_STATUS_VALUE_PENDING = "pending"; static const std::string STATS_GENERATION_STATUS_VALUE_BASE_DATA_FAILED = "failed"; /** \brief Returns the StatisticsContainer that was computed on given input (image/mask/planar figure) and is added as DataNode in a DataStorage */ class MITKIMAGESTATISTICS_EXPORT ImageStatisticsContainerManager { public: /**Documentation @brief Returns the StatisticsContainer for the given image and mask from the storage- @return a valid StatisticsContainer or nullptr if no StatisticsContainer is found. @details if more than one StatisticsContainer is found, only the newest (ModifiedTime) is returned @pre Datastorage must point to a valid instance. @pre image must Point to a valid instance. + @param dataStorage + @param image + @param mask @param onlyIfUpToDate Indicates if results should only be returned if the are up to date, thus not older then image and ROI. @param noWIP If noWIP is true, the function only returns valid final result and not just its placeholder (WIP). If noWIP equals false it might also return a WIP, thus the valid result is currently processed/ordered but might not be ready yet. @param ignoreZeroVoxel indicates the wanted statistics are calculated with or w/o zero voxels. @param histogramNBins Number of bins the statistics should have that are searched for. */ static mitk::ImageStatisticsContainer::Pointer GetImageStatistics(const mitk::DataStorage* dataStorage, const mitk::BaseData* image, const mitk::BaseData* mask=nullptr, bool ignoreZeroVoxel = false, unsigned int histogramNBins = 100, bool onlyIfUpToDate = true, bool noWIP = true); static mitk::DataNode::Pointer GetImageStatisticsNode(const mitk::DataStorage* dataStorage, const mitk::BaseData* image, const mitk::BaseData* mask = nullptr, bool ignoreZeroVoxel = false, unsigned int histogramNBins = 100, bool onlyIfUpToDate = true, bool noWIP = true); /** Returns the predicate that can be used to search for statistic containers of the given image (and mask) in the passed data storage.*/ static mitk::NodePredicateBase::ConstPointer GetStatisticsPredicateForSources(const mitk::BaseData* image, const mitk::BaseData* mask = nullptr); }; } #endif diff --git a/Modules/ImageStatistics/mitkIntensityProfile.h b/Modules/ImageStatistics/mitkIntensityProfile.h index 4060012726..1ecab74dfc 100644 --- a/Modules/ImageStatistics/mitkIntensityProfile.h +++ b/Modules/ImageStatistics/mitkIntensityProfile.h @@ -1,135 +1,137 @@ /*============================================================================ 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 mitkIntensityProfile_h #define mitkIntensityProfile_h #include #include #include #include #include namespace mitk { typedef itk::Statistics::ListSample::MeasurementVectorType> IntensityProfile; /** \brief Compute intensity profile of an image for each pixel along the first PolyLine of a given planar figure. * * \param[in] image A two or three-dimensional image which consists of single component pixels. * \param[in] planarFigure A planar figure from which the first PolyLine is used to evaluate the intensity profile. * * \return The computed intensity profile. */ MITKIMAGESTATISTICS_EXPORT IntensityProfile::Pointer ComputeIntensityProfile(Image::Pointer image, PlanarFigure::Pointer planarFigure); namespace InterpolateImageFunction { enum Enum { NearestNeighbor, Linear, WindowedSinc_Blackman_3, WindowedSinc_Blackman_4, WindowedSinc_Blackman_5, WindowedSinc_Cosine_3, WindowedSinc_Cosine_4, WindowedSinc_Cosine_5, WindowedSinc_Hamming_3, WindowedSinc_Hamming_4, WindowedSinc_Hamming_5, WindowedSinc_Lanczos_3, WindowedSinc_Lanczos_4, WindowedSinc_Lanczos_5, WindowedSinc_Welch_3, WindowedSinc_Welch_4, WindowedSinc_Welch_5 }; } /** \brief Compute intensity profile of an image for each sample along a planar line. * * \param[in] image A three-dimensional image which consists of single component pixels. * \param[in] planarLine A planar line along which the intensity profile will be evaluated. * \param[in] numSamples Number of samples along the planar line (must be at least 2). * \param[in] interpolator Image interpolation function which is used to read each sample. * \throw if image is 4D * * \return The computed intensity profile. */ MITKIMAGESTATISTICS_EXPORT IntensityProfile::Pointer ComputeIntensityProfile(Image::Pointer image, PlanarLine::Pointer planarLine, unsigned int numSamples, InterpolateImageFunction::Enum interpolator = InterpolateImageFunction::NearestNeighbor); /** \brief Compute intensity profile of an image for each sample between two points. * * \param[in] image A three-dimensional image which consists of single component pixels. * \param[in] startPoint A point at which the first sample is to be read. * \param[in] endPoint A point at which the last sample is to be read. * \param[in] numSamples Number of samples between startPoint and endPoint (must be at least 2). * \param[in] interpolator Image interpolation function which is used to read each sample. * \throw if image is 4D * * \return The computed intensity profile. */ MITKIMAGESTATISTICS_EXPORT IntensityProfile::Pointer ComputeIntensityProfile(Image::Pointer image, const Point3D& startPoint, const Point3D& endPoint, unsigned int numSamples, InterpolateImageFunction::Enum interpolator = InterpolateImageFunction::NearestNeighbor); /** \brief Compute global maximum of an intensity profile. * * \param[in] intensityProfile An intensity profile. + * \param[out] max The global maximum. * * \return Index of the global maximum. */ MITKIMAGESTATISTICS_EXPORT IntensityProfile::InstanceIdentifier ComputeGlobalMaximum(IntensityProfile::ConstPointer intensityProfile, IntensityProfile::MeasurementType &max); /** \brief Compute global minimum of an intensity profile. * * \param[in] intensityProfile An intensity profile. + * \param[out] min The global minimum. * * \return Index of the global minimum. */ MITKIMAGESTATISTICS_EXPORT IntensityProfile::InstanceIdentifier ComputeGlobalMinimum(IntensityProfile::ConstPointer intensityProfile, IntensityProfile::MeasurementType &min); /** \brief Compute statistics of an intensity profile. * * \param[in] intensityProfile An intensity profile. * * \param[in] stats An ImageStatisticsCalculator::Statistics object to hold the calculated statistics. * */ MITKIMAGESTATISTICS_EXPORT void ComputeIntensityProfileStatistics(IntensityProfile::ConstPointer intensityProfile, ImageStatisticsContainer::ImageStatisticsObject& stats); /** \brief Compute center of maximum area under the curve of an intensity profile. * * \param[in] intensityProfile An intensity profile. * \param[in] radius Radius of the area (width of area equals 1 + 2 * radius). * * \return Index of the maximum area center. */ MITKIMAGESTATISTICS_EXPORT IntensityProfile::InstanceIdentifier ComputeCenterOfMaximumArea(IntensityProfile::ConstPointer intensityProfile, IntensityProfile::InstanceIdentifier radius); /** \brief Convert an intensity profile to a standard library vector. * * \param[in] intensityProfile An intensity profile. * * \return Standard library vector which contains the input intensity profile measurements. */ MITKIMAGESTATISTICS_EXPORT std::vector CreateVectorFromIntensityProfile(IntensityProfile::ConstPointer intensityProfile); /** \brief Convert a standard library vector to an intensity profile. * * \param[in] vector An standard library vector which contains intensity profile measurements. * * \return An intensity profile. */ MITKIMAGESTATISTICS_EXPORT IntensityProfile::Pointer CreateIntensityProfileFromVector(const std::vector& vector); } #endif diff --git a/Modules/MapperExt/include/mitkEnhancedPointSetVtkMapper3D.h b/Modules/MapperExt/include/mitkEnhancedPointSetVtkMapper3D.h index 20ac8bd42b..dab5d786d0 100644 --- a/Modules/MapperExt/include/mitkEnhancedPointSetVtkMapper3D.h +++ b/Modules/MapperExt/include/mitkEnhancedPointSetVtkMapper3D.h @@ -1,119 +1,119 @@ /*============================================================================ 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 MITKEnhancedPointSetVtkMapper3D_H_HEADER_INCLUDED_C1907273 #define MITKEnhancedPointSetVtkMapper3D_H_HEADER_INCLUDED_C1907273 #include "MitkMapperExtExports.h" #include "mitkBaseRenderer.h" #include "mitkCommon.h" #include "mitkPointSet.h" #include "mitkVector.h" #include "mitkVtkMapper.h" class vtkActor; class vtkAssembly; class vtkSphereSource; class vtkCubeSource; class vtkConeSource; class vtkCylinderSource; class vtkTubeFilter; class vtkProp; namespace mitk { /** * \brief Alternative Vtk-based 3D mapper for mitk::PointSet * * This class renders mitk::PointSet objects in 3D views. It resembles the * standard mitk::PointSetVtkMapper3D, but is designed to enable single * points to be rendered with individual appearances. * * Instead of assembling one vtkPolyData object containing all points, * a list of VTK source objects (spheres, cubes, cones, ...) is maintained. * Therefore, the application can change the appearance and/or type of a * specific point at runtime, without having to rebuild the * * You should use this class instead of the standard mapper if you * * - change the PointSet very often (by adding or removing points) * - need different representations for points (+++) * - want to change the point representation frequently (+++) * * Note: the class is still in experimental stage, and the points above * marked with (+++) are not yet working correctly. Also, drawing lines * between points (contour mode) is not yet supported. The class will be * extended so that point representations are stored in a lookup table, * which is indexed by point data from the rendered PointSet. * - * \warn This mapper requires the PointData container to be the same size + * \warning This mapper requires the PointData container to be the same size * as the point container. * * \sa PointSetVtkMapper3D */ class MITKMAPPEREXT_EXPORT EnhancedPointSetVtkMapper3D : public VtkMapper { public: mitkClassMacro(EnhancedPointSetVtkMapper3D, VtkMapper); itkFactorylessNewMacro(Self); itkCloneMacro(Self); virtual const mitk::PointSet *GetInput(); vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override; void UpdateVtkTransform(mitk::BaseRenderer *renderer) override; static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false); LocalStorageHandler m_LSH; protected: EnhancedPointSetVtkMapper3D(); ~EnhancedPointSetVtkMapper3D() override; void RemoveEntryFromSourceMaps(mitk::PointSet::PointIdentifier pointID); void DeleteVtkObject(vtkObject *o); // functor for stl_each in destructor // update all vtk sources, mappers, actors with current data and properties void UpdateVtkObjects(); void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override; void ApplyColorAndOpacityProperties(mitk::BaseRenderer *renderer, vtkActor *actor) override; typedef mitk::PointSet::PointIdentifier PointIdentifier; typedef std::map SphereSourceMap; typedef std::map CubeSourceMap; typedef std::map ConeSourceMap; typedef std::map CylinderSourceMap; typedef std::pair ActorAndPointType; typedef std::map ActorMap; SphereSourceMap m_SphereSources; // stores all sphere sources CubeSourceMap m_CubeSources; // stores all cube sources ConeSourceMap m_ConeSources; // stores all cone sources CylinderSourceMap m_CylinderSources; // stores all cylinder sources ActorMap m_PointActors; // stores an actor for each point(referenced by its ID) and the currently used pointspec = // which source type is generating the polydata vtkActor *m_Contour; vtkTubeFilter *m_ContourSource; vtkAssembly *m_PropAssembly; // this contains everything, this will be returned by GetVtkProp() }; } // namespace mitk #endif /* MITKEnhancedPointSetVtkMapper3D_H_HEADER_INCLUDED_C1907273 */ diff --git a/Modules/ModelFit/include/mitkFormulaParser.h b/Modules/ModelFit/include/mitkFormulaParser.h index fa1c4b9219..6e7eb93d2a 100644 --- a/Modules/ModelFit/include/mitkFormulaParser.h +++ b/Modules/ModelFit/include/mitkFormulaParser.h @@ -1,107 +1,107 @@ /*============================================================================ 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 __MITKFORMULAPARSER_H__ #define __MITKFORMULAPARSER_H__ #include #include #include "mitkExceptionMacro.h" #include "MitkModelFitExports.h" namespace mitk { /*! * @brief Exception class for all exceptions that are generated in the FormulaParser module. */ class MITKMODELFIT_EXPORT FormulaParserException : public mitk::Exception { public: mitkExceptionClassMacro(FormulaParserException, mitk::Exception); }; /*! * @brief This class offers the functionality to evaluate simple mathematical formula * strings (e.g. "3.5 + 4 * x * sin(x) - 1 / 2"). - * @details Internally it utilizes the @c boost::spirit framework with the @ref Grammar + * @details Internally it utilizes the @c boost::spirit framework with the Grammar * structure to parse the input string into a valid result number. * Function strings (e.g. @c "sin", @c "tan" or @c "abs") are translated to * actual function calls and variables (e.g. @c "x", @c "myVariable", "amount_") * are replaced by their currently assigned value via a look-up table. * * The parser is able to recognize: * @li sums, differences, products and divisions (a + b, * 4 - 3, 2 * x, 9 / 3) * @li algebraic signs (@c +5, @c -5) * @li exponentiation (2 ^ 4) * @li parentheses (3 * (4 + 2)) * @li variables (@c x, @c myVar, @c test2_var_) * @li the following unary functions: @c abs, @c exp, @c sin, @c cos, @c tan, * @c sind (sine in degrees), @c cosd (cosine in degrees), @c tand (tangent in * degrees) * * In order to use the FormulaParser you just have to initialize it with a map of * variables (i.e. a look-up table where @c "x" is assigned to @c 5 for example and * @c "y" is assigned to @c 13 and so on) and then call the * @ref FormulaParser::parse function with the string that should be evaluated. Be * sure to update the look-up table everytime a variable's value changes since that * is not done automatically. * * @author Sascha Diatschuk */ class MITKMODELFIT_EXPORT FormulaParser { public: using ValueType = double; using VariableMapType = std::map; /*! * @brief Construct the FormulaParser and initialized the variables with * @b variables. * @param[in] variables A map of variables with values that will be assigned to the * corresponding member variable. The map is delivered as a * pointer so you can still change it from outside this class. */ FormulaParser(const VariableMapType* variables); /*! * @brief Evaluates the @b input string and returns the resulting * value. * @param[in] input The string to be evaluated. * @return The number that results from the evaluated string. * @throw FormulaParserException If * @li the parser comes across an unexpected character, * @li a variable in the input string could not be found in the look-up * table or * @li the parser cannot apply the grammar to the string at all. */ ValueType parse(const std::string& input); /*! * @brief Looks up the associated value of the given string @b var in the * variables map. * @param[in] var The name of the variable whose value is to be returned. * @return The associated value of the given variable name. * @throw FormulaParserException If the variable map is empty or the given variable name * cannot be found. */ ValueType lookupVariable(const std::string var); private: /*! @brief Map that holds the values that will replace the variables during evaluation. */ const VariableMapType* m_Variables; }; } #endif diff --git a/Modules/ModelFit/include/mitkModelFitCmdAppsHelper.h b/Modules/ModelFit/include/mitkModelFitCmdAppsHelper.h index 5cc65983a5..4d2cd049f2 100644 --- a/Modules/ModelFit/include/mitkModelFitCmdAppsHelper.h +++ b/Modules/ModelFit/include/mitkModelFitCmdAppsHelper.h @@ -1,56 +1,56 @@ /*============================================================================ 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 _MITK_MODEL_FIT_CMD_APPS_HELPER_H_ #define _MITK_MODEL_FIT_CMD_APPS_HELPER_H_ // std includes #include // itk includes #include "itksys/SystemTools.hxx" // MITK includes #include #include #include #include #include "MitkModelFitExports.h" namespace mitk { /** Helper function that generates the file path that would be used to store an result image. The output path will be determined given the outputPathTemplate (which determines the directory, - the basic file name and the file formate). The output file name is: _.*/ + the basic file name and the file formate). The output file name is: \_\.\*/ MITKMODELFIT_EXPORT std::string generateModelFitResultImagePath(const std::string& outputPathTemplate, const std::string& parameterName); /** Helper function that takes the given image and stores it based on a template path. The real output path will be determined given the outputPathTemplate (which determines the directory, - the basic file name and the file formate). The output file name is: _.*/ + the basic file name and the file formate). The output file name is: \_\.\*/ MITKMODELFIT_EXPORT void storeParameterResultImage(const std::string& outputPathTemplate, const std::string& parameterName, mitk::Image* image, mitk::modelFit::Parameter::Type parameterType = mitk::modelFit::Parameter::ParameterType); /** Helper function that takes the given image, sets its properties according to the fit session and stores it. The output path will be determined given the outputPathTemplate (which determines the directory, the basic file name and the file formate). The output file name is: \_\.\*/ MITKMODELFIT_EXPORT void storeModelFitResultImage(const std::string& outputPathTemplate, const std::string& parameterName, mitk::Image* image, mitk::modelFit::Parameter::Type nodeType, const mitk::modelFit::ModelFitInfo* modelFitInfo); /** Helper function that stores all results of the passed generator according to the passed outputPathTemplate. For further information regarding the output file path, please see storeModelFitResultImage().*/ MITKMODELFIT_EXPORT void storeModelFitGeneratorResults(const std::string& outputPathTemplate, mitk::ParameterFitImageGeneratorBase* generator, const mitk::modelFit::ModelFitInfo* fitSession); /** Helper function that outputs on the std::cout the result images the generator would produces.*/ MITKMODELFIT_EXPORT void previewModelFitGeneratorResults(const std::string& outputPathTemplate, mitk::ParameterFitImageGeneratorBase* generator); } #endif diff --git a/Modules/ModelFit/include/mitkModelFitParameterValueExtraction.h b/Modules/ModelFit/include/mitkModelFitParameterValueExtraction.h index 48d2f11773..6212b1a88f 100644 --- a/Modules/ModelFit/include/mitkModelFitParameterValueExtraction.h +++ b/Modules/ModelFit/include/mitkModelFitParameterValueExtraction.h @@ -1,59 +1,65 @@ /*============================================================================ 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 mitkModelFitParameterValueExtraction_h #define mitkModelFitParameterValueExtraction_h #include #include "mitkModelFitInfo.h" #include "mitkModelTraitsInterface.h" #include "MitkModelFitExports.h" namespace mitk { /** Helper function that gets the voxel value (as double) of an image (given an 3D position and a time step). Function is used in different contexts of model fit view. + @param image + @param position + @param timestep @param noThrow If set to false, function will throw exceptions. If set to true, exceptions will be blocked, an MITK_ERROR will be notified and the return is 0.0.*/ MITKMODELFIT_EXPORT ModelTraitsInterface::ParameterValueType ReadVoxel(const mitk::Image* image, const mitk::Point3D& position, unsigned int timestep = 0, bool noThrow = true); /** Helper function that gets the voxel value (as double) of an image (given an image index and a time step). Function is used in different contexts of model fit view. + @param image + @param index + @param timestep @param noThrow If set to false, function will throw exceptions.If set to true, exceptions will be blocked, an MITK_ERROR will be notified and the return is 0.0. */ MITKMODELFIT_EXPORT ModelTraitsInterface::ParameterValueType ReadVoxel(const mitk::Image* image, const ::itk::Index<3>& index, unsigned int timestep = 0, bool noThrow = true); using ParameterValueMapType = std::map; /** Helper function that extracts a map (keys are the parameter names, values are the associated parameter values) of parameter values for the specified 3D point given a model fit info instance. @pre fit must point to a valid instance. */ MITKMODELFIT_EXPORT ParameterValueMapType ExtractParameterValueMapFromModelFit(const mitk::modelFit::ModelFitInfo* fitInfo, const mitk::Point3D& position); MITKMODELFIT_EXPORT ParameterValueMapType ExtractParameterValueMapFromModelFit(const mitk::modelFit::ModelFitInfo* fitInfo, const ::itk::Index<3>& index); /** Helper function that converts a parameter value map (like returned by ExtractParameterValueMapFromModelFit() into the ParametersType. the ordering will be deduced with the help of the passed trait interface. @pre pTraitInterface must point to a valid instance. @pre valueMap must contain all parameter names of pTraitsInterface*/ MITKMODELFIT_EXPORT ModelTraitsInterface::ParametersType ConvertParameterMapToParameterVector(const ParameterValueMapType &valueMap, const ModelTraitsInterface * pTraitInterface); } #endif diff --git a/Modules/ModelFit/include/mitkTimeGridHelper.h b/Modules/ModelFit/include/mitkTimeGridHelper.h index fba0b23e51..eb9c25150c 100644 --- a/Modules/ModelFit/include/mitkTimeGridHelper.h +++ b/Modules/ModelFit/include/mitkTimeGridHelper.h @@ -1,36 +1,37 @@ /*============================================================================ 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 __MITK_TIME_GRID_HELPER_H_ #define __MITK_TIME_GRID_HELPER_H_ #include "mitkModelBase.h" #include "MitkModelFitExports.h" namespace mitk { /* Checks if the time grid is monotone increasing (timeGrid[n] <= timeGrid[n+1]). * It is a precondition for the helper interpolate time grid.*/ MITKMODELFIT_EXPORT bool TimeGridIsMonotonIncreasing(const ModelBase::TimeGridType timeGrid); /* Helper function that interpolates a passed signal to a new time grid. * @pre The time grids must be monotone increasing. Use TimeGridIsMonotonIncreasing() to verify that.*/ MITKMODELFIT_EXPORT ModelBase::ModelResultType InterpolateSignalToNewTimeGrid(const ModelBase::ModelResultType& inputSignal, const ModelBase::TimeGridType& inputGrid, const ModelBase::TimeGridType& outputGrid); /** Super sample passed time grid by a given supersampling rate and interpolates linear in between original time steps. + * @param grid * @param samplingRate Defines how many samples should be generated between to original time steps (including the preceeding time step). E.g. a sampling rate of 1 will just returns the original grid untouched; a sampling rate of 3 will generate to aditional steps between to original steps.*/ MITKMODELFIT_EXPORT ModelBase::TimeGridType GenerateSupersampledTimeGrid(const mitk::ModelBase::TimeGridType& grid, const unsigned int samplingRate); } #endif diff --git a/Modules/OpenCVVideoSupport/Commands/mitkGrabCutOpenCVImageFilter.h b/Modules/OpenCVVideoSupport/Commands/mitkGrabCutOpenCVImageFilter.h index 774101d459..361c0dad68 100644 --- a/Modules/OpenCVVideoSupport/Commands/mitkGrabCutOpenCVImageFilter.h +++ b/Modules/OpenCVVideoSupport/Commands/mitkGrabCutOpenCVImageFilter.h @@ -1,287 +1,287 @@ /*============================================================================ 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 MITKGRABCUTOPENCVIMAGEFILTER_H #define MITKGRABCUTOPENCVIMAGEFILTER_H // mitk headers #include "mitkAbstractOpenCVImageFilter.h" #include "mitkVector.h" // itk headers #include "itkObjectFactory.h" #include "itkMutexLock.h" // opencv headers #include namespace itk { template class Index; template class SmartPointer; class MultiThreader; class ConditionVariable; class FastMutexLock; } namespace mitk { class PointSet; /** * \brief Makes the OpenCV GrabCut filter available as OpenCVImageFilter. * * Image filtering is done asynchronly by using a worker thread as GrabCut segmentation * can take up to some seconds. Calling the mitk::GrabCutOpenCVImageFilter::OnFilterImage() * method sets just the input image and wakes up the worker thread. It is not guaranteed * that every image gets segmented. If multiple new images where set before a segmentation * was finished, only the last new image gets segmented afterwards. * * At least foreground model points have to be set by * mitk::GrabCutOpenCVImageFilter::SetModelPoints() before a segmentation can be performed. * The worder thread will not be waken up before any model points were set. * * When a new segmentation is ready, mitk::GrabCutOpenCVImageFilter::GetCurrentImageId() * returns a new image id. The segmentation can be got then by calling * mitk::GrabCutOpenCVImageFilter::GetResultMask(), * mitk::GrabCutOpenCVImageFilter::GetResultContours() or * mitk::GrabCutOpenCVImageFilter::GetResultContourWithPixel(). */ class MITKOPENCVVIDEOSUPPORT_EXPORT GrabCutOpenCVImageFilter : public AbstractOpenCVImageFilter { public: /** \brief List holding image indices of the model points. */ typedef std::vector > ModelPointsList; mitkClassMacro(GrabCutOpenCVImageFilter, AbstractOpenCVImageFilter); itkFactorylessNewMacro(Self); itkCloneMacro(Self); GrabCutOpenCVImageFilter(); ~GrabCutOpenCVImageFilter() override; /** * \brief Implementation of the virtual image filtering method. * The input image is copied to a member attribute, but the actual filtering is not done * in this method. Instead a worker thread is waken up every time this method is called, * if foreground model points were set before. * - * \param OpenCV image to be segmentated + * \param image OpenCV image to be segmentated * \return false if an empty image was set, true otherwise */ bool OnFilterImage( cv::Mat& image ) override; /** * \brief Sets a list of image indices as foreground model points. * \param foregroundPoints List of image indices which definitely belong to the foreground. */ void SetModelPoints(ModelPointsList foregroundPoints); /** * \brief Sets a list of image indices as foreground and another list as background model points. * \param foregroundPoints List of image indices which definitely belong to the foreground. * \param backgroundPoints List of image indices which definitely belong to the background. */ void SetModelPoints(ModelPointsList foregroundPoints, ModelPointsList backgroundPoints); /** * \brief Sets a mask where every non-zero pixel is treated as a foreground model pixel. */ void SetModelPoints(cv::Mat foregroundMask); /** * \brief Sets masks specifying foreground and background points. * \param foregroundMask every non-zero pixel is treated as a foreground model pixel * \param backgroundMask every non-zero pixel is treated as a background model pixel */ void SetModelPoints(cv::Mat foregroundMask, cv::Mat backgroundMask); /** * \brief Set a size of which each model point is dilated before image filtering. * The more color information of the foreground object the GrabCut filter gets the better * the result will be. Therefore the foreground pixels can be dilated before filtering. The * caller is responsible for setting a dilation size so that no foreground model pixels will * be indeed part of the background after dilation. * * Dilation is done to the background model pixles as well, if there are any set for the * filter. * * \param modelPointsDilationSize how many pixels are added in every direction, 0 sets back to no dilation */ void SetModelPointsDilationSize(int modelPointsDilationSize); /** * \brief Use only the region around the foreground model points for the segmentation. * * This is mainly for reasons of segmentation speed and has the drawback that the foreground * model points (plus the given additional border) have to cover the whole foreground object. * * The segmentation filter can be set back to using the whole image by calling * mitk::GrabCutOpenCVImageFilter::SetUseFullImage(). * * \param additionalBorder size of the border around the foreground points which will be used for segmentation, too */ void SetUseOnlyRegionAroundModelPoints(unsigned int additionalBorder); /** * \brief The full image is used as input for the segmentation. * This method sets the behaviour back to the default behaviour in case * mitk::GrabCutOpenCVImageFilter::SetUseOnlyRegionAroundModelPoints() was * called before. */ void SetUseFullImage(); /** * \brief Getter for the rectangle used for the area of segmentation. * See mitk::GrabCutOpenCVImageFilter::SetUseOnlyRegionAroundModelPoints(). * This method is mainly for debugging purposes and may be removed in * the future. */ cv::Rect GetRegionAroundModelPoints(); /** * \brief Getter for an ascending id of the current result image. * The id will be increased for every segmentation that is produced by the worker thread. * It can be used to determine if a new segmentation was produced since the last time a * segmentation was got from this filter. * * int lastResultImageId = grabCutFilter->GetResultImageId(); * // do something * if ( lastResultImageId != grabCutFilter->GetResultImageId() ) * // get new segmentation */ int GetResultImageId(); /** * \brief Getter for the result mask of the current segmentation. * The result of this method is not necessarily consistent with the result of * mitk::GrabCutOpenCVImageFilter::GetResultContours() if they are called afterwards. * The segmentation may have changed in the meantime. One should decide if he needs * a mask or a contour or convert one into the other on his own. * \return image of the size of the input image where all pixels segmented as foreground are non-zero */ cv::Mat GetResultMask(); /** * \brief Getter for the contours of the current segmentation. * * A segmentation can consist of multiple regions therefore a list of contours * is returned. If one needs only one specific region he can call * mitk::GrabCutOpenCVImageFilter::GetResultContourWithPixel(). * * This result of this method is not necessarily consistent with the result of * mitk::GrabCutOpenCVImageFilter::GetResultContours() if they are called afterwards. * The segmentation may have changed in the meantime. One should decide if he needs * a mask or a contour or convert one into the other on his own. * * \return List containing lists of pixel indices for every contour. */ std::vector GetResultContours(); /** * \brief Getter for one specific contour of the current segmentation. * * Can be used if only one (of possible multiple contours) is needed. A pixel index * must be given to select from the contours. This could be one of the foreground * model pixels for example. If other criteria are needed to distinguish the contours * mitk::GrabCutOpenCVImageFilter::GetResultContours() can be used instead and therefore * contour selection can be done by hand then. * * This result of this method is not necessarily consistent with the result of * mitk::GrabCutOpenCVImageFilter::GetResultContours() if they are called afterwards. * The segmentation may have changed in the meantime. One should decide if he needs * a mask or a contour or convert one into the other on his own. * * \param pixelIndex index of a pixel which lies inside the contour * \return list of pixel indices for the selected contour */ ModelPointsList GetResultContourWithPixel(itk::Index<2> pixelIndex); protected: /** \brief Creates an image mask for GrabCut algorithm by using the foreground and background point sets. * Background and foreground points will be dilated by the size set by * mitk::GrabCutOpenCVImageFilter::SetModelPointsDilationSize(). */ cv::Mat GetMaskFromPointSets(); /** * \brief Creates a bounding box around all pixels which aren't propably background. * The bounding box is widened as specified by * mitk::GrabCutOpenCVImageFilter::SetUseOnlyRegionAroundModelPoints(). */ cv::Rect GetBoundingRectFromMask(cv::Mat mask); /** * \brief Performs a GrabCut segmentation of the given input image. * \param input image on which the segmentation will be performed * \param mask foreground and background pixels used as basis for segmentation * \return mask with every pixel of the segmented foreground object set non-zero */ cv::Mat RunSegmentation(cv::Mat input, cv::Mat mask); /** * \brief Creates a list of points from every non-zero pixel of the given mask. */ ModelPointsList ConvertMaskToModelPointsList(cv::Mat mask); int m_ModelPointsDilationSize; bool m_UseOnlyRegionAroundModelPoints; unsigned int m_AdditionalWidth; cv::Rect m_BoundingBox; ModelPointsList m_ForegroundPoints; ModelPointsList m_BackgroundPoints; cv::Mat m_InputImage; cv::Mat m_GrabCutMask; cv::Mat m_ResultMask; unsigned int m_CurrentProcessImageNum; /** \brief id of the image currently set as m_InputImage */ int m_InputImageId; /** \brief id of the image which segmentation result is currently present in m_ResultMask */ int m_ResultImageId; private: /** * \brief Worker thread for doing the segmentation. * It blocks every time a image was segmented and will be waken up again by * the mitk::GrabCutOpenCVImageFilter::OnFilterImage() method. * * \param pInfoStruct pointer to the GrabCutOpenCVImageFilter object * \return */ static ITK_THREAD_RETURN_TYPE SegmentationWorker(void* pInfoStruct); int m_ThreadId; /** \brief worker thread will terminate after the next wakeup if set to true */ bool m_StopThread; itk::SmartPointer m_MultiThreader; itk::SmartPointer m_WorkerBarrier; /** \brief mutex for guarding m_InputImage and m_InputImageId */ itk::SmartPointer m_ImageMutex; /** \brief mutex for guarding m_ResultMask and m_ResultImageId */ itk::SmartPointer m_ResultMutex; /** \brief mutex for guarding m_ForegroundPoints and m_BackgroundPoints */ itk::SmartPointer m_PointSetsMutex; }; } // namespace mitk #endif // MITKGRABCUTOPENCVIMAGEFILTER_H diff --git a/Modules/OpenIGTLink/mitkIGTLMeasurements.h b/Modules/OpenIGTLink/mitkIGTLMeasurements.h index 598ea28a6f..82b24b6cfd 100644 --- a/Modules/OpenIGTLink/mitkIGTLMeasurements.h +++ b/Modules/OpenIGTLink/mitkIGTLMeasurements.h @@ -1,125 +1,85 @@ /*============================================================================ 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 IGTLMeasurements_H_HEADER_INCLUDED_ #define IGTLMeasurements_H_HEADER_INCLUDED_ // Microservices #include #include #include "MitkOpenIGTLinkExports.h" #include "itkObject.h" #include "mitkCommon.h" namespace mitk { - ///** - //* \brief Is a helper class to make measurments for latency and fps - //* - //* \ingroup OpenIGTLink - //*/ - //class MITKOPENIGTLINK_EXPORT IGTLMeasurementsImplementation : public itk::Object - //{ - //public: - // mitkClassMacroItkParent(IGTLMeasurementsImplementation, itk::Object); - // itkFactorylessNewMacro(Self) - // itkCloneMacro(Self) - - // typedef std::list MeasurementList; - // typedef std::map MeasurementPoints; - - // /** - // * \brief AddMeasurementPoint - // */ - // void AddMeasurement(unsigned int measurementPoint); - // bool ExportData(std::string filename); - - // /** - // * \brief clears all measurements - // */ - // void Reset(); - - // void SetStarted(bool started); - - // void RegisterAsMicroservice(); - // void UnRegisterMicroservice(); - //protected: - // IGTLMeasurementsImplementation(); - // ~IGTLMeasurementsImplementation(); - - // /** \brief */ - // MeasurementPoints m_MeasurementPoints; - - // bool m_IsStarted; - - // us::ServiceRegistration m_ServiceRegistration; - //}; - /** * \brief Is a helper class to make measurments for latency and fps * * \ingroup OpenIGTLink */ class MITKOPENIGTLINK_EXPORT IGTLMeasurements : public itk::Object { public: mitkClassMacroItkParent(IGTLMeasurements, itk::Object); static IGTLMeasurements* GetInstance(); /** * \brief AddMeasurementPoint + * \param measurementPoint + * \param index * \param timestamp Sets the timestamp, if it is 0 the current system time is used. */ void AddMeasurement(unsigned int measurementPoint, unsigned int index, long long timestamp = 0); /** * \brief AddMeasurementPoint */ bool ExportData(std::string filename); /** * \brief clears all measurements */ void Reset(); void SetStarted(bool started); private: // Only our module activator class should be able to instantiate // a SingletonOneService object. friend class IGTLModuleActivator; itkFactorylessNewMacro(Self) //itkCloneMacro(Self) IGTLMeasurements(); ~IGTLMeasurements() override; // Disable copy constructor and assignment operator. IGTLMeasurements(const IGTLMeasurements&); IGTLMeasurements& operator=(const IGTLMeasurements&); //protected: //IGTLMeasurementsImplementation::Pointer m_Measurements; typedef std::pair TimeStampIndexPair; typedef std::list MeasurementList; typedef std::map MeasurementPoints; MeasurementPoints m_MeasurementPoints; bool m_IsStarted; }; } // namespace mitk #endif /* MITKIGTLMeasurements_H_HEADER_INCLUDED_ */ diff --git a/Modules/RT/include/mitkDoseImageVtkMapper2D.h b/Modules/RT/include/mitkDoseImageVtkMapper2D.h index cb0f7bbded..e376d228a1 100644 --- a/Modules/RT/include/mitkDoseImageVtkMapper2D.h +++ b/Modules/RT/include/mitkDoseImageVtkMapper2D.h @@ -1,309 +1,303 @@ /*============================================================================ 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 MITKDoseImageVtkMapper2D2D_H_HEADER_INCLUDED #define MITKDoseImageVtkMapper2D2D_H_HEADER_INCLUDED //MITK #include #include //MITK Rendering #include "mitkBaseRenderer.h" #include "mitkVtkMapper.h" #include "mitkExtractSliceFilter.h" //VTK #include #include #include class vtkActor; class vtkPolyDataMapper; class vtkPlaneSource; class vtkImageData; class vtkLookupTable; class vtkImageExtractComponents; class vtkImageReslice; class vtkImageChangeInformation; class vtkPoints; class vtkMitkThickSlicesFilter; class vtkPolyData; class vtkMitkApplyLevelWindowToRGBFilter; class vtkMitkLevelWindowFilter; namespace mitk { /** \brief Mapper to resample and display 2D slices of a 3D image. * - * The following image gives a brief overview of the mapping and the involved parts. - * - * \image html DoseImageVtkMapper2Darchitecture.png - * * First, the image is resliced by means of vtkImageReslice. The volume image * serves as input to the mapper in addition to spatial placement of the slice and a few other * properties such as thick slices. This code was already present in the old version * (mitkImageMapperGL2D). * * Next, the obtained slice (m_ReslicedImage) is put into a vtkMitkLevelWindowFilter * and the scalar levelwindow, opacity levelwindow and optional clipping to * local image bounds are applied * * Next, the output of the vtkMitkLevelWindowFilter is used to create a texture * (m_Texture) and a plane onto which the texture is rendered (m_Plane). For * mapping purposes, a vtkPolyDataMapper (m_Mapper) is utilized. Orthographic * projection is applied to create the effect of a 2D image. The mapper and the * texture are assigned to the actor (m_Actor) which is passed to the VTK rendering * pipeline via the method GetVtkProp(). * * In order to transform the textured plane to the correct position in space, the * same transformation as used for reslicing is applied to both the camera and the * vtkActor. All important steps are explained in more detail below. The resulting * 2D image (by reslicing the underlying 3D input image appropriately) can either * be directly rendered in a 2D view or just be calculated to be used later by another * rendering entity, e.g. in texture mapping in a 3D view. * * Properties that can be set for images and influence the imageMapper2D are: * * - \b "opacity": (FloatProperty) Opacity of the image * - \b "color": (ColorProperty) Color of the image * - \b "LookupTable": (mitkLookupTableProperty) If this property is set, * the default lookuptable will be ignored and the "LookupTable" value * will be used instead. * - \b "Image Rendering.Mode": This property decides which mode is used to render images. (E.g. if a lookup table or a transferfunction is applied). Detailed documentation about the modes can be found here: \link mitk::RenderingModeProperty \endlink * - \b "Image Rendering.Transfer Function": (mitkTransferFunctionProperty) If this * property is set, a color transferfunction will be used to color the image. * - \b "binary": (BoolProperty) is the image a binary image or not * - \b "outline binary": (BoolProperty) show outline of the image or not * - \b "texture interpolation": (BoolProperty) texture interpolation of the image * - \b "reslice interpolation": (VtkResliceInterpolationProperty) reslice interpolation of the image * - \b "in plane resample extent by geometry": (BoolProperty) Do it or not * - \b "bounding box": (BoolProperty) Is the Bounding Box of the image shown or not * - \b "layer": (IntProperty) Layer of the image * - \b "volume annotation color": (ColorProperty) color of the volume annotation, TODO has to be reimplemented * - \b "volume annotation unit": (StringProperty) annotation unit as string (does not implicit convert the unit!) unit is ml or cm3, TODO has to be reimplemented * The default properties are: * - \b "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite ) * - \b "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ) * - \b "binary", mitk::BoolProperty::New( true ), renderer, overwrite ) * - \b "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite ) * - \b "texture interpolation", mitk::BoolProperty::New( false ) ) * - \b "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() ) * - \b "in plane resample extent by geometry", mitk::BoolProperty::New( false ) ) * - \b "bounding box", mitk::BoolProperty::New( false ) ) * - \b "layer", mitk::IntProperty::New(10), renderer, overwrite) * - \b "Image Rendering.Transfer Function": Default color transfer function for CTs * - \b "LookupTable": Rainbow color. * If the modality-property is set for an image, the mapper uses modality-specific default properties, * e.g. color maps, if they are defined. * \ingroup Mapper */ class MITKRT_EXPORT DoseImageVtkMapper2D : public VtkMapper { public: /** Standard class typedefs. */ mitkClassMacro( DoseImageVtkMapper2D,VtkMapper ); /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** \brief Get the Image to map */ const mitk::Image *GetInput(void); /** \brief Checks whether this mapper needs to update itself and generate * data. */ void Update(mitk::BaseRenderer * renderer) override; //### methods of MITK-VTK rendering pipeline vtkProp* GetVtkProp(mitk::BaseRenderer* renderer) override; //### end of methods of MITK-VTK rendering pipeline /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */ /** * To render transveral, coronal, and sagittal, the mapper is called three times. * For performance reasons, the corresponding data for each view is saved in the * internal helper class LocalStorage. This allows rendering n views with just * 1 mitkMapper using n vtkMapper. * */ class MITKRT_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage { public: /** \brief Actor of a 2D render window. */ vtkSmartPointer m_Actor; vtkSmartPointer m_Actors; /** \brief Mapper of a 2D render window. */ vtkSmartPointer m_Mapper; vtkSmartPointer m_VectorComponentExtractor; /** \brief Current slice of a 2D render window.*/ vtkSmartPointer m_ReslicedImage; /** \brief Empty vtkPolyData that is set when rendering geometry does not * intersect the image geometry. * \warning This member variable is set to nullptr, * if no image geometry is inside the plane geometry * of the respective render window. Any user of this * slice has to check whether it is set to nullptr! */ vtkSmartPointer m_EmptyPolyData; /** \brief Plane on which the slice is rendered as texture. */ vtkSmartPointer m_Plane; /** \brief The texture which is used to render the current slice. */ vtkSmartPointer m_Texture; /** \brief The lookuptables for colors and level window */ vtkSmartPointer m_DefaultLookupTable; vtkSmartPointer m_BinaryLookupTable; vtkSmartPointer m_ColorLookupTable; /** \brief The actual reslicer (one per renderer) */ mitk::ExtractSliceFilter::Pointer m_Reslicer; /** \brief Filter for thick slices */ vtkSmartPointer m_TSFilter; /** \brief PolyData object containg all lines/points needed for outlining the contour. This container is used to save a computed contour for the next rendering execution. For instance, if you zoom or pann, there is no need to recompute the contour. */ vtkSmartPointer m_OutlinePolyData; /** \brief Timestamp of last update of stored data. */ itk::TimeStamp m_LastUpdateTime; /** \brief mmPerPixel relation between pixel and mm. (World spacing).*/ mitk::ScalarType* m_mmPerPixel; /** \brief This filter is used to apply the level window to Grayvalue and RBG(A) images. */ vtkSmartPointer m_LevelWindowFilter; /** \brief Default constructor of the local storage. */ LocalStorage(); /** \brief Default deconstructor of the local storage. */ ~LocalStorage() override; }; /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ mitk::LocalStorageHandler m_LSH; /** \brief Get the LocalStorage corresponding to the current renderer. */ LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer); /** \brief Set the default properties for general image rendering. */ static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = nullptr, bool overwrite = false); /** \brief This method switches between different rendering modes (e.g. use a lookup table or a transfer function). * Detailed documentation about the modes can be found here: \link mitk::RenderingModeProperty \endlink */ void ApplyRenderingMode(mitk::BaseRenderer *renderer); protected: /** \brief Transforms the actor to the actual position in 3D. * \param renderer The current renderer corresponding to the render window. */ void TransformActor(mitk::BaseRenderer* renderer); /** \brief Generates a plane according to the size of the resliced image in milimeters. * - * \image html texturedPlane.png - * * In VTK a vtkPlaneSource is defined through three points. The origin and two * points defining the axes of the plane (see VTK documentation). The origin is * set to (xMin; yMin; Z), where xMin and yMin are the minimal bounds of the * resliced image in space. Z is relevant for blending and the layer property. * The center of the plane (C) is also the center of the view plane (cf. the image above). * * \note For the standard MITK view with three 2D render windows showing three * different slices, three such planes are generated. All these planes are generated * in the XY-plane (even if they depict a YZ-slice of the volume). * */ void GeneratePlane(mitk::BaseRenderer* renderer, double planeBounds[6]); /** \brief Generates a vtkPolyData object containing the outline of a given binary slice. \param renderer: Pointer to the renderer containing the needed information \note This code is based on code from the iil library. */ vtkSmartPointer CreateOutlinePolyData(mitk::BaseRenderer* renderer); /** Default constructor */ DoseImageVtkMapper2D(); /** Default deconstructor */ ~DoseImageVtkMapper2D() override; /** \brief Does the actual resampling, without rendering the image yet. * All the data is generated inside this method. The vtkProp (or Actor) * is filled with content (i.e. the resliced image). * * After generation, a 4x4 transformation matrix(t) of the current slice is obtained * from the vtkResliceImage object via GetReslicesAxis(). This matrix is * applied to each textured plane (actor->SetUserTransform(t)) to transform everything * to the actual 3D position (cf. the following image). * * \image html cameraPositioning3D.png * */ void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override; /** \brief This method uses the vtkCamera clipping range and the layer property * to calcualte the depth of the object (e.g. image or contour). The depth is used * to keep the correct order for the final VTK rendering.*/ float CalculateLayerDepth(mitk::BaseRenderer* renderer); /** \brief This method applies (or modifies) the lookuptable for all types of images. * \warning To use the lookup table, the property 'Lookup Table' must be set and a 'Image Rendering.Mode' * which uses the lookup table must be set. */ void ApplyLookuptable(mitk::BaseRenderer* renderer); /** \brief This method applies a color transfer function. * Internally, a vtkColorTransferFunction is used. This is usefull for coloring continous * images (e.g. float) * \warning To use the color transfer function, the property 'Image Rendering.Transfer Function' must be set and a 'Image Rendering.Mode' which uses the color transfer function must be set. */ void ApplyColorTransferFunction(mitk::BaseRenderer* renderer); /** * @brief ApplyLevelWindow Apply the level window for the given renderer. * \warning To use the level window, the property 'LevelWindow' must be set and a 'Image Rendering.Mode' which uses the level window must be set. * @param renderer Level window for which renderer? */ void ApplyLevelWindow(mitk::BaseRenderer* renderer); /** \brief Set the color of the image/polydata */ void ApplyColor( mitk::BaseRenderer* renderer ); /** \brief Set the opacity of the actor. */ void ApplyOpacity( mitk::BaseRenderer* renderer ); /** * \brief Calculates whether the given rendering geometry intersects the * given SlicedGeometry3D. * * This method checks if the given PlaneGeometry intersects the given * SlicedGeometry3D. It calculates the distance of the PlaneGeometry to all * 8 cornerpoints of the SlicedGeometry3D. If all distances have the same * sign (all positive or all negative) there is no intersection. * If the distances have different sign, there is an intersection. **/ bool RenderingGeometryIntersectsImage( const PlaneGeometry* renderingGeometry, SlicedGeometry3D* imageGeometry ); private: void CreateLevelOutline(mitk::BaseRenderer* renderer, const mitk::IsoDoseLevel* level, float pref, vtkSmartPointer points, vtkSmartPointer lines, vtkSmartPointer colors); }; } // namespace mitk #endif /* MITKDoseImageVtkMapper2D_H_HEADER_INCLUDED_C10E906E */ diff --git a/Modules/Segmentation/Algorithms/mitkContourUtils.h b/Modules/Segmentation/Algorithms/mitkContourUtils.h index d9add259f2..3040e042fa 100644 --- a/Modules/Segmentation/Algorithms/mitkContourUtils.h +++ b/Modules/Segmentation/Algorithms/mitkContourUtils.h @@ -1,68 +1,71 @@ /*============================================================================ 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 mitkContourUtilshIncludett #define mitkContourUtilshIncludett #include "mitkContour.h" #include "mitkContourModel.h" #include "mitkImage.h" #include namespace mitk { /** * \brief Helpful methods for working with contours and images * * Legacy support for mitk::Contour * TODO remove this class when mitk::Contour is removed */ class MITKSEGMENTATION_EXPORT ContourUtils : public itk::Object { public: mitkClassMacroItkParent(ContourUtils, itk::Object); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** \brief Projects a contour onto an image point by point. Converts from world to index coordinates. + \param slice + \param contourIn3D \param correctionForIpSegmentation adds 0.5 to x and y index coordinates (difference between ipSegmentation and MITK contours) + \param constrainToInside */ ContourModel::Pointer ProjectContourTo2DSlice(Image *slice, Contour *contourIn3D, bool correctionForIpSegmentation, bool constrainToInside); /** \brief Projects a slice index coordinates of a contour back into world coordinates. \param correctionForIpSegmentation subtracts 0.5 to x and y index coordinates (difference between ipSegmentation and MITK contours) */ ContourModel::Pointer BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry, Contour *contourIn2D, bool correctionForIpSegmentation = false); /** \brief Fill a contour in a 2D slice with a specified pixel value. */ void FillContourInSlice(Contour *projectedContour, Image *sliceImage, int paintingPixelValue = 1); protected: ContourUtils(); ~ContourUtils() override; }; } #endif diff --git a/Modules/Segmentation/Algorithms/mitkImageLiveWireContourModelFilter.h b/Modules/Segmentation/Algorithms/mitkImageLiveWireContourModelFilter.h index e2fd65b038..1b923b58b2 100644 --- a/Modules/Segmentation/Algorithms/mitkImageLiveWireContourModelFilter.h +++ b/Modules/Segmentation/Algorithms/mitkImageLiveWireContourModelFilter.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 _mitkImageLiveWireContourModelFilter_h__ #define _mitkImageLiveWireContourModelFilter_h__ #include "mitkCommon.h" #include "mitkContourModel.h" #include "mitkContourModelSource.h" #include #include #include #include #include #include namespace mitk { /** \brief Calculates a LiveWire contour between two points in an image. For defining costs between two pixels specific features are extraced from the image and tranformed into a single cost value. \sa ShortestPathCostFunctionLiveWire The filter is able to create dynamic cost tranfer map and thus use on the fly training. - \Note On the fly training will only be used for next update. + \note On the fly training will only be used for next update. The computation uses the last calculated segment to map cost according to features in the area of the segment. For time resolved purposes use ImageLiveWireContourModelFilter::SetTimestep( unsigned int ) to create the LiveWire contour at a specific timestep. \ingroup ContourModelFilters \ingroup Process */ class MITKSEGMENTATION_EXPORT ImageLiveWireContourModelFilter : public ContourModelSource { public: mitkClassMacro(ImageLiveWireContourModelFilter, ContourModelSource); itkFactorylessNewMacro(Self); itkCloneMacro(Self); typedef ContourModel OutputType; typedef OutputType::Pointer OutputTypePointer; typedef mitk::Image InputType; typedef itk::Image InternalImageType; typedef itk::ShortestPathImageFilter ShortestPathImageFilterType; typedef itk::ShortestPathCostFunctionLiveWire CostFunctionType; typedef std::vector> ShortestPathType; /** \brief start point in world coordinates*/ itkSetMacro(StartPoint, mitk::Point3D); itkGetMacro(StartPoint, mitk::Point3D); /** \brief end point in woorld coordinates*/ itkSetMacro(EndPoint, mitk::Point3D); itkGetMacro(EndPoint, mitk::Point3D); /** \brief Create dynamic cost tranfer map - use on the fly training. - \Note On the fly training will be used for next update only. + \note On the fly training will be used for next update only. The computation uses the last calculated segment to map cost according to features in the area of the segment. */ itkSetMacro(UseDynamicCostMap, bool); itkGetMacro(UseDynamicCostMap, bool); /** \brief Actual time step */ itkSetMacro(TimeStep, unsigned int); itkGetMacro(TimeStep, unsigned int); /** \brief Clear all repulsive points used in the cost function */ void ClearRepulsivePoints(); /** \brief Set a vector with repulsive points to use in the cost function */ void SetRepulsivePoints(const ShortestPathType &points); /** \brief Add a single repulsive point to the cost function */ void AddRepulsivePoint(const itk::Index<2> &idx); /** \brief Remove a single repulsive point from the cost function */ void RemoveRepulsivePoint(const itk::Index<2> &idx); virtual void SetInput(const InputType *input); using Superclass::SetInput; virtual void SetInput(unsigned int idx, const InputType *input); const InputType *GetInput(void); const InputType *GetInput(unsigned int idx); virtual OutputType *GetOutput(); virtual void DumpMaskImage(); /** \brief Create dynamic cost tranfer map - on the fly training*/ bool CreateDynamicCostMap(mitk::ContourModel *path = nullptr); protected: ImageLiveWireContourModelFilter(); ~ImageLiveWireContourModelFilter() override; void GenerateOutputInformation() override{}; void GenerateData() override; void UpdateLiveWire(); /** \brief start point in worldcoordinates*/ mitk::Point3D m_StartPoint; /** \brief end point in woorldcoordinates*/ mitk::Point3D m_EndPoint; /** \brief Start point in index*/ mitk::Point3D m_StartPointInIndex; /** \brief End point in index*/ mitk::Point3D m_EndPointInIndex; /** \brief The cost function to compute costs between two pixels*/ CostFunctionType::Pointer m_CostFunction; /** \brief Shortest path filter according to cost function m_CostFunction*/ ShortestPathImageFilterType::Pointer m_ShortestPathFilter; /** \brief Flag to use a dynmic cost map or not*/ bool m_UseDynamicCostMap; unsigned int m_TimeStep; template void ItkPreProcessImage(const itk::Image *inputImage); template void CreateDynamicCostMapByITK(const itk::Image *inputImage, mitk::ContourModel *path = nullptr); InternalImageType::Pointer m_InternalImage; }; } #endif diff --git a/Modules/Segmentation/Interactions/mitkFeedbackContourTool.h b/Modules/Segmentation/Interactions/mitkFeedbackContourTool.h index f7525aeac6..945c4911fd 100644 --- a/Modules/Segmentation/Interactions/mitkFeedbackContourTool.h +++ b/Modules/Segmentation/Interactions/mitkFeedbackContourTool.h @@ -1,113 +1,118 @@ /*============================================================================ 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 mitkFeedbackContourTool_h_Included #define mitkFeedbackContourTool_h_Included #include "mitkCommon.h" #include "mitkContourModelUtils.h" #include "mitkContourUtils.h" //TODO remove legacy support #include "mitkImage.h" #include "mitkSegTool2D.h" #include #include "mitkDataNode.h" #include "mitkImageCast.h" namespace mitk { /** \brief Base class for tools that use a contour for feedback \sa Tool \sa ContourModel \ingroup Interaction \ingroup ToolManagerEtAl Implements helper methods, that might be of use to all kind of 2D segmentation tools that use a contour for user feedback. - Providing a feedback contour that might be added or removed from the visible scene (SetFeedbackContourVisible). - Filling of a contour into a 2D slice These helper methods are actually implemented in ContourUtils now. FeedbackContourTool only forwards such requests. \warning Only to be instantiated by mitk::ToolManager. $Author: nolden $ */ class MITKSEGMENTATION_EXPORT FeedbackContourTool : public SegTool2D { public: mitkClassMacro(FeedbackContourTool, SegTool2D); protected: FeedbackContourTool(); // purposely hidden FeedbackContourTool(const char *); // purposely hidden ~FeedbackContourTool() override; ContourModel *GetFeedbackContour(); void SetFeedbackContour(ContourModel::Pointer); void SetFeedbackContourVisible(bool); /// Provide values from 0.0 (black) to 1.0 (full color) void SetFeedbackContourColor(float r, float g, float b); void SetFeedbackContourColorDefault(); void Deactivated() override; void Activated() override; /** \brief Projects a contour onto an image point by point. Converts from world to index coordinates. + \param slice + \param contourIn3D \param correctionForIpSegmentation adds 0.5 to x and y index coordinates (difference between ipSegmentation and MITK contours) + \param constrainToInside */ ContourModel::Pointer ProjectContourTo2DSlice(Image *slice, ContourModel *contourIn3D, bool correctionForIpSegmentation = false, bool constrainToInside = true); /** \brief Projects a slice index coordinates of a contour back into world coordinates. + \param sliceGeometry + \param contourIn2D \param correctionForIpSegmentation subtracts 0.5 to x and y index coordinates (difference between ipSegmentation and MITK contours) */ ContourModel::Pointer BackProjectContourFrom2DSlice(const BaseGeometry *sliceGeometry, ContourModel *contourIn2D, bool correctionForIpSegmentation = false); /** \brief Fill a contour in a 2D slice with a specified pixel value. */ void FillContourInSlice(ContourModel *projectedContour, Image *sliceImage, int paintingPixelValue = 1); /** \brief Fill a contour in a 2D slice with a specified pixel value at a given time step. */ void FillContourInSlice(ContourModel *projectedContour, unsigned int timeStep, Image *sliceImage, int paintingPixelValue = 1); ContourModel::Pointer m_FeedbackContour; DataNode::Pointer m_FeedbackContourNode; bool m_FeedbackContourVisible; }; } // namespace #endif diff --git a/Modules/SemanticRelations/include/mitkControlPointManager.h b/Modules/SemanticRelations/include/mitkControlPointManager.h index 601ca9c945..3e13e89dc9 100644 --- a/Modules/SemanticRelations/include/mitkControlPointManager.h +++ b/Modules/SemanticRelations/include/mitkControlPointManager.h @@ -1,119 +1,119 @@ /*============================================================================ 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 MITKCONTROLPOINTMANAGER_H #define MITKCONTROLPOINTMANAGER_H #include // semantic relations module #include "mitkSemanticTypes.h" // mitk core #include namespace mitk { /** * @brief Provides helper functions that are needed to work with control points. * * These functions help to generate new control points, check for overlapping / containing control points or provide functionality * to find a fitting control point or even extend an already existing control point. */ /** * @brief Generates a control point from a given data node. * The date is extracted from the data node by using the 'DICOMHelper::GetDICOMDateFromDataNode'-function. * * @param datanode A data node pointer, whose date should be included in the newly generated control point. */ MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ControlPoint GenerateControlPoint(const mitk::DataNode* datanode); /** * @brief Find and return a whole control point including its date given a specific control point UID. * * @param caseID The current case identifier is defined by the given string. * @param controlPointUID The control point UID as string. * * @return The control point with its UID and the date. */ MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ControlPoint GetControlPointByUID(const SemanticTypes::CaseID& caseID, const SemanticTypes::ID& controlPointUID); /** * @brief Returns an already existing control point from the given vector of control points. This existing control point has the * the same date (year, month, day) as the given single control point. * If no existing control point can be found an empty control point is returned. * * @param caseID The current case identifier is defined by the given string. * @param controlPoint The control point to check for existence. * * @return The existing control point. */ MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ControlPoint FindExistingControlPoint(const SemanticTypes::CaseID& caseID, const SemanticTypes::ControlPoint& controlPoint); /** * @brief Returns an already existing close control point from the given vector of control points. This closest control point has a * date that is within a certain distance-in-days to the given control point. * If no closest control point can be found within the distance threshold an empty control point is returned. * * @param caseID The current case identifier is defined by the given string. * @param controlPoint The control point to check for distance. * * @return The closest control point. */ MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ControlPoint FindClosestControlPoint(const SemanticTypes::CaseID& caseID, const SemanticTypes::ControlPoint& controlPoint); /** * @brief Returns the examination period to which the given control point belongs. * Each examination point holds a vector of control point UIDs so that the UID of the given control point can be compared against the UIDs of the vector. * An empty examination period is returned if, * - the given vector of examination periods is empty * - the examination periods do not contain any control point UIDs * - the UID of the given control point is not contained in any examination period * * @param caseID The current case identifier is defined by the given string. * @param controlPoint The control point of which the examination period should be found. * * @return The examination period that contains the given control point. */ MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ExaminationPeriod FindContainingExaminationPeriod(const SemanticTypes::CaseID& caseID, const SemanticTypes::ControlPoint& controlPoint); /** * @brief Return the examination period to which the given data node belongs. * The control point is used to find an already existing or the closest control point in the semantic relations storage. * If such a control point is found, the 'FindClosestControlPoint'-function with this control point as an argument is used * to actually find the corresponding examination period. * * @param caseID The current case identifier is defined by the given string. * @param controlPoint The control point of which the examination period should be found. * * @return The examination period that fits the given data node. */ MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ExaminationPeriod FindFittingExaminationPeriod(const SemanticTypes::CaseID& caseID, const SemanticTypes::ControlPoint& controlPoint); /** * @brief Return the examination period to which the given data node belongs. * The DICOM date of the data node is used to find an already existing or the closest control point in the semantic relations storage. * If such a control point is found, the 'FindFittingExaminationPeriod'-function with this control point as an argument is used * to actually find the corresponding examination period. * - * @param datanode A data node pointer, whose date should be included in the newly generated control point. + * @param dataNode A data node pointer, whose date should be included in the newly generated control point. * * @return The examination period that contains the given data node. */ MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ExaminationPeriod FindFittingExaminationPeriod(const DataNode* dataNode); /** * @brief Sort the given vector of examination periods. * Each examination period has a vector of control point UIDs (stored in chronological order). * The examination periods can be sorted by comparing the first control points of the examination periods. * * @param caseID The current case identifier is defined by the given string. * @param allExaminationPeriods The examination periods to sort. */ MITKSEMANTICRELATIONS_EXPORT void SortAllExaminationPeriods(const SemanticTypes::CaseID& caseID, SemanticTypes::ExaminationPeriodVector& allExaminationPeriods); } // namespace mitk #endif // MITKCONTROLPOINTMANAGER_H diff --git a/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.h b/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.h index dfcb9c71ed..d5419912a7 100644 --- a/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.h +++ b/Modules/US/USFilters/mitkIGTLMessageToUSImageFilter.h @@ -1,78 +1,78 @@ /*============================================================================ 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 MITKIGTLMessageToUSImageFilter_H_HEADER_INCLUDED_ #define MITKIGTLMessageToUSImageFilter_H_HEADER_INCLUDED_ #include #include #include #include #include namespace mitk { class MITKUS_EXPORT IGTLMessageToUSImageFilter : public USImageSource { public: mitkClassMacro(IGTLMessageToUSImageFilter, USImageSource); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** *\brief Sets the number of expected outputs. * * Normally, this is done automatically by the filter concept. However, in our * case we can not know, for example, how many tracking elements are stored * in the incoming igtl message. Therefore, we have to set the number here to * the expected value. */ void SetNumberOfExpectedOutputs(unsigned int numOutputs); /** *\brief Connects the input of this filter to the outputs of the given * IGTLMessageSource * * This method does not support smartpointer. use FilterX.GetPointer() to * retrieve a dumbpointer. */ void ConnectTo(mitk::IGTLMessageSource* UpstreamFilter); protected: IGTLMessageToUSImageFilter(); using Superclass::GetNextRawImage; /** * \brief Copies the data from the next OIGTL message to an mitk::Image. * - * \param img the image to fill with the data from the OIGTL message. + * \param imgVector the image to fill with the data from the OIGTL message. */ void GetNextRawImage(std::vector& imgVector) override; private: mitk::IGTLMessageSource* m_upstream; mitk::Image::Pointer m_previousImage; /** * \brief Templated method to copy the data of the OIGTL message to the image, depending * on the pixel type contained in the message. * * \param img the image to fill with the data from msg * \param msg the OIGTL message to copy the data from * \param big_endian whether the data is in big endian byte order */ template void Initiate(mitk::Image::Pointer& img, igtl::ImageMessage* msg, bool big_endian); }; } // namespace mitk #endif // MITKIGTLMessageToUSImageFilter_H_HEADER_INCLUDED_ diff --git a/Plugins/org.blueberry.core.jobs/src/berryISchedulingRule.h b/Plugins/org.blueberry.core.jobs/src/berryISchedulingRule.h index 97cd93d78e..f3c41cd46a 100644 --- a/Plugins/org.blueberry.core.jobs/src/berryISchedulingRule.h +++ b/Plugins/org.blueberry.core.jobs/src/berryISchedulingRule.h @@ -1,89 +1,89 @@ /*============================================================================ 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 _BERRY_ISCHEDULING_RULE_H_ #define _BERRY_ISCHEDULING_RULE_H_ #include #include namespace berry { /** * Scheduling rules are used by jobs to indicate when they need exclusive access * to a resource. * @todo * Scheduling rules can also be applied synchronously to a thread * using IJobManager.beginRule(ISchedulingRule) and * IJobManager.endRule(ISchedulingRule). * * The job manager guarantees that * no two jobs with conflicting scheduling rules will run concurrently. * @todo * Multiple rules can be applied to a given thread only if the outer rule explicitly * allows the nesting as specified by the contains method. * *

* Clients may implement this interface. * * @see Job#GetRule() * @see Job#SetRule(ISchedulingRule) * @see Job#Schedule(long) * @see IJobManager#BeginRule(ISchedulingRule, org.eclipse.core.runtime.IProgressMonitor) * @see IJobManager#EndRule(ISchedulingRule) */ struct BERRY_JOBS ISchedulingRule: public Object { berryObjectMacro(berry::ISchedulingRule); /** * Returns whether this scheduling rule completely contains another scheduling * rule. Rules can only be nested within a thread if the inner rule is completely * contained within the outer rule. *

* Implementations of this method must obey the rules of a partial order relation * on the set of all scheduling rules. In particular, implementations must be reflexive * (a.contains(a) is always true), antisymmetric (a.contains(b) and b.contains(a) iff * equals(b), * and transitive (if a.contains(b) and b.contains(c), then a.contains(c)). Implementations * of this method must return false when compared to a rule they * know nothing about. * * @param rule the rule to check for containment * @return true if this rule contains the given rule, and * false otherwise. */ virtual bool Contains(ISchedulingRule::Pointer rule) const = 0; /** * Returns whether this scheduling rule is compatible with another scheduling rule. * If true is returned, then no job with this rule will be run at the * same time as a job with the conflicting rule. If false is returned, * then the job manager is free to run jobs with these rules at the same time. *

* Implementations of this method must be reflexive, symmetric, and consistent, * and must return false when compared to a rule they know * nothing about. * - * @param rule the rule to check for conflicts + * @param myRule the rule to check for conflicts * @return true if the rule is conflicting, and false * otherwise. */ virtual bool IsConflicting(ISchedulingRule::Pointer myRule) const = 0; }; } #endif // _BERRY_ISCHEDULING_RULE_H_ diff --git a/Plugins/org.mitk.core.ext/src/mitkIInputDevice.h b/Plugins/org.mitk.core.ext/src/mitkIInputDevice.h index aacf2b8093..b690331cf9 100644 --- a/Plugins/org.mitk.core.ext/src/mitkIInputDevice.h +++ b/Plugins/org.mitk.core.ext/src/mitkIInputDevice.h @@ -1,52 +1,52 @@ /*============================================================================ 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 MITKIINPUTDEVICE_H_ #define MITKIINPUTDEVICE_H_ #include #include #include namespace mitk { /** * An input device provides a method to register and unregister itself. Meaning
* for example adding listeners and instianciate classes necessary to use the input device. * - * @noimplement This interface is not intended to be implemented by clients. + * @note This interface is not intended to be implemented by clients. * @ingroup org_mitk_core_ext */ struct IInputDevice : public berry::Object { berryObjectMacro(mitk::IInputDevice); /** * Register the input device at one or more instances. */ virtual bool RegisterInputDevice() = 0; /** * Unregister the input device at one or more instances. */ virtual bool UnRegisterInputDevice() = 0; ~IInputDevice() override {} }; // end struct IInputDevice } // end namespace mitk Q_DECLARE_INTERFACE(mitk::IInputDevice, "org.mitk.IInputDevice") #endif /*MITKIINPUTDEVICE_H_*/ diff --git a/Plugins/org.mitk.core.ext/src/mitkIInputDeviceRegistry.h b/Plugins/org.mitk.core.ext/src/mitkIInputDeviceRegistry.h index 6606d54f90..820c162582 100644 --- a/Plugins/org.mitk.core.ext/src/mitkIInputDeviceRegistry.h +++ b/Plugins/org.mitk.core.ext/src/mitkIInputDeviceRegistry.h @@ -1,64 +1,64 @@ /*============================================================================ 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 MITKIINPUTDEVICEREGISTRY_H_ #define MITKIINPUTDEVICEREGISTRY_H_ #include #include "mitkIInputDeviceDescriptor.h" namespace mitk { /** * * The input device registry maintains a list of input devices explicitly registered * against the view extension point. *

* The description of a given input device is kept in a IInputDeviceDescriptor. *

*

* This interface is not intended to be implemented by clients. *

* * @see mitk::IInputDeviceDescriptor - * @noimplement This interface is not intended to be implemented by clients. + * @note This interface is not intended to be implemented by clients. * @ingroup org_mitk_core_ext */ struct IInputDeviceRegistry { /** * Return an input device descriptor with the given extension id. If no input device exists, * with the id return null. * * @param id * the id to search for * @return the descriptor or null */ virtual IInputDeviceDescriptor::Pointer Find(const QString& id) const = 0; /** * Return a list of input devices defined in the registry. * * @return the input devices. */ virtual QList GetInputDevices() const = 0; virtual ~IInputDeviceRegistry() {} }; // end struct IInputDeviceRegistry } // end namespace mitk Q_DECLARE_INTERFACE(mitk::IInputDeviceRegistry, "org.mitk.service.IInputDeviceRegistry") #endif /*MITKIINPUTDEVICEREGISTRY_H_*/ diff --git a/Utilities/mbilog/mbilogBackendCout.h b/Utilities/mbilog/mbilogBackendCout.h index e4d290980d..daba4f6645 100644 --- a/Utilities/mbilog/mbilogBackendCout.h +++ b/Utilities/mbilog/mbilogBackendCout.h @@ -1,60 +1,60 @@ /*============================================================================ 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 _mbilogBackendCout_H #define _mbilogBackendCout_H #include #include "mbilogExports.h" #include "mbilogLogMessage.h" #include "mbilogLoggingTypes.h" #include "mbilogTextBackendBase.h" namespace mbilog { /** * \brief Default backend of the mbi logging mechanism. This backend is used if no other backend is registered. * The backend formats the logging messages to a normal string and writes them to std::cout. * \ingroup mbilog */ class MBILOG_EXPORT BackendCout : public TextBackendBase { public: BackendCout(); ~BackendCout() override; /** \brief This method is called by the mbi logging mechanism if the object is registered in * the mbi logging mechanism and a logging message is emitted. The method formats the * logging messages to a normal string (depending on formatting mode) and writes it to std::cout. * - * \param logMessage Logging message. + * \param l Logging message. */ void ProcessMessage(const mbilog::LogMessage &l) override; /** \brief Sets the formatting mode. If true long messages will be displayed. Default is false (short/smart * messages). * Long messages provide all informations and are also capable to be postproccessed (e.g. in a web viewer). */ void SetFull(bool full); OutputType GetOutputType() const override; private: /** \brief The formatting mode of this backend. True is full/long message formatting mode. False is short/smart * message formatting mode */ bool m_useFullOutput; }; } #endif diff --git a/Utilities/mbilog/mbilogTextBackendBase.h b/Utilities/mbilog/mbilogTextBackendBase.h index be4e072b08..46a4e9bd77 100644 --- a/Utilities/mbilog/mbilogTextBackendBase.h +++ b/Utilities/mbilog/mbilogTextBackendBase.h @@ -1,71 +1,77 @@ /*============================================================================ 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 _mbilogTextBackendBase_H #define _mbilogTextBackendBase_H #include "mbilogBackendBase.h" #include "mbilogExports.h" namespace mbilog { /** Documentation * \brief This class is an abstract superclass for logging text backends. It adds string formatting methods * to the backend interface BackendBase. Accordingly backends that inherit from this class can be * registered in the mbi logging mechanism. * * \ingroup mbilog */ class MBILOG_EXPORT TextBackendBase : public BackendBase { public: ~TextBackendBase() override; /** \brief This method is called by the mbi logging mechanism if the object is registered in * the mbi logging mechanism and a logging message is emitted. * * \param logMessage Logging message which was emitted. * */ void ProcessMessage(const mbilog::LogMessage &logMessage) override = 0; protected: /** \brief Method formats the given LogMessage in the smart/short format and writes it to std::cout. + * \param l * \param threadID Can be set to the threadID where the logging message was emitted. Is 0 by default. */ void FormatSmart(const LogMessage &l, int threadID = 0); /** \brief Method formats the given LogMessage in the full/long format and writes it to std::cout. + * \param l * \param threadID Can be set to the threadID where the logging message was emitted. Is 0 by default. */ void FormatFull(const LogMessage &l, int threadID = 0); /** \brief Method formats the given LogMessage in the smart/short format and writes it to the given std::ostream. + * \param out + * \param l * \param threadID Can be set to the threadID where the logging message was emitted. Is 0 by default. */ void FormatSmart(std::ostream &out, const LogMessage &l, int threadID = 0); /** \brief Method formats the given LogMessage in the full/long format and writes it to the given std::ostream. + * \param out + * \param l * \param threadID Can be set to the threadID where the logging message was emitted. Is 0 by default. */ void FormatFull(std::ostream &out, const LogMessage &l, int threadID = 0); /** \brief Writes the system time to the given stream.*/ void AppendTimeStamp(std::ostream &out); /** \brief Special variant of method FormatSmart which uses colored messages (only for windows).*/ // TODO: implement for linux? void FormatSmartWindows(const mbilog::LogMessage &l, int /*threadID*/); }; } #endif