diff --git a/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.cpp b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.cpp index 18ffe63533..b9e9fba8ea 100644 --- a/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.cpp +++ b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.cpp @@ -1,224 +1,224 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkMultiLabelSegmentationIO.h" #include "mitkBasePropertySerializer.h" #include "mitkIOMimeTypes.h" #include "mitkImageAccessByItk.h" #include "mitkMultiLabelIOHelper.h" #include "mitkLabelSetImageConverter.h" #include #include #include #include #include #include // itk #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkMetaDataDictionary.h" #include "itkMetaDataObject.h" #include "itkNrrdImageIO.h" #include namespace mitk { const constexpr char* const MULTILABEL_SEGMENTATION_MODALITY_KEY = "modality"; const constexpr char* const MULTILABEL_SEGMENTATION_MODALITY_VALUE = "org.mitk.multilabel.segmentation"; const constexpr char* const MULTILABEL_SEGMENTATION_VERSION_KEY = "org.mitk.multilabel.segmentation.version"; const constexpr int MULTILABEL_SEGMENTATION_VERSION_VALUE = 1; const constexpr char* const MULTILABEL_SEGMENTATION_LABELS_INFO_KEY = "org.mitk.multilabel.segmentation.labelgroups"; const constexpr char* const MULTILABEL_SEGMENTATION_UNLABELEDLABEL_LOCK_KEY = "org.mitk.multilabel.segmentation.unlabeledlabellock"; MultiLabelSegmentationIO::MultiLabelSegmentationIO() : AbstractFileIO(LabelSetImage::GetStaticNameOfClass(), IOMimeTypes::NRRD_MIMETYPE(), "MITK Multilabel Segmentation") { this->InitializeDefaultMetaDataKeys(); AbstractFileWriter::SetRanking(10); AbstractFileReader::SetRanking(10); this->RegisterService(); } IFileIO::ConfidenceLevel MultiLabelSegmentationIO::GetWriterConfidenceLevel() const { if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; const auto *input = static_cast(this->GetInput()); if (input) return Supported; else return Unsupported; } void MultiLabelSegmentationIO::Write() { ValidateOutputLocation(); auto input = dynamic_cast(this->GetInput()); mitk::LocaleSwitch localeSwitch("C"); mitk::Image::Pointer inputVector = mitk::ConvertLabelSetImageToImage(input); // image write if (inputVector.IsNull()) { mitkThrow() << "Cannot write non-image data"; } itk::NrrdImageIO::Pointer nrrdImageIo = itk::NrrdImageIO::New(); ItkImageIO::PreparImageIOToWriteImage(nrrdImageIo, inputVector); LocalFile localFile(this); const std::string path = localFile.GetFileName(); MITK_INFO << "Writing image: " << path << std::endl; try { itk::EncapsulateMetaData( nrrdImageIo->GetMetaDataDictionary(), std::string(MULTILABEL_SEGMENTATION_MODALITY_KEY), std::string(MULTILABEL_SEGMENTATION_MODALITY_VALUE)); //nrrd does only support string meta information. So we have to convert before. itk::EncapsulateMetaData( nrrdImageIo->GetMetaDataDictionary(), std::string(MULTILABEL_SEGMENTATION_VERSION_KEY), std::to_string(MULTILABEL_SEGMENTATION_VERSION_VALUE)); auto json = MultiLabelIOHelper::SerializeMultLabelGroupsToJSON(input); itk::EncapsulateMetaData( nrrdImageIo->GetMetaDataDictionary(), std::string(MULTILABEL_SEGMENTATION_LABELS_INFO_KEY), json.dump()); // end label set specific meta data //nrrd does only support string meta information. So we have to convert before. itk::EncapsulateMetaData( nrrdImageIo->GetMetaDataDictionary(), std::string(MULTILABEL_SEGMENTATION_UNLABELEDLABEL_LOCK_KEY), std::to_string(input->GetUnlabeledLabelLock())); // Handle properties ItkImageIO::SavePropertyListAsMetaData(nrrdImageIo->GetMetaDataDictionary(), input->GetPropertyList(), this->GetMimeType()->GetName()); // Handle UID itk::EncapsulateMetaData(nrrdImageIo->GetMetaDataDictionary(), PROPERTY_KEY_UID, input->GetUID()); // use compression if available nrrdImageIo->UseCompressionOn(); nrrdImageIo->SetFileName(path); ImageReadAccessor imageAccess(inputVector); nrrdImageIo->Write(imageAccess.GetData()); } catch (const std::exception &e) { mitkThrow() << e.what(); } } IFileIO::ConfidenceLevel MultiLabelSegmentationIO::GetReaderConfidenceLevel() const { if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; const std::string fileName = this->GetLocalFileName(); itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileName(fileName); io->ReadImageInformation(); itk::MetaDataDictionary imgMetaDataDictionary = io->GetMetaDataDictionary(); std::string value(""); itk::ExposeMetaData(imgMetaDataDictionary, "modality", value); if (value.compare(MULTILABEL_SEGMENTATION_MODALITY_VALUE) == 0) { return Supported; } else return Unsupported; } std::vector MultiLabelSegmentationIO::DoRead() { itk::NrrdImageIO::Pointer nrrdImageIO = itk::NrrdImageIO::New(); std::vector result; auto rawimage = ItkImageIO::LoadRawMitkImageFromImageIO(nrrdImageIO, this->GetLocalFileName()); const itk::MetaDataDictionary& dictionary = nrrdImageIO->GetMetaDataDictionary(); //check version auto version = MultiLabelIOHelper::GetIntByKey(dictionary, MULTILABEL_SEGMENTATION_VERSION_KEY); if (version > MULTILABEL_SEGMENTATION_VERSION_VALUE) { mitkThrow() << "Data to read has unsupported version. Software is to old to ensure correct reading. Please use a compatible version of MITK or store data in another format. Version of data: " << version << "; Supported versions up to: "< labelsets = MultiLabelIOHelper::DeserializeMultLabelGroupsFromJSON(jlabelsets); + std::vector labelsets = MultiLabelIOHelper::DeserializeMultiLabelGroupsFromJSON(jlabelsets); if (labelsets.size() != output->GetNumberOfLayers()) { mitkThrow() << "Loaded data is in an invalid state. Number of extracted layer images and labels sets does not match. Found layer images: " << output->GetNumberOfLayers() << "; found labelsets: " << labelsets.size(); } LabelSetImage::GroupIndexType id = 0; for (auto labelset : labelsets) { output->AddLabelSetToLayer(id, labelset); id++; } bool unlabeledLock = MultiLabelIOHelper::GetIntByKey(dictionary, MULTILABEL_SEGMENTATION_UNLABELEDLABEL_LOCK_KEY) != 0; output->SetUnlabeledLabelLock(unlabeledLock); //meta data handling auto props = ItkImageIO::ExtractMetaDataAsPropertyList(nrrdImageIO->GetMetaDataDictionary(), this->GetMimeType()->GetName(), this->m_DefaultMetaDataKeys); for (auto& [name, prop] : *(props->GetMap())) { output->SetProperty(name, prop->Clone()); //need to clone to avoid that all outputs pointing to the same prop instances. } // Handle UID if (dictionary.HasKey(PROPERTY_KEY_UID)) { itk::MetaDataObject::ConstPointer uidData = dynamic_cast*>(dictionary.Get(PROPERTY_KEY_UID)); if (uidData.IsNotNull()) { mitk::UIDManipulator uidManipulator(output); uidManipulator.SetUID(uidData->GetMetaDataObjectValue()); } } result.push_back(output.GetPointer()); MITK_INFO << "...finished!"; return result; } MultiLabelSegmentationIO *MultiLabelSegmentationIO::IOClone() const { return new MultiLabelSegmentationIO(*this); } void MultiLabelSegmentationIO::InitializeDefaultMetaDataKeys() { this->m_DefaultMetaDataKeys.push_back("NRRD.space"); this->m_DefaultMetaDataKeys.push_back("NRRD.kinds"); this->m_DefaultMetaDataKeys.push_back(PROPERTY_NAME_TIMEGEOMETRY_TYPE); this->m_DefaultMetaDataKeys.push_back(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS); this->m_DefaultMetaDataKeys.push_back("ITK.InputFilterName"); this->m_DefaultMetaDataKeys.push_back("org.mitk.multilabel."); this->m_DefaultMetaDataKeys.push_back("MITK.IO."); this->m_DefaultMetaDataKeys.push_back(MULTILABEL_SEGMENTATION_MODALITY_KEY); } } // namespace diff --git a/Modules/Multilabel/mitkMultiLabelIOHelper.cpp b/Modules/Multilabel/mitkMultiLabelIOHelper.cpp index 407e89fa40..a95c6d11e8 100644 --- a/Modules/Multilabel/mitkMultiLabelIOHelper.cpp +++ b/Modules/Multilabel/mitkMultiLabelIOHelper.cpp @@ -1,435 +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. ============================================================================*/ #include "mitkMultiLabelIOHelper.h" #include "mitkLabelSetImage.h" #include #include "itkMetaDataDictionary.h" #include "itkMetaDataObject.h" #include namespace { std::string EnsureExtension(const std::string& filename) { const std::string extension = ".lsetp"; if (filename.size() < extension.size() || std::string::npos == filename.find(extension, filename.size() - extension.size())) return filename + extension; return filename; } } bool mitk::MultiLabelIOHelper::SaveLabelSetImagePreset(const std::string &presetFilename, const mitk::LabelSetImage *inputImage) { const auto filename = EnsureExtension(presetFilename); tinyxml2::XMLDocument xmlDocument; xmlDocument.InsertEndChild(xmlDocument.NewDeclaration()); auto *rootElement = xmlDocument.NewElement("LabelSetImagePreset"); rootElement->SetAttribute("layers", inputImage->GetNumberOfLayers()); xmlDocument.InsertEndChild(rootElement); for (unsigned int layerIndex = 0; layerIndex < inputImage->GetNumberOfLayers(); layerIndex++) { auto *layerElement = xmlDocument.NewElement("Layer"); layerElement->SetAttribute("index", layerIndex); layerElement->SetAttribute("labels", inputImage->GetNumberOfLabels(layerIndex)); rootElement->InsertEndChild(layerElement); for (unsigned int labelIndex = 0; labelIndex < inputImage->GetNumberOfLabels(layerIndex); labelIndex++) layerElement->InsertEndChild(MultiLabelIOHelper::GetLabelAsXMLElement(xmlDocument, inputImage->GetLabel(labelIndex, layerIndex))); } return tinyxml2::XML_SUCCESS == xmlDocument.SaveFile(filename.c_str()); } bool mitk::MultiLabelIOHelper::LoadLabelSetImagePreset(const std::string &presetFilename, mitk::LabelSetImage *inputImage) { if (nullptr == inputImage) return false; const auto filename = EnsureExtension(presetFilename); tinyxml2::XMLDocument xmlDocument; if (tinyxml2::XML_SUCCESS != xmlDocument.LoadFile(filename.c_str())) { MITK_WARN << "Label set preset file \"" << filename << "\" does not exist or cannot be opened"; return false; } auto *rootElement = xmlDocument.FirstChildElement("LabelSetImagePreset"); if (nullptr == rootElement) { MITK_WARN << "Not a valid Label set preset"; return false; } auto activeLayerBackup = inputImage->GetActiveLayer(); int numberOfLayers = 0; rootElement->QueryIntAttribute("layers", &numberOfLayers); auto* layerElement = rootElement->FirstChildElement("Layer"); if (nullptr == layerElement) { MITK_WARN << "Label set preset does not contain any layers"; return false; } for (int layerIndex = 0; layerIndex < numberOfLayers; layerIndex++) { int numberOfLabels = 0; layerElement->QueryIntAttribute("labels", &numberOfLabels); if (nullptr == inputImage->GetLabelSet(layerIndex)) { inputImage->AddLayer(); } else { inputImage->SetActiveLayer(layerIndex); } auto *labelElement = layerElement->FirstChildElement("Label"); if (nullptr == labelElement) continue; for (int labelIndex = 0; labelIndex < numberOfLabels; labelIndex++) { auto label = mitk::MultiLabelIOHelper::LoadLabelFromXMLDocument(labelElement); const auto labelValue = label->GetValue(); if (LabelSetImage::UnlabeledLabelValue != labelValue) { auto* labelSet = inputImage->GetLabelSet(layerIndex); auto* alreadyExistingLabel = labelSet->GetLabel(labelValue); if (nullptr != alreadyExistingLabel) { // Override existing label with label from preset alreadyExistingLabel->ConcatenatePropertyList(label); labelSet->UpdateLookupTable(labelValue); } else { labelSet->AddLabel(label); } } labelElement = labelElement->NextSiblingElement("Label"); if (nullptr == labelElement) continue; } layerElement = layerElement->NextSiblingElement("Layer"); if (nullptr == layerElement) continue; } inputImage->SetActiveLayer(activeLayerBackup); return true; } tinyxml2::XMLElement *mitk::MultiLabelIOHelper::GetLabelAsXMLElement(tinyxml2::XMLDocument &doc, Label *label) { auto *labelElem = doc.NewElement("Label"); if (nullptr != label) { // add XML contents const PropertyList::PropertyMap* propmap = label->GetMap(); for (auto iter = propmap->begin(); iter != propmap->end(); ++iter) { std::string key = iter->first; const BaseProperty* property = iter->second; auto* element = PropertyToXMLElement(doc, key, property); if (element) labelElem->InsertEndChild(element); } } return labelElem; } mitk::Label::Pointer mitk::MultiLabelIOHelper::LoadLabelFromXMLDocument(const tinyxml2::XMLElement *labelElem) { // reread auto *propElem = labelElem->FirstChildElement("property"); std::string name; mitk::BaseProperty::Pointer prop; mitk::Label::Pointer label = mitk::Label::New(); while (propElem) { MultiLabelIOHelper::PropertyFromXMLElement(name, prop, propElem); label->SetProperty(name, prop); propElem = propElem->NextSiblingElement("property"); } return label.GetPointer(); } tinyxml2::XMLElement *mitk::MultiLabelIOHelper::PropertyToXMLElement(tinyxml2::XMLDocument &doc, const std::string &key, const BaseProperty *property) { auto *keyelement = doc.NewElement("property"); keyelement->SetAttribute("key", key.c_str()); keyelement->SetAttribute("type", property->GetNameOfClass()); // construct name of serializer class std::string serializername(property->GetNameOfClass()); serializername += "Serializer"; std::list allSerializers = itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str()); if (allSerializers.size() < 1) MITK_ERROR << "No serializer found for " << property->GetNameOfClass() << ". Skipping object"; if (allSerializers.size() > 1) MITK_WARN << "Multiple serializers found for " << property->GetNameOfClass() << "Using arbitrarily the first one."; for (auto iter = allSerializers.begin(); iter != allSerializers.end(); ++iter) { if (auto *serializer = dynamic_cast(iter->GetPointer())) { serializer->SetProperty(property); try { auto *valueelement = serializer->Serialize(doc); if (valueelement) keyelement->InsertEndChild(valueelement); } catch (std::exception &e) { MITK_ERROR << "Serializer " << serializer->GetNameOfClass() << " failed: " << e.what(); } break; } } return keyelement; } bool mitk::MultiLabelIOHelper::PropertyFromXMLElement(std::string &key, mitk::BaseProperty::Pointer &prop, const tinyxml2::XMLElement *elem) { const char* typeC = elem->Attribute("type"); std::string type = nullptr != typeC ? typeC : ""; const char* keyC = elem->Attribute("key"); key = nullptr != keyC ? keyC : ""; // construct name of serializer class std::string serializername(type); serializername += "Serializer"; std::list allSerializers = itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str()); if (allSerializers.size() < 1) MITK_ERROR << "No serializer found for " << type << ". Skipping object"; if (allSerializers.size() > 1) MITK_WARN << "Multiple deserializers found for " << type << "Using arbitrarily the first one."; for (auto iter = allSerializers.begin(); iter != allSerializers.end(); ++iter) { if (auto *serializer = dynamic_cast(iter->GetPointer())) { try { prop = serializer->Deserialize(elem->FirstChildElement()); } catch (std::exception &e) { MITK_ERROR << "Deserializer " << serializer->GetNameOfClass() << " failed: " << e.what(); return false; } break; } } if (prop.IsNull()) return false; return true; } int mitk::MultiLabelIOHelper::GetIntByKey(const itk::MetaDataDictionary& dic, const std::string& str) { std::vector imgMetaKeys = dic.GetKeys(); std::vector::const_iterator itKey = imgMetaKeys.begin(); std::string metaString(""); for (; itKey != imgMetaKeys.end(); itKey++) { itk::ExposeMetaData(dic, *itKey, metaString); if (itKey->find(str.c_str()) != std::string::npos) { return atoi(metaString.c_str()); } } return 0; } std::string mitk::MultiLabelIOHelper::GetStringByKey(const itk::MetaDataDictionary& dic, const std::string& str) { std::vector imgMetaKeys = dic.GetKeys(); std::vector::const_iterator itKey = imgMetaKeys.begin(); std::string metaString(""); for (; itKey != imgMetaKeys.end(); itKey++) { itk::ExposeMetaData(dic, *itKey, metaString); if (itKey->find(str.c_str()) != std::string::npos) { return metaString; } } return metaString; } nlohmann::json mitk::MultiLabelIOHelper::SerializeMultLabelGroupsToJSON(const mitk::LabelSetImage* inputImage) { if (nullptr == inputImage) { mitkThrow() << "Invalid call of SerializeMultLabelGroupsToJSON. Passed image pointer is null."; } nlohmann::json result; for (LabelSetImage::GroupIndexType i = 0; i < inputImage->GetNumberOfLayers(); i++) { nlohmann::json jgroup; + nlohmann::json jlabels; + for (const auto& label : inputImage->GetLabelsInGroup(i)) { - jgroup.emplace_back(SerializeLabelToJSON(label)); + jlabels.emplace_back(SerializeLabelToJSON(label)); } + jgroup["labels"] = jlabels; result.emplace_back(jgroup); } return result; }; -std::vector mitk::MultiLabelIOHelper::DeserializeMultLabelGroupsFromJSON(const nlohmann::json& listOfLabelSets) +std::vector mitk::MultiLabelIOHelper::DeserializeMultiLabelGroupsFromJSON(const nlohmann::json& listOfLabelSets) { std::vector result; - for (const auto& jlabelsets : listOfLabelSets) + for (const auto& jlabelset : listOfLabelSets) { LabelSet::Pointer labelSet = LabelSet::New(); - for (const auto& jlabel : jlabelsets) + if (jlabelset.find("labels") != jlabelset.end()) { - auto label = DeserializeLabelFromJSON(jlabel); - labelSet->AddLabel(label, false); - } + auto jlabels = jlabelset["labels"]; + for (const auto& jlabel : jlabels) + { + auto label = DeserializeLabelFromJSON(jlabel); + labelSet->AddLabel(label, false); + } + } result.emplace_back(labelSet); } return result; } nlohmann::json mitk::MultiLabelIOHelper::SerializeLabelToJSON(const Label* label) { if (nullptr == label) { mitkThrow() << "Invalid call of GetLabelAsJSON. Passed label pointer is null."; } nlohmann::json j; j["name"] = label->GetName(); j["value"] = label->GetValue(); nlohmann::json jcolor; jcolor["type"] = "ColorProperty"; jcolor["value"] = {label->GetColor().GetRed(), label->GetColor().GetGreen(), label->GetColor().GetBlue() }; j["color"] = jcolor; j["locked"] = label->GetLocked(); j["opacity"] = label->GetOpacity(); j["visible"] = label->GetVisible(); return j; }; template bool GetValueFromJson(const nlohmann::json& labelJson, const std::string& key, TValueType& value) { if (labelJson.find(key) != labelJson.end()) { try { value = labelJson[key].get(); return true; } catch (...) { MITK_ERROR << "Unable to read label information from json. Value has wrong type. Failed key: " << key << "; invalid value: " << labelJson[key].dump(); throw; } } return false; } mitk::Label::Pointer mitk::MultiLabelIOHelper::DeserializeLabelFromJSON(const nlohmann::json& labelJson) { Label::Pointer resultLabel = Label::New(); std::string name = "Unkown label name"; GetValueFromJson(labelJson, "name", name); resultLabel->SetName(name); Label::PixelType value = 1; GetValueFromJson(labelJson, "value", value); resultLabel->SetValue(value); if (labelJson.find("color") != labelJson.end()) { auto jcolor = labelJson["color"]["value"]; Color color; color.SetRed(jcolor[0].get()); color.SetGreen(jcolor[1].get()); color.SetBlue(jcolor[2].get()); resultLabel->SetColor(color); } bool locked = false; if (GetValueFromJson(labelJson, "locked", locked)) resultLabel->SetLocked(locked); float opacity = 1.; if (GetValueFromJson(labelJson, "opacity", opacity)) resultLabel->SetOpacity(opacity); bool visible = true; if (GetValueFromJson(labelJson, "visible", visible)) resultLabel->SetVisible(visible); return resultLabel; } diff --git a/Modules/Multilabel/mitkMultiLabelIOHelper.h b/Modules/Multilabel/mitkMultiLabelIOHelper.h index c13f5cbfca..a30e22787e 100644 --- a/Modules/Multilabel/mitkMultiLabelIOHelper.h +++ b/Modules/Multilabel/mitkMultiLabelIOHelper.h @@ -1,127 +1,127 @@ /*============================================================================ 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 mitkMultiLabelIOHelper_h #define mitkMultiLabelIOHelper_h #include #include #include #include namespace tinyxml2 { class XMLDocument; class XMLElement; } namespace itk { class MetaDataDictionary; } namespace mitk { class LabelSetImage; const constexpr char* const PROPERTY_NAME_TIMEGEOMETRY_TYPE = "org.mitk.timegeometry.type"; const constexpr char* const PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS = "org.mitk.timegeometry.timepoints"; const constexpr char* const PROPERTY_KEY_TIMEGEOMETRY_TYPE = "org_mitk_timegeometry_type"; const constexpr char* const PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS = "org_mitk_timegeometry_timepoints"; const constexpr char* const PROPERTY_KEY_UID = "org_mitk_uid"; /** * @brief The MultiLabelIOHelper is a static helper class that supports serialization of mitk::LabelSetImage * * This class provides static functions for converting mitk::Label into XML and also allows the serialization * of mitk::LabelSet as presets */ class MITKMULTILABEL_EXPORT MultiLabelIOHelper { public: /** * @brief Saves the mitk::LabelSet configuration of inputImage to presetFilename. * The preset is stored as "*.lsetp" * @param presetFilename the filename including the filesystem path * @param inputImage the input image from which the preset should be generated * @return true if the serialization was successful and false otherwise */ static bool SaveLabelSetImagePreset(const std::string &presetFilename, const mitk::LabelSetImage *inputImage); /** * @brief Loads an existing preset for a mitk::LabelSetImage from presetFilename and applies it to inputImage * @param presetFilename the filename of the preset including the filesystem path * @param inputImage the image to which the loaded preset will be applied * @return true if the deserilization was successful and false otherwise */ static bool LoadLabelSetImagePreset(const std::string &presetFilename, mitk::LabelSetImage *inputImage); /** * @brief Creates a mitk::Label from an XML element * @param labelElem the xml element from which a mitk::Label will be created * @return the created mitk::Label */ static itk::SmartPointer LoadLabelFromXMLDocument(const tinyxml2::XMLElement *labelElem); /** * @brief Creates an XML element from a mitk::Label * @param doc * @param label the mitk::Label from which the xml element will be created * @return the created XML element */ static tinyxml2::XMLElement *GetLabelAsXMLElement(tinyxml2::XMLDocument &doc, Label *label); /** * @brief Since a mitk::Label is basically a mitk::PropertyList this function coverts the label's properties into * XML * @param doc * @param key the property's key which will be used in the XML element * @param property the mitk::BaseProperty that should be converted * @return the created XML element */ static tinyxml2::XMLElement *PropertyToXMLElement(tinyxml2::XMLDocument& doc, const std::string &key, const BaseProperty *property); /** * @brief Since a mitk::Label is basically a mitk::PropertyList this function coverts a XML element into a property * @param key the property's key * @param prop the mitk::BaseProperty that will be created * @param elem the XML elem from which the property will be created * @return true if the conversion was successful and false otherwise */ static bool PropertyFromXMLElement(std::string &key, itk::SmartPointer &prop, const tinyxml2::XMLElement *elem); /** Helper that extracts the value of a key in a meta dictionary as int. * If the key does not exist 0 is returned.*/ static int GetIntByKey(const itk::MetaDataDictionary& dic, const std::string& key); /** Helper that extracts the value of a key in a meta dictionary as string. * If the key does not exist an empty string is returned.*/ static std::string GetStringByKey(const itk::MetaDataDictionary& dic, const std::string& key); static nlohmann::json SerializeMultLabelGroupsToJSON(const mitk::LabelSetImage* inputImage); - static std::vector DeserializeMultLabelGroupsFromJSON(const nlohmann::json& listOfLabelSets); + static std::vector DeserializeMultiLabelGroupsFromJSON(const nlohmann::json& listOfLabelSets); static nlohmann::json SerializeLabelToJSON(const Label* label); static mitk::Label::Pointer DeserializeLabelFromJSON(const nlohmann::json& labelJson); private: MultiLabelIOHelper(); }; } #endif