diff --git a/Documentation/Doxygen/3-DeveloperManual/Concepts/Concepts.dox b/Documentation/Doxygen/3-DeveloperManual/Concepts/Concepts.dox index 2213eef822..c66a8971dc 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Concepts/Concepts.dox +++ b/Documentation/Doxygen/3-DeveloperManual/Concepts/Concepts.dox @@ -1,32 +1,32 @@ /** \page Concepts MITK Concepts The following items describe some issues about MITK on a more abstract level. -# \subpage CodingPage "Coding Concepts" -# \ref CodingPageGeneral -# \ref CodingPageStyle -# \ref CodingPageMITKMacros -# \subpage MicroServices_Overview -# Data Concepts -# \subpage BasicDataTypesPage -# \subpage DataManagementPage -# \subpage ReaderWriterPage -# \subpage MitkImagePage -# \subpage MITKSegmentationTaskListsPage - -# \subpage MITKROIsPage + -# \subpage MITKROIPage -# \subpage PropertiesPage -# \subpage GeometryOverviewPage -# \subpage PipelineingConceptPage -# \subpage AnnotationPage -# \subpage PersistenceConceptPage -# \subpage SelectionConceptPage -# \subpage QVTKRendering -# Interaction -# \subpage DataInteractionPage -# \subpage InteractionPage -# \subpage LoggingPage -# \subpage ExceptionPage -# \subpage ModularizationPage "Modularization Concept" -# \ref ModularizationPageOverview */ diff --git a/Documentation/Doxygen/3-DeveloperManual/Concepts/MITKROIs.md b/Documentation/Doxygen/3-DeveloperManual/Concepts/MITKROIs.md index 7e73aa67e8..2dac2c9742 100644 --- a/Documentation/Doxygen/3-DeveloperManual/Concepts/MITKROIs.md +++ b/Documentation/Doxygen/3-DeveloperManual/Concepts/MITKROIs.md @@ -1,24 +1,154 @@ -# MITK ROIs {#MITKROIsPage} +# MITK ROI {#MITKROIPage} [TOC] +## Disclaimer + +Until the MITK ROI file format is going to be officially announced in a 2024 release of MITK, the file format must be considered experimental and is prone to change without any prior warning. + ## Overview -MITK ROIs are a JSON-based file format defining a list of region of interests (ROIs). +MITK ROI is a JSON-based file format defining a collection of region of interests (ROIs). + +ROIs must have an ID (unsigned integer) and their shape is currently considered to be an axis-aligned bounding box. +Its bounds are defined by minimum and maximum index coordinates, typically relative to an image. +Custom properties of various known types can be optionally attached to a ROI. +A few of these properties are used by MITK to define the appearance of a rendered ROI, for example: + + - "color" (mitk::ColorProperty): Color/RGB triplet of the rendered ROI (default: white \[1.0, 1.0, 1.0\]) + - "opacity" (mitk::FloatProperty): Opacity of the rendered ROI (default: 100% \[1.0\]) + - "lineWidth" (mitk::FloatProperty): Line width of the egdes of the rendered ROI (default: 1px \[1.0\]) + +ROIs can be optionally time-resolved and define both coordinates and properties per time step, allowing for a dynamic appearance, position, and size over time. -MITK ROIs must be considered experimental at the moment and are prone to change without any prior warning. +ROIs also display a caption at their bottom-left corner (supporting multiple lines), that can be set once per MITK ROI file for all contained ROIs. +Placeholders enclosed by braces in the caption are substituted by their corresponding ROI property values at runtime. +The default caption is "{name} ({ID})", where ``{ID}`` is a special placeholder for the ID of a ROI (technically not a ROI property), and ``{name}`` refers to the ROI property "name" (typically an mitk::StringProperty). + +Last but not least the reference (image) geometry of the ROIs in an MITK ROI file must be specified to be able to map all index coordinates to actual world coordinates. +A geometry is defined by an origin, the pixel/voxel spacing, a size, and optionally the number of time steps in case of a time-resolved MITK ROI file. ## File format -MITK ROIs are JSON files containing a JSON object as root, which must contain the two mandatory properties `FileFormat` and `Version`: +As all features are explained in the overview above, the JSON-based file format is defined here by two examples with minimal additional notes: one example for a static MITK ROI file and one example for a time-resolved MITK ROI file. + +### Static MITK ROI file + +This example contains two ROIs for detected tumors in an image with certain confidence. +Names and confidence values will be displayed in separate lines for each ROI. + +~~~{.json} +{ + "FileFormat": "MITK ROI", + "Version": 1, + "Name": "Static example", + "Caption": "{name}\nConfidence: {confidence}", + "Geometry": { + "Origin": [0, 0, 0], + "Spacing": [1, 1, 3], + "Size": [256, 256, 49] + }, + "ROIs": [ + { + "ID": 0, + "Min": [4, 4, 1], + "Max": [124, 124, 31], + "Properties": { + "StringProperty": { + "name": "tumor", + "comment": "Detected a tumor with 95% confidence.", + "note": "Properties are grouped by their type to reduce verbosity." + }, + "ColorProperty": { + "color": [0, 1, 0] + }, + "FloatProperty": { + "confidence": 0.95 + } + } + }, + { + "ID": 1, + "Min": [132, 4, 1], + "Max": [252, 60, 15], + "Properties": { + "StringProperty": { + "name": "Another tumor", + "comment": "Maybe another tumor (confidence only 25%)." + }, + "ColorProperty": { + "color": [1, 0, 0] + }, + "FloatProperty": { + "confidence": 0.25 + } + } + } + ] +} + +~~~ + +Further hints: + + - "FileFormat" ("MITK ROI"), "Version" (1), and "Geometry" are mandatory. + - "Name" is optional. If not set, the file name is used by MITK instead. + - ROIs are defined by JSON objects in the "ROIs" JSON array. + - See the derived classes of mitk::BaseProperty for an overview of known property types. + +### Time-resolved MITK ROI file + +This example only contains a single ROI but it is defined for several time steps. +Fallbacks of time step properties to default properties are demonstrated as well. ~~~{.json} { "FileFormat": "MITK ROI", - "Version": 1 + "Version": 1, + "Name": "Time-resolved example", + "Geometry": { + "Origin": [0, 0, 0], + "Spacing": [1, 1, 3], + "Size": [256, 256, 49], + "TimeSteps": 3 + }, + "ROIs": [ + { + "ID": 0, + "Properties": { + "ColorProperty": { + "color": [1, 0, 0] + }, + "StringProperty": { + "name": "Color-changing ROI" + } + }, + "TimeSteps": [ + { + "t": 0, + "Min": [4, 4, 1], + "Max": [124, 124, 31] + }, + { + "t": 2, + "Min": [14, 14, 11], + "Max": [121, 121, 28], + "Properties": { + "ColorProperty": { + "color": [0, 1, 0] + } + } + } + ] + } + ] } ~~~ -### ROIs +Further hints: -... + - The geometry defines 3 time steps. + - The "Properties" directly in the ROI function as fallbacks, if they are not defined for a certain time step. + - Time time step indices "t" are mandatory. The ROI is only present at time steps 0 and 2. + - The ROI is red (fallback) at time step 0 and green at time step 2. + - Its extents are larger at time step 0 than at time step 2. diff --git a/Modules/ROI/include/mitkROI.h b/Modules/ROI/include/mitkROI.h index 5546f6100f..ab1ee0464c 100644 --- a/Modules/ROI/include/mitkROI.h +++ b/Modules/ROI/include/mitkROI.h @@ -1,195 +1,195 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkROI_h #define mitkROI_h #include #include namespace mitk { /** \brief A collection of region of interests (ROIs). * * ROIs, essentially defined by the minimum and maximum index coordinates of an axis-aligned box, are * represented by the nested ROI::Element class. These index coordinates are relative to a common * TimeGeometry. * * All ROIs are required to have a unique ID by which they can be accessed. * * ROIs can optionally have properties (PropertyList), also called default properties. In case of * time-resolved ROIs, each time step can optionally have properties, too. These properties have * precedence over the default properties. In other words, the default properties may contain * fallback properties which are queried when a property is not defined at a certain time step. * This allows for an opt-in dynamic appearance of ROIs over time, for example by changing * color or opacity. * * ROIs are rendered both in 3-d and 2-d views as cubes, resp. cutting slices of these cubes. * They support the following ROI::Element properties: * * - \c color (ColorProperty): Color of the cube * - \c opacity (FloatProperty): Opacity of the cube * - \c lineWidth (FloatProperty): %Line width of the cube edges * * ROIs display a customizable caption at their bottom-left corner. It is defined by the base data * property \c caption (StringProperty). By default it is set to "{name} ({ID})". Braces * are used to define placeholders which are replaced by their corresponding ROI::Element properties. * {ID} is a special placeholder which will be replaced by the ID of the ROI::Element instead. * The caption is allowed to include line breaks. Rendering of captions can be customized through the * following data node properties: * * - \c font.size (IntProperty) Font size in points * - \c font.bold (BoolProperty) Bold font style * - \c font.italic (BoolProperty) Italic font style * - * See \ref MITKROIsPage for details on the JSON-based MITK %ROI file format. + * See \ref MITKROIPage for details on the JSON-based MITK %ROI file format. */ class MITKROI_EXPORT ROI : public BaseData { public: /** \brief Encapsulates a single (possibly time-resolved) %ROI. * * \sa ROI */ class MITKROI_EXPORT Element : public IPropertyOwner { public: using PointsType = std::map; using PropertyListsType = std::map; Element(); explicit Element(unsigned int id); ~Element() = default; /** \brief Get a const property. * * \note A time step can be specified as context. Use \c std::to_string() to convert a time step to a context name. * An empty context name addresses the default properties. */ BaseProperty::ConstPointer GetConstProperty(const std::string& propertyKey, const std::string& contextName = "", bool fallBackOnDefaultContext = true) const override; /** \brief Get all property keys. * * \note A time step can be specified as context. Use \c std::to_string() to convert a time step to a context name. * An empty context name addresses the default properties. */ std::vector GetPropertyKeys(const std::string& contextName = "", bool includeDefaultContext = false) const override; /** \brief Get all property context names (stringified time steps). */ std::vector GetPropertyContextNames() const override; /** \brief Get a property. * * \note A time step can be specified as context. Use \c std::to_string() to convert a time step to a context name. * An empty context name addresses the default properties. */ BaseProperty* GetNonConstProperty(const std::string& propertyKey, const std::string& contextName = "", bool fallBackOnDefaultContext = true) override; /** \brief Set a property. * * \note A time step can be specified as context. Use \c std::to_string() to convert a time step to a context name. * An empty context name addresses the default properties. */ void SetProperty(const std::string& propertyKey, BaseProperty* property, const std::string& contextName = "", bool fallBackOnDefaultContext = false) override; /** \brief Remove a property. * * \note A time step can be specified as context. Use \c std::to_string() to convert a time step to a context name. * An empty context name addresses the default properties. */ void RemoveProperty(const std::string& propertyKey, const std::string& contextName = "", bool fallBackOnDefaultContext = false) override; unsigned int GetID() const; void SetID(unsigned int id); /** \brief Check if the %ROI is defined for a certain time step. */ bool HasTimeStep(TimeStepType t) const; /** \brief Check if the %ROI can be considered time-resolved. */ bool HasTimeSteps() const; /** \brief Get all valid time steps that have a minimum point and a maximum point. */ std::vector GetTimeSteps() const; Point3D GetMin(TimeStepType t = 0) const; void SetMin(const Point3D& min, TimeStepType t = 0); Point3D GetMax(TimeStepType t = 0) const; void SetMax(const Point3D& max, TimeStepType t = 0); PropertyList* GetDefaultProperties() const; void SetDefaultProperties(PropertyList* properties); /** \brief Get properties for a certain time step or \c nullptr if absent. */ PropertyList* GetProperties(TimeStepType t = 0) const; void SetProperties(PropertyList* properties, TimeStepType t = 0); private: unsigned int m_ID; PointsType m_Min; PointsType m_Max; PropertyList::Pointer m_DefaultProperties; PropertyListsType m_Properties; }; mitkClassMacro(ROI, BaseData) itkFactorylessNewMacro(Self) itkCloneMacro(Self) using ElementsType = std::map; using Iterator = ElementsType::iterator; using ConstIterator = ElementsType::const_iterator; size_t GetNumberOfElements() const; /** \brief Add a ROI::Element to the collection. * * \note The ID of the ROI::Element must be set to a unique number in advance. */ void AddElement(const Element& element); const Element& GetElement(unsigned int id) const; Element& GetElement(unsigned int id); ConstIterator begin() const; ConstIterator end() const; Iterator begin(); Iterator end(); void SetRequestedRegionToLargestPossibleRegion() override; bool RequestedRegionIsOutsideOfTheBufferedRegion() override; bool VerifyRequestedRegion() override; void SetRequestedRegion(const itk::DataObject* data) override; protected: mitkCloneMacro(Self) ROI(); ROI(const Self& other); ~ROI() override; private: ElementsType m_Elements; }; MITKROI_EXPORT void to_json(nlohmann::json& j, const ROI::Element& roi); MITKROI_EXPORT void from_json(const nlohmann::json& j, ROI::Element& roi); } #endif