Medical Imaging Interaction Toolkit  2018.4.99-1bab67a2
Medical Imaging Interaction Toolkit
mitkLabelSetImageIO.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef __mitkLabelSetImageWriter__cpp
14 #define __mitkLabelSetImageWriter__cpp
15 
16 #include "mitkLabelSetImageIO.h"
18 #include "mitkIOMimeTypes.h"
19 #include "mitkImageAccessByItk.h"
20 #include "mitkLabelSetIOHelper.h"
22 #include <mitkLocaleSwitch.h>
25 #include <mitkCoreServices.h>
26 #include <mitkItkImageIO.h>
27 
28 // itk
29 #include "itkImageFileReader.h"
30 #include "itkImageFileWriter.h"
31 #include "itkMetaDataDictionary.h"
32 #include "itkMetaDataObject.h"
33 #include "itkNrrdImageIO.h"
34 
35 namespace mitk
36 {
37 
38  const char* const PROPERTY_NAME_TIMEGEOMETRY_TYPE = "org.mitk.timegeometry.type";
39  const char* const PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS = "org.mitk.timegeometry.timepoints";
40  const char* const PROPERTY_KEY_TIMEGEOMETRY_TYPE = "org_mitk_timegeometry_type";
41  const char* const PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS = "org_mitk_timegeometry_timepoints";
42 
44  : AbstractFileIO(LabelSetImage::GetStaticNameOfClass(), IOMimeTypes::NRRD_MIMETYPE(), "MITK Multilabel Image")
45  {
48  this->RegisterService();
49  }
50 
52  {
54  return Unsupported;
55  const auto *input = static_cast<const LabelSetImage *>(this->GetInput());
56  if (input)
57  return Supported;
58  else
59  return Unsupported;
60  }
61 
63  {
65 
66  auto input = dynamic_cast<const LabelSetImage *>(this->GetInput());
67 
68  mitk::LocaleSwitch localeSwitch("C");
69 
71 
72  // image write
73  if (inputVector.IsNull())
74  {
75  mitkThrow() << "Cannot write non-image data";
76  }
77 
78  itk::NrrdImageIO::Pointer nrrdImageIo = itk::NrrdImageIO::New();
79 
80  // Clone the image geometry, because we might have to change it
81  // for writing purposes
82  BaseGeometry::Pointer geometry = inputVector->GetGeometry()->Clone();
83 
84  // Check if geometry information will be lost
85  if (inputVector->GetDimension() == 2 && !geometry->Is2DConvertable())
86  {
87  MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might "
88  "consider using Convert2Dto3DImageFilter before saving.";
89 
90  // set matrix to identity
91  mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New();
92  affTrans->SetIdentity();
93  mitk::Vector3D spacing = geometry->GetSpacing();
94  mitk::Point3D origin = geometry->GetOrigin();
95  geometry->SetIndexToWorldTransform(affTrans);
96  geometry->SetSpacing(spacing);
97  geometry->SetOrigin(origin);
98  }
99 
100  LocalFile localFile(this);
101  const std::string path = localFile.GetFileName();
102 
103  MITK_INFO << "Writing image: " << path << std::endl;
104 
105  try
106  {
107  // Implementation of writer using itkImageIO directly. This skips the use
108  // of templated itkImageFileWriter, which saves the multiplexing on MITK side.
109 
110  const unsigned int dimension = inputVector->GetDimension();
111  const unsigned int *const dimensions = inputVector->GetDimensions();
112  const mitk::PixelType pixelType = inputVector->GetPixelType();
113  const mitk::Vector3D mitkSpacing = geometry->GetSpacing();
114  const mitk::Point3D mitkOrigin = geometry->GetOrigin();
115 
116  // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin,
117  // though they are not supported in MITK
118  itk::Vector<double, 4u> spacing4D;
119  spacing4D[0] = mitkSpacing[0];
120  spacing4D[1] = mitkSpacing[1];
121  spacing4D[2] = mitkSpacing[2];
122  spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have a valid value here
123 
124  itk::Vector<double, 4u> origin4D;
125  origin4D[0] = mitkOrigin[0];
126  origin4D[1] = mitkOrigin[1];
127  origin4D[2] = mitkOrigin[2];
128  origin4D[3] = 0; // There is no support for a 4D origin. However, we should have a valid value here
129 
130  // Set the necessary information for imageIO
131  nrrdImageIo->SetNumberOfDimensions(dimension);
132  nrrdImageIo->SetPixelType(pixelType.GetPixelType());
133  nrrdImageIo->SetComponentType(pixelType.GetComponentType() < PixelComponentUserType ?
134  static_cast<itk::ImageIOBase::IOComponentType>(pixelType.GetComponentType()) :
135  itk::ImageIOBase::UNKNOWNCOMPONENTTYPE);
136  nrrdImageIo->SetNumberOfComponents(pixelType.GetNumberOfComponents());
137 
138  itk::ImageIORegion ioRegion(dimension);
139 
140  for (unsigned int i = 0; i < dimension; i++)
141  {
142  nrrdImageIo->SetDimensions(i, dimensions[i]);
143  nrrdImageIo->SetSpacing(i, spacing4D[i]);
144  nrrdImageIo->SetOrigin(i, origin4D[i]);
145 
146  mitk::Vector3D mitkDirection;
147  mitkDirection.SetVnlVector(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i));
148  itk::Vector<double, 4u> direction4D;
149  direction4D[0] = mitkDirection[0];
150  direction4D[1] = mitkDirection[1];
151  direction4D[2] = mitkDirection[2];
152 
153  // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must
154  // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix.
155  if (i == 3)
156  {
157  direction4D[3] = 1; // homogenous component
158  }
159  else
160  {
161  direction4D[3] = 0;
162  }
163  vnl_vector<double> axisDirection(dimension);
164  for (unsigned int j = 0; j < dimension; j++)
165  {
166  axisDirection[j] = direction4D[j] / spacing4D[i];
167  }
168  nrrdImageIo->SetDirection(i, axisDirection);
169 
170  ioRegion.SetSize(i, inputVector->GetLargestPossibleRegion().GetSize(i));
171  ioRegion.SetIndex(i, inputVector->GetLargestPossibleRegion().GetIndex(i));
172  }
173 
174  // use compression if available
175  nrrdImageIo->UseCompressionOn();
176 
177  nrrdImageIo->SetIORegion(ioRegion);
178  nrrdImageIo->SetFileName(path);
179 
180  // label set specific meta data
181  char keybuffer[512];
182  char valbuffer[512];
183 
184  sprintf(keybuffer, "modality");
185  sprintf(valbuffer, "org.mitk.image.multilabel");
186  itk::EncapsulateMetaData<std::string>(
187  nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));
188 
189  sprintf(keybuffer, "layers");
190  sprintf(valbuffer, "%1d", input->GetNumberOfLayers());
191  itk::EncapsulateMetaData<std::string>(
192  nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));
193 
194  for (unsigned int layerIdx = 0; layerIdx < input->GetNumberOfLayers(); layerIdx++)
195  {
196  sprintf(keybuffer, "layer_%03u", layerIdx); // layer idx
197  sprintf(valbuffer, "%1u", input->GetNumberOfLabels(layerIdx)); // number of labels for the layer
198  itk::EncapsulateMetaData<std::string>(
199  nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));
200 
201  auto iter = input->GetLabelSet(layerIdx)->IteratorConstBegin();
202  unsigned int count(0);
203  while (iter != input->GetLabelSet(layerIdx)->IteratorConstEnd())
204  {
205  std::unique_ptr<TiXmlDocument> document;
206  document.reset(new TiXmlDocument());
207 
208  auto *decl = new TiXmlDeclaration("1.0", "", ""); // TODO what to write here? encoding? etc....
209  document->LinkEndChild(decl);
210  TiXmlElement *labelElem = mitk::LabelSetIOHelper::GetLabelAsTiXmlElement(iter->second);
211  document->LinkEndChild(labelElem);
212  TiXmlPrinter printer;
213  printer.SetIndent("");
214  printer.SetLineBreak("");
215 
216  document->Accept(&printer);
217 
218  sprintf(keybuffer, "org.mitk.label_%03u_%05u", layerIdx, count);
219  itk::EncapsulateMetaData<std::string>(
220  nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), printer.Str());
221  ++iter;
222  ++count;
223  }
224  }
225  // end label set specific meta data
226 
227  // Handle time geometry
228  const auto* arbitraryTG = dynamic_cast<const ArbitraryTimeGeometry*>(input->GetTimeGeometry());
229  if (arbitraryTG)
230  {
231  itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(),
234 
235 
236  auto metaTimePoints = ConvertTimePointListToMetaDataObject(arbitraryTG);
237  nrrdImageIo->GetMetaDataDictionary().Set(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS, metaTimePoints);
238  }
239 
240  // Handle properties
241  mitk::PropertyList::Pointer imagePropertyList = input->GetPropertyList();
242  for (const auto& property : *imagePropertyList->GetMap())
243  {
245  IPropertyPersistence::InfoResultType infoList = propPersistenceService->GetInfo(property.first, GetMimeType()->GetName(), true);
246 
247  if (infoList.empty())
248  {
249  continue;
250  }
251 
252  std::string value = infoList.front()->GetSerializationFunction()(property.second);
253 
255  {
256  continue;
257  }
258 
259  std::string key = infoList.front()->GetKey();
260 
261  itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(), key, value);
262  }
263 
264  ImageReadAccessor imageAccess(inputVector);
265  nrrdImageIo->Write(imageAccess.GetData());
266  }
267  catch (const std::exception &e)
268  {
269  mitkThrow() << e.what();
270  }
271  // end image write
272  }
273 
275  {
277  return Unsupported;
278  const std::string fileName = this->GetLocalFileName();
279  itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
280  io->SetFileName(fileName);
281  io->ReadImageInformation();
282 
283  itk::MetaDataDictionary imgMetaDataDictionary = io->GetMetaDataDictionary();
284  std::string value("");
285  itk::ExposeMetaData<std::string>(imgMetaDataDictionary, "modality", value);
286  if (value.compare("org.mitk.image.multilabel") == 0)
287  {
288  return Supported;
289  }
290  else
291  return Unsupported;
292  }
293 
294  std::vector<BaseData::Pointer> LabelSetImageIO::DoRead()
295  {
296  mitk::LocaleSwitch localeSwitch("C");
297 
298  // begin regular image loading, adapted from mitkItkImageIO
299  itk::NrrdImageIO::Pointer nrrdImageIO = itk::NrrdImageIO::New();
301 
302  const unsigned int MINDIM = 2;
303  const unsigned int MAXDIM = 4;
304 
305  const std::string path = this->GetLocalFileName();
306 
307  MITK_INFO << "loading " << path << " via itk::ImageIOFactory... " << std::endl;
308 
309  // Check to see if we can read the file given the name or prefix
310  if (path.empty())
311  {
312  mitkThrow() << "Empty filename in mitk::ItkImageIO ";
313  }
314 
315  // Got to allocate space for the image. Determine the characteristics of
316  // the image.
317  nrrdImageIO->SetFileName(path);
318  nrrdImageIO->ReadImageInformation();
319 
320  unsigned int ndim = nrrdImageIO->GetNumberOfDimensions();
321  if (ndim < MINDIM || ndim > MAXDIM)
322  {
323  MITK_WARN << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim
324  << " dimensions! Reading as 4D.";
325  ndim = MAXDIM;
326  }
327 
328  itk::ImageIORegion ioRegion(ndim);
329  itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize();
330  itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex();
331 
332  unsigned int dimensions[MAXDIM];
333  dimensions[0] = 0;
334  dimensions[1] = 0;
335  dimensions[2] = 0;
336  dimensions[3] = 0;
337 
338  ScalarType spacing[MAXDIM];
339  spacing[0] = 1.0f;
340  spacing[1] = 1.0f;
341  spacing[2] = 1.0f;
342  spacing[3] = 1.0f;
343 
344  Point3D origin;
345  origin.Fill(0);
346 
347  unsigned int i;
348  for (i = 0; i < ndim; ++i)
349  {
350  ioStart[i] = 0;
351  ioSize[i] = nrrdImageIO->GetDimensions(i);
352  if (i < MAXDIM)
353  {
354  dimensions[i] = nrrdImageIO->GetDimensions(i);
355  spacing[i] = nrrdImageIO->GetSpacing(i);
356  if (spacing[i] <= 0)
357  spacing[i] = 1.0f;
358  }
359  if (i < 3)
360  {
361  origin[i] = nrrdImageIO->GetOrigin(i);
362  }
363  }
364 
365  ioRegion.SetSize(ioSize);
366  ioRegion.SetIndex(ioStart);
367 
368  MITK_INFO << "ioRegion: " << ioRegion << std::endl;
369  nrrdImageIO->SetIORegion(ioRegion);
370  void *buffer = new unsigned char[nrrdImageIO->GetImageSizeInBytes()];
371  nrrdImageIO->Read(buffer);
372 
373  image->Initialize(MakePixelType(nrrdImageIO), ndim, dimensions);
374  image->SetImportChannel(buffer, 0, Image::ManageMemory);
375 
376  // access direction of itk::Image and include spacing
377  mitk::Matrix3D matrix;
378  matrix.SetIdentity();
379  unsigned int j, itkDimMax3 = (ndim >= 3 ? 3 : ndim);
380  for (i = 0; i < itkDimMax3; ++i)
381  for (j = 0; j < itkDimMax3; ++j)
382  matrix[i][j] = nrrdImageIO->GetDirection(j)[i];
383 
384  // re-initialize PlaneGeometry with origin and direction
385  PlaneGeometry *planeGeometry = image->GetSlicedGeometry(0)->GetPlaneGeometry(0);
386  planeGeometry->SetOrigin(origin);
387  planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix);
388 
389  // re-initialize SlicedGeometry3D
390  SlicedGeometry3D *slicedGeometry = image->GetSlicedGeometry(0);
391  slicedGeometry->InitializeEvenlySpaced(planeGeometry, image->GetDimension(2));
392  slicedGeometry->SetSpacing(spacing);
393 
394  MITK_INFO << slicedGeometry->GetCornerPoint(false, false, false);
395  MITK_INFO << slicedGeometry->GetCornerPoint(true, true, true);
396 
397  // re-initialize TimeGeometry
398  const itk::MetaDataDictionary& dictionary = nrrdImageIO->GetMetaDataDictionary();
399  TimeGeometry::Pointer timeGeometry;
400 
401  if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TYPE) || dictionary.HasKey(PROPERTY_KEY_TIMEGEOMETRY_TYPE))
402  { // also check for the name because of backwards compatibility. Past code version stored with the name and not with
403  // the key
404  itk::MetaDataObject<std::string>::ConstPointer timeGeometryTypeData;
405  if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TYPE))
406  {
407  timeGeometryTypeData =
408  dynamic_cast<const itk::MetaDataObject<std::string>*>(dictionary.Get(PROPERTY_NAME_TIMEGEOMETRY_TYPE));
409  }
410  else
411  {
412  timeGeometryTypeData =
413  dynamic_cast<const itk::MetaDataObject<std::string>*>(dictionary.Get(PROPERTY_KEY_TIMEGEOMETRY_TYPE));
414  }
415 
416  if (timeGeometryTypeData->GetMetaDataObjectValue() == ArbitraryTimeGeometry::GetStaticNameOfClass())
417  {
418  MITK_INFO << "used time geometry: " << ArbitraryTimeGeometry::GetStaticNameOfClass();
419  typedef std::vector<TimePointType> TimePointVector;
420  TimePointVector timePoints;
421 
422  if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS))
423  {
424  timePoints = ConvertMetaDataObjectToTimePointList(dictionary.Get(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS));
425  }
426  else if (dictionary.HasKey(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS))
427  {
428  timePoints = ConvertMetaDataObjectToTimePointList(dictionary.Get(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS));
429  }
430 
431  if (timePoints.empty())
432  {
433  MITK_ERROR << "Stored timepoints are empty. Meta information seems to bee invalid. Switch to ProportionalTimeGeometry fallback";
434  }
435  else if (timePoints.size() - 1 != image->GetDimension(3))
436  {
437  MITK_ERROR << "Stored timepoints (" << timePoints.size() - 1 << ") and size of image time dimension ("
438  << image->GetDimension(3) << ") do not match. Switch to ProportionalTimeGeometry fallback";
439  }
440  else
441  {
443  TimePointVector::const_iterator pos = timePoints.begin();
444  auto prePos = pos++;
445 
446  for (; pos != timePoints.end(); ++prePos, ++pos)
447  {
448  arbitraryTimeGeometry->AppendNewTimeStepClone(slicedGeometry, *prePos, *pos);
449  }
450 
451  timeGeometry = arbitraryTimeGeometry;
452  }
453  }
454  }
455 
456  if (timeGeometry.IsNull())
457  { // Fallback. If no other valid time geometry has been created, create a ProportionalTimeGeometry
458  MITK_INFO << "used time geometry: " << ProportionalTimeGeometry::GetStaticNameOfClass();
460  propTimeGeometry->Initialize(slicedGeometry, image->GetDimension(3));
461  timeGeometry = propTimeGeometry;
462  }
463 
464  image->SetTimeGeometry(timeGeometry);
465 
466  buffer = nullptr;
467  MITK_INFO << "number of image components: " << image->GetPixelType().GetNumberOfComponents();
468 
469  // end regular image loading
470 
472 
473  // get labels and add them as properties to the image
474  char keybuffer[256];
475 
476  unsigned int numberOfLayers = GetIntByKey(dictionary, "layers");
477  std::string _xmlStr;
478  mitk::Label::Pointer label;
479 
480  for (unsigned int layerIdx = 0; layerIdx < numberOfLayers; layerIdx++)
481  {
482  sprintf(keybuffer, "layer_%03u", layerIdx);
483  int numberOfLabels = GetIntByKey(dictionary, keybuffer);
484 
485  mitk::LabelSet::Pointer labelSet = mitk::LabelSet::New();
486 
487  for (int labelIdx = 0; labelIdx < numberOfLabels; labelIdx++)
488  {
489  TiXmlDocument doc;
490  sprintf(keybuffer, "label_%03u_%05d", layerIdx, labelIdx);
491  _xmlStr = GetStringByKey(dictionary, keybuffer);
492  doc.Parse(_xmlStr.c_str());
493 
494  TiXmlElement *labelElem = doc.FirstChildElement("Label");
495  if (labelElem == nullptr)
496  mitkThrow() << "Error parsing NRRD header for mitk::LabelSetImage IO";
497 
499 
500  if (label->GetValue() == 0) // set exterior label is needed to hold exterior information
501  output->SetExteriorLabel(label);
502  labelSet->AddLabel(label);
503  labelSet->SetLayer(layerIdx);
504  }
505  output->AddLabelSetToLayer(layerIdx, labelSet);
506  }
507 
508  for (auto iter = dictionary.Begin(), iterEnd = dictionary.End(); iter != iterEnd;
509  ++iter)
510  {
511  if (iter->second->GetMetaDataObjectTypeInfo() == typeid(std::string))
512  {
513  const std::string& key = iter->first;
514  std::string assumedPropertyName = key;
515  std::replace(assumedPropertyName.begin(), assumedPropertyName.end(), '_', '.');
516 
517  std::string mimeTypeName = GetMimeType()->GetName();
518 
519  // Check if there is already a info for the key and our mime type.
521  IPropertyPersistence::InfoResultType infoList = propPersistenceService->GetInfoByKey(key);
522 
523  auto predicate = [&mimeTypeName](const PropertyPersistenceInfo::ConstPointer& x) {
524  return x.IsNotNull() && x->GetMimeTypeName() == mimeTypeName;
525  };
526  auto finding = std::find_if(infoList.begin(), infoList.end(), predicate);
527 
528  if (finding == infoList.end())
529  {
530  auto predicateWild = [](const PropertyPersistenceInfo::ConstPointer& x) {
531  return x.IsNotNull() && x->GetMimeTypeName() == PropertyPersistenceInfo::ANY_MIMETYPE_NAME();
532  };
533  finding = std::find_if(infoList.begin(), infoList.end(), predicateWild);
534  }
535 
537 
538  if (finding != infoList.end())
539  {
540  assumedPropertyName = (*finding)->GetName();
541  info = *finding;
542  }
543  else
544  { // we have not found anything suitable so we generate our own info
545  auto newInfo = PropertyPersistenceInfo::New();
546  newInfo->SetNameAndKey(assumedPropertyName, key);
547  newInfo->SetMimeTypeName(PropertyPersistenceInfo::ANY_MIMETYPE_NAME());
548  info = newInfo;
549  }
550 
551  std::string value =
552  dynamic_cast<itk::MetaDataObject<std::string>*>(iter->second.GetPointer())->GetMetaDataObjectValue();
553 
554  mitk::BaseProperty::Pointer loadedProp = info->GetDeserializationFunction()(value);
555 
556  output->SetProperty(assumedPropertyName.c_str(), loadedProp);
557 
558  // Read properties should be persisted unless they are default properties
559  // which are written anyway
560  bool isDefaultKey = false;
561 
562  for (const auto& defaultKey : m_DefaultMetaDataKeys)
563  {
564  if (defaultKey.length() <= assumedPropertyName.length())
565  {
566  // does the start match the default key
567  if (assumedPropertyName.substr(0, defaultKey.length()).find(defaultKey) != std::string::npos)
568  {
569  isDefaultKey = true;
570  break;
571  }
572  }
573  }
574 
575  if (!isDefaultKey)
576  {
577  propPersistenceService->AddInfo(info);
578  }
579  }
580  }
581 
582  MITK_INFO << "...finished!";
583 
584  std::vector<BaseData::Pointer> result;
585  result.push_back(output.GetPointer());
586  return result;
587  }
588 
589  int LabelSetImageIO::GetIntByKey(const itk::MetaDataDictionary &dic, const std::string &str)
590  {
591  std::vector<std::string> imgMetaKeys = dic.GetKeys();
592  std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
593  std::string metaString("");
594  for (; itKey != imgMetaKeys.end(); itKey++)
595  {
596  itk::ExposeMetaData<std::string>(dic, *itKey, metaString);
597  if (itKey->find(str.c_str()) != std::string::npos)
598  {
599  return atoi(metaString.c_str());
600  }
601  }
602  return 0;
603  }
604 
605  std::string LabelSetImageIO::GetStringByKey(const itk::MetaDataDictionary &dic, const std::string &str)
606  {
607  std::vector<std::string> imgMetaKeys = dic.GetKeys();
608  std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
609  std::string metaString("");
610  for (; itKey != imgMetaKeys.end(); itKey++)
611  {
612  itk::ExposeMetaData<std::string>(dic, *itKey, metaString);
613  if (itKey->find(str.c_str()) != std::string::npos)
614  {
615  return metaString;
616  }
617  }
618  return metaString;
619  }
620 
621  LabelSetImageIO *LabelSetImageIO::IOClone() const { return new LabelSetImageIO(*this); }
622 
624  {
625  this->m_DefaultMetaDataKeys.push_back("NRRD.space");
626  this->m_DefaultMetaDataKeys.push_back("NRRD.kinds");
627  this->m_DefaultMetaDataKeys.push_back(PROPERTY_NAME_TIMEGEOMETRY_TYPE);
628  this->m_DefaultMetaDataKeys.push_back(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS);
629  this->m_DefaultMetaDataKeys.push_back("ITK.InputFilterName");
630  this->m_DefaultMetaDataKeys.push_back("label_");
631  this->m_DefaultMetaDataKeys.push_back("layer_");
632  }
633 
634 } // namespace
635 
636 #endif //__mitkLabelSetImageWriter__cpp
MITKMULTILABEL_EXPORT Image::Pointer ConvertLabelSetImageToImage(LabelSetImage::ConstPointer labelSetImage)
Convert mitk::LabelSetImage to mitk::Image (itk::VectorImage)
static const char * GetStaticNameOfClass()
virtual void InitializeDefaultMetaDataKeys()
The IOMimeTypes class.
void SetSpacing(const mitk::Vector3D &aSpacing, bool enforceSetSpacing=false)
Set the spacing (m_Spacing).
#define MITK_INFO
Definition: mitkLogMacros.h:18
static itk::SmartPointer< mitk::Label > LoadLabelFromTiXmlDocument(TiXmlElement *labelElem)
Creates a mitk::Label from a TiXmlElement.
ConfidenceLevel GetReaderConfidenceLevel() const override
#define MITK_ERROR
Definition: mitkLogMacros.h:20
const char *const PROPERTY_KEY_TIMEGEOMETRY_TYPE
double ScalarType
vcl_size_t GetNumberOfComponents() const
Get the number of components of which each element consists.
std::string GetName() const
Returns the unique name for the MimeType.
MITKMULTILABEL_EXPORT LabelSetImage::Pointer ConvertImageToLabelSetImage(Image::Pointer image)
Convert mitk::Image to mitk::LabelSetImage, templating and differentation between itk::Image and itk:...
const char *const PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS
int GetIntByKey(const itk::MetaDataDictionary &dic, const std::string &str)
std::string GetStringByKey(const itk::MetaDataDictionary &dic, const std::string &str)
DataCollection - Class to facilitate loading/accessing structured data.
Point3D GetCornerPoint(int id) const
Get the position of the corner number id (in world coordinates)
void Write() override
Write the base data to the specified location or output stream.
MITKCORE_EXPORT itk::MetaDataObjectBase::Pointer ConvertTimePointListToMetaDataObject(const mitk::TimeGeometry *timeGeometry)
static Pointer New()
virtual void InitializeEvenlySpaced(mitk::PlaneGeometry *geometry2D, unsigned int slices)
Completely initialize this instance as evenly-spaced with slices parallel to the provided PlaneGeomet...
static void info(const char *fmt,...)
Definition: svm.cpp:86
static const int PixelComponentUserType
int GetComponentType() const
Get the component type (the scalar (!) type). Each element may contain m_NumberOfComponents (more tha...
void SetRanking(int ranking)
Set the service ranking for this file writer.
std::string GetLocalFileName() const
Get a local file name for reading.
ConfidenceLevel GetReaderConfidenceLevel() const override
std::vector< itk::SmartPointer< BaseData > > DoRead() override
Reads a number of mitk::LabelSetImages from the file system.
MITKCORE_EXPORT mitk::PixelType MakePixelType(vtkImageData *vtkimagedata)
deduct the PixelType for a given vtk image
#define MITK_WARN
Definition: mitkLogMacros.h:19
ConfidenceLevel
A confidence level describing the confidence of the reader or writer in handling the given data...
Definition: mitkIFileIO.h:45
Convenience class to temporarily change the current locale.
static IPropertyPersistence * GetPropertyPersistence(us::ModuleContext *context=us::GetModuleContext())
Get an IPropertyPersistence instance.
std::pair< us::ServiceRegistration< IFileReader >, us::ServiceRegistration< IFileWriter > > RegisterService(us::ModuleContext *context=us::GetModuleContext())
#define mitkThrow()
void SetOrigin(const Point3D &origin)
Set the origin, i.e. the upper-left corner of the plane.
const BaseData * GetInput() const override
Get the input data set via SetInput().
ConfidenceLevel GetWriterConfidenceLevel() const override
A local file representation for streams.
static const std::string VALUE_CANNOT_BE_CONVERTED_TO_STRING
Default return value if a property which can not be returned as string.
itk::ImageIOBase::IOPixelType GetPixelType() const
mitk::Image::Pointer image
static Pointer New()
Describes the geometry of a data object consisting of slices.
void SetRanking(int ranking)
Set the service ranking for this file reader.
static TiXmlElement * GetLabelAsTiXmlElement(Label *label)
Creates a TiXmlElement from a mitk::Label.
LabelSetImage class for handling labels and layers in a segmentation session.
const char *const PROPERTY_NAME_TIMEGEOMETRY_TYPE
static const char * replace[]
This is a dictionary to replace long names of classes, modules, etc. to shorter versions in the conso...
static std::string GetName(std::string fileName, std::string suffix)
MITKCORE_EXPORT std::vector< TimePointType > ConvertMetaDataObjectToTimePointList(const itk::MetaDataObjectBase *data)
ConfidenceLevel GetWriterConfidenceLevel() const override
A RAII helper class for core service objects.
Describes a two-dimensional, rectangular plane.
std::list< PropertyPersistenceInfo::ConstPointer > InfoResultType
ImageReadAccessor class to get locked read access for a particular image part.
Abstract class for implementing a reader and writer.
const CustomMimeType * GetMimeType() const
const char *const PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS
Class for defining the data type of pixels.
Definition: mitkPixelType.h:51
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.