2023 Week 48 (Very Late November)
The following - possibly updated - changelog can be viewed as formatted
article at https://phabricator.mitk.org/w/mitk/changelog/2023.48/.
🛠 Third-party dependency changes
none
✨ New features
- Build system
- MITK is now compatible with the latest version 17.8 of Visual Studio 2022
🐛 Bugfixes
- Segmentation
- Fixed several crashes in some edge cases of segmentation group handling
- Made message boxes for segmentation group deletion more clear and explicit
- Segment Anything segmentation tool now works for all view directions of a 2-d images
- Point set interaction
- Fixed selection glitch of points in close proximity to other points
- Image statistics
- Fixed potential crash with line profiles based on open planar figures exceeding the bounds of an image
- DICOM inspector
- Fixed initial data selection glitch
🔥 API-breaking changes
Properties
We added two pure virtual methods to the mitk::BaseProperty class for JSON serialization, that must be implemented in all derived classes:
- bool ToJSON(nlohmann::json& j) const
- bool FromJSON(const nlohmann::json& j)
See the documentation of these methods for important implementation hints.
You find plenty of example impementations in our code base for all existing property classes. Here is the implementation for mitk::StringProperty:
bool mitk::StringProperty::ToJSON(nlohmann::json& j) const { j = this->GetValueAsString(); return true; } bool mitk::StringProperty::FromJSON(const nlohmann::json& j) { this->SetValue(j.get<std::string>()); return true; }
If you have more complex types (that can be default-constructed) you certainly want to utilize the arbitrary type conversions feature of the JSON for Modern C++ library by implementing all the (de)serialization logic in void to_json(nlohmann::json& j, const <my_type>&) and void from_json(const nlohmann::json& j, <my_type>&) functions, located in the same namespace as your type.
This reduces the implementation of the mitk::BaseProperty methods mentioned above to the same two-liners as shown in the example for mitk::StringProperty. Here is the implementation for itk::RGBPixel<>, which is used as value type in mitk::ColorProperty (typedef itk::RGBPixel<float> Color):
namespace itk { template <typename TComponent> void to_json(nlohmann::json& j, const RGBPixel<TComponent>& c) { j = nlohmann::json::array(); for (size_t i = 0; i < 3; ++i) j.push_back(c[i]); } template <typename TComponent> void from_json(const nlohmann::json& j, RGBPixel<TComponent>& c) { for (size_t i = 0; i < 3; ++i) j.at(i).get_to(c[i]); } }
Now, the JSON (de)serialization implementation of mitk::ColorProperty boils down to:
bool mitk::ColorProperty::ToJSON(nlohmann::json& j) const { j = this->GetColor(); return true; } bool mitk::ColorProperty::FromJSON(const nlohmann::json& j) { this->SetColor(j.get<Color>()); return true; }
mitk::PropertyList deserialization
Property lists can now be (de)serialized in JSON format as well.
However, the deserialization needs to know upfront which property type is tied to the type names found in the JSON representation.
In addition to the To/FromJSON() method implementations mentioned above, you also need to register your property type for that purpose with the mitk::IPropertyDeserialization core service:
mitk::CoreServicePointer<mitk::IPropertyDeserialization> service(mitk::CoreServices::GetPropertyDeserialization()); service->RegisterProperty<MyPropertyType>();