Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkLabelSetIOHelper.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkLabelSetIOHelper.h"
18 
19 #include "mitkLabelSetImage.h"
21 #include <tinyxml.h>
22 
23 bool mitk::LabelSetIOHelper::SaveLabelSetImagePreset(std::string &presetFilename,
24  mitk::LabelSetImage::Pointer &inputImage)
25 {
26  if (presetFilename.find(".lsetp") == std::string::npos)
27  {
28  presetFilename.append(".lsetp");
29  }
30 
31  TiXmlDocument *presetXmlDoc = new TiXmlDocument();
32 
33  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", "");
34  presetXmlDoc->LinkEndChild(decl);
35 
36  TiXmlElement *presetElement = new TiXmlElement("LabelSetImagePreset");
37  presetElement->SetAttribute("layers", inputImage->GetNumberOfLayers());
38 
39  presetXmlDoc->LinkEndChild(presetElement);
40 
41  for (unsigned int layerIdx = 0; layerIdx < inputImage->GetNumberOfLayers(); layerIdx++)
42  {
43  TiXmlElement *layerElement = new TiXmlElement("Layer");
44  layerElement->SetAttribute("index", layerIdx);
45  layerElement->SetAttribute("labels", inputImage->GetNumberOfLabels(layerIdx));
46 
47  presetElement->LinkEndChild(layerElement);
48 
49  for (unsigned int labelIdx = 0; labelIdx < inputImage->GetNumberOfLabels(layerIdx); labelIdx++)
50  {
51  TiXmlElement *labelAsXml = LabelSetIOHelper::GetLabelAsTiXmlElement(inputImage->GetLabel(labelIdx, layerIdx));
52  layerElement->LinkEndChild(labelAsXml);
53  }
54  }
55 
56  bool wasSaved = presetXmlDoc->SaveFile(presetFilename);
57  delete presetXmlDoc;
58 
59  return wasSaved;
60 }
61 
62 void mitk::LabelSetIOHelper::LoadLabelSetImagePreset(std::string &presetFilename,
63  mitk::LabelSetImage::Pointer &inputImage)
64 {
65  if (presetFilename.find(".lsetp") == std::string::npos)
66  {
67  presetFilename.append(".lsetp");
68  }
69 
70  std::unique_ptr<TiXmlDocument> presetXmlDoc(new TiXmlDocument());
71 
72  bool ok = presetXmlDoc->LoadFile(presetFilename);
73  if (!ok)
74  return;
75 
76  TiXmlElement *presetElem = presetXmlDoc->FirstChildElement("LabelSetImagePreset");
77  if (!presetElem)
78  {
79  MITK_INFO << "No valid preset XML";
80  return;
81  }
82 
83  int numberOfLayers;
84  presetElem->QueryIntAttribute("layers", &numberOfLayers);
85 
86  for (int i = 0; i < numberOfLayers; i++)
87  {
88  TiXmlElement *layerElem = presetElem->FirstChildElement("Layer");
89  int numberOfLabels;
90  layerElem->QueryIntAttribute("labels", &numberOfLabels);
91 
92  if (inputImage->GetLabelSet(i) == NULL)
93  inputImage->AddLayer();
94 
95  TiXmlElement *labelElement = layerElem->FirstChildElement("Label");
96  if (labelElement == NULL)
97  break;
98  for (int j = 0; j < numberOfLabels; j++)
99  {
101 
102  if (label->GetValue() == 0)
103  inputImage->SetExteriorLabel(label);
104  else
105  inputImage->GetLabelSet()->AddLabel(label);
106 
107  labelElement = labelElement->NextSiblingElement("Label");
108  if (labelElement == NULL)
109  break;
110  }
111  }
112 }
113 
115 {
116  TiXmlElement *labelElem = new TiXmlElement("Label");
117 
118  // add XML contents
119  const PropertyList::PropertyMap *propmap = label->GetMap();
120  for (PropertyList::PropertyMap::const_iterator iter = propmap->begin(); iter != propmap->end(); ++iter)
121  {
122  std::string key = iter->first;
123  const BaseProperty *property = iter->second;
124  TiXmlElement *element = PropertyToXmlElem(key, property);
125  if (element)
126  labelElem->LinkEndChild(element);
127  }
128  return labelElem;
129 }
130 
132 {
133  // reread
134  TiXmlElement *propElem = labelElem->FirstChildElement("property");
135 
136  std::string name;
138 
140  while (propElem)
141  {
142  LabelSetIOHelper::PropertyFromXmlElem(name, prop, propElem);
143  label->SetProperty(name, prop);
144  propElem = propElem->NextSiblingElement("property");
145  }
146 
147  return label.GetPointer();
148 }
149 
150 TiXmlElement *mitk::LabelSetIOHelper::PropertyToXmlElem(const std::string &key, const BaseProperty *property)
151 {
152  TiXmlElement *keyelement = new TiXmlElement("property");
153  keyelement->SetAttribute("key", key);
154  keyelement->SetAttribute("type", property->GetNameOfClass());
155 
156  // construct name of serializer class
157  std::string serializername(property->GetNameOfClass());
158  serializername += "Serializer";
159 
160  std::list<itk::LightObject::Pointer> allSerializers =
161  itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str());
162  if (allSerializers.size() < 1)
163  MITK_ERROR << "No serializer found for " << property->GetNameOfClass() << ". Skipping object";
164 
165  if (allSerializers.size() > 1)
166  MITK_WARN << "Multiple serializers found for " << property->GetNameOfClass() << "Using arbitrarily the first one.";
167 
168  for (std::list<itk::LightObject::Pointer>::iterator iter = allSerializers.begin(); iter != allSerializers.end();
169  ++iter)
170  {
171  if (BasePropertySerializer *serializer = dynamic_cast<BasePropertySerializer *>(iter->GetPointer()))
172  {
173  serializer->SetProperty(property);
174  try
175  {
176  TiXmlElement *valueelement = serializer->Serialize();
177  if (valueelement)
178  keyelement->LinkEndChild(valueelement);
179  }
180  catch (std::exception &e)
181  {
182  MITK_ERROR << "Serializer " << serializer->GetNameOfClass() << " failed: " << e.what();
183  }
184  break;
185  }
186  }
187  return keyelement;
188 }
189 
192  TiXmlElement *elem)
193 {
194  std::string type;
195  elem->QueryStringAttribute("type", &type);
196  elem->QueryStringAttribute("key", &key);
197 
198  // construct name of serializer class
199  std::string serializername(type);
200  serializername += "Serializer";
201 
202  std::list<itk::LightObject::Pointer> allSerializers =
203  itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str());
204  if (allSerializers.size() < 1)
205  MITK_ERROR << "No serializer found for " << type << ". Skipping object";
206 
207  if (allSerializers.size() > 1)
208  MITK_WARN << "Multiple deserializers found for " << type << "Using arbitrarily the first one.";
209 
210  for (std::list<itk::LightObject::Pointer>::iterator iter = allSerializers.begin(); iter != allSerializers.end();
211  ++iter)
212  {
213  if (BasePropertySerializer *serializer = dynamic_cast<BasePropertySerializer *>(iter->GetPointer()))
214  {
215  try
216  {
217  prop = serializer->Deserialize(elem->FirstChildElement());
218  }
219  catch (std::exception &e)
220  {
221  MITK_ERROR << "Deserializer " << serializer->GetNameOfClass() << " failed: " << e.what();
222  return false;
223  }
224  break;
225  }
226  }
227  if (prop.IsNull())
228  return false;
229  return true;
230 }
#define MITK_INFO
Definition: mitkLogMacros.h:22
static itk::SmartPointer< mitk::Label > LoadLabelFromTiXmlDocument(TiXmlElement *labelElem)
Creates a mitk::Label from a TiXmlElement.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
static TiXmlElement * PropertyToXmlElem(const std::string &key, const BaseProperty *property)
Since a mitk::Label is basically a mitk::PropertyList this function coverts the label's properties in...
A data structure describing a label.
Definition: mitkLabel.h:35
static bool PropertyFromXmlElem(std::string &key, itk::SmartPointer< mitk::BaseProperty > &prop, TiXmlElement *elem)
Since a mitk::Label is basically a mitk::PropertyList this function coverts a XML element into a prop...
static void LoadLabelSetImagePreset(std::string &presetFilename, itk::SmartPointer< mitk::LabelSetImage > &inputImage)
Loads an existing preset for a mitk::LabelSetImage from presetFilename and applies it to inputImage...
static Pointer New()
Abstract base class for properties.
#define MITK_WARN
Definition: mitkLogMacros.h:23
std::map< std::string, BaseProperty::Pointer > PropertyMap
Base class for objects that serialize BaseProperty types.
static TiXmlElement * GetLabelAsTiXmlElement(Label *label)
Creates a TiXmlElement from a mitk::Label.
static bool SaveLabelSetImagePreset(std::string &presetFilename, itk::SmartPointer< mitk::LabelSetImage > &inputImage)
Saves the mitk::LabelSet configuration of inputImage to presetFilename. The preset is stored as "*...
const PropertyMap * GetMap() const