Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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