Medical Imaging Interaction Toolkit  2018.4.99-87d68d9f
Medical Imaging Interaction Toolkit
mitkDICOMSegmentationIO.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 __mitkDICOMSegmentationIO__cpp
14 #define __mitkDICOMSegmentationIO__cpp
15 
17 
21 #include <mitkDICOMIOHelper.h>
22 #include <mitkDICOMProperty.h>
24 #include <mitkImageAccessByItk.h>
25 #include <mitkImageCast.h>
26 #include <mitkLocaleSwitch.h>
27 #include <mitkPropertyNameHelper.h>
28 
29 
30 // itk
31 #include <itkThresholdImageFilter.h>
32 
33 // dcmqi
34 #include <dcmqi/ImageSEGConverter.h>
35 
36 // us
37 #include <usGetModuleContext.h>
38 #include <usModuleContext.h>
39 
40 namespace mitk
41 {
43  : AbstractFileIO(LabelSetImage::GetStaticNameOfClass(),
44  mitk::MitkDICOMSEGIOMimeTypes::DICOMSEG_MIMETYPE_NAME(),
45  "DICOM Segmentation")
46  {
49  this->RegisterService();
50 
51  this->AddDICOMTagsToService();
52  }
53 
54  void DICOMSegmentationIO::AddDICOMTagsToService()
55  {
57  if (toiService != nullptr)
58  {
60 
64 
69 
74 
79 
84  }
85  }
86 
88  {
90  return Unsupported;
91 
92  // Check if the input file is a segmentation
93  const LabelSetImage *input = static_cast<const LabelSetImage *>(this->GetInput());
94 
95  if (input)
96  {
97  if ((input->GetDimension() != 3))
98  {
99  MITK_INFO << "DICOM segmentation writer is tested only with 3D images, sorry.";
100  return Unsupported;
101  }
102 
103  // Check if input file has dicom information for the referenced image (original DICOM image, e.g. CT) Still necessary, see write()
105  dynamic_cast<mitk::StringLookupTableProperty *>(input->GetProperty("referenceFiles").GetPointer());
106 
107  if (dicomFilesProp.IsNotNull())
108  return Supported;
109  }
110 
111  return Unsupported;
112  }
113 
115  {
117 
118  mitk::LocaleSwitch localeSwitch("C");
119  LocalFile localFile(this);
120  const std::string path = localFile.GetFileName();
121 
122  auto input = dynamic_cast<const LabelSetImage *>(this->GetInput());
123  if (input == nullptr)
124  mitkThrow() << "Cannot write non-image data";
125 
126  // Get DICOM information from referenced image
127  vector<std::unique_ptr<DcmDataset>> dcmDatasetsSourceImage;
128  std::unique_ptr<DcmFileFormat> readFileFormat(new DcmFileFormat());
129  try
130  {
131  // TODO: Generate dcmdataset witk DICOM tags from property list; ATM the source are the filepaths from the
132  // property list
134  dynamic_cast<mitk::StringLookupTableProperty *>(input->GetProperty("referenceFiles").GetPointer());
135 
136  if (filesProp.IsNull())
137  {
138  mitkThrow() << "No property with dicom file path.";
139  return;
140  }
141 
142  StringLookupTable filesLut = filesProp->GetValue();
143  const StringLookupTable::LookupTableType &lookUpTableMap = filesLut.GetLookupTable();
144 
145  for (auto it : lookUpTableMap)
146  {
147  const char *fileName = (it.second).c_str();
148  if (readFileFormat->loadFile(fileName, EXS_Unknown).good())
149  {
150  std::unique_ptr<DcmDataset> readDCMDataset(readFileFormat->getAndRemoveDataset());
151  dcmDatasetsSourceImage.push_back(std::move(readDCMDataset));
152  }
153  }
154  }
155  catch (const std::exception &e)
156  {
157  MITK_ERROR << "An error occurred while getting the dicom informations: " << e.what() << endl;
158  return;
159  }
160 
161  // Iterate over all layers. For each a dcm file will be generated
162  for (unsigned int layer = 0; layer < input->GetNumberOfLayers(); ++layer)
163  {
164  vector<itkInternalImageType::Pointer> segmentations;
165 
166  try
167  {
168  // Hack: Remove the const attribute to switch between the layer images. Normally you could get the different
169  // layer images by input->GetLayerImage(layer)
170  mitk::LabelSetImage *mitkLayerImage = const_cast<mitk::LabelSetImage *>(input);
171  mitkLayerImage->SetActiveLayer(layer);
172 
173  // Cast mitk layer image to itk
175  imageToItkFilter->SetInput(mitkLayerImage);
176  // Cast from original itk type to dcmqi input itk image type
177  typedef itk::CastImageFilter<itkInputImageType, itkInternalImageType> castItkImageFilterType;
178  castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New();
179  castFilter->SetInput(imageToItkFilter->GetOutput());
180  castFilter->Update();
181 
182  itkInternalImageType::Pointer itkLabelImage = castFilter->GetOutput();
183  itkLabelImage->DisconnectPipeline();
184 
185  // Iterate over all labels. For each label a segmentation image will be created
186  const LabelSet *labelSet = input->GetLabelSet(layer);
187  auto labelIter = labelSet->IteratorConstBegin();
188  // Ignore background label
189  ++labelIter;
190 
191  for (; labelIter != labelSet->IteratorConstEnd(); ++labelIter)
192  {
193  // Thresold over the image with the given label value
194  itk::ThresholdImageFilter<itkInternalImageType>::Pointer thresholdFilter =
195  itk::ThresholdImageFilter<itkInternalImageType>::New();
196  thresholdFilter->SetInput(itkLabelImage);
197  thresholdFilter->ThresholdOutside(labelIter->first, labelIter->first);
198  thresholdFilter->SetOutsideValue(0);
199  thresholdFilter->Update();
200  itkInternalImageType::Pointer segmentImage = thresholdFilter->GetOutput();
201  segmentImage->DisconnectPipeline();
202 
203  segmentations.push_back(segmentImage);
204  }
205  }
206  catch (const itk::ExceptionObject &e)
207  {
208  MITK_ERROR << e.GetDescription() << endl;
209  return;
210  }
211 
212  // Create segmentation meta information
213  const std::string tmpMetaInfoFile = this->CreateMetaDataJsonFile(layer);
214 
215  MITK_INFO << "Writing image: " << path << std::endl;
216  try
217  {
218  //TODO is there a better way? Interface expects a vector of raw pointer.
219  vector<DcmDataset*> rawVecDataset;
220  for (const auto& dcmDataSet : dcmDatasetsSourceImage)
221  rawVecDataset.push_back(dcmDataSet.get());
222 
223  // Convert itk segmentation images to dicom image
224  std::unique_ptr<dcmqi::ImageSEGConverter> converter = std::make_unique<dcmqi::ImageSEGConverter>();
225  std::unique_ptr<DcmDataset> result(converter->itkimage2dcmSegmentation(rawVecDataset, segmentations, tmpMetaInfoFile));
226 
227  // Write dicom file
228  DcmFileFormat dcmFileFormat(result.get());
229 
230  std::string filePath = path.substr(0, path.find_last_of("."));
231  // If there is more than one layer, we have to write more than 1 dicom file
232  if (input->GetNumberOfLayers() != 1)
233  filePath = filePath + std::to_string(layer) + ".dcm";
234  else
235  filePath = filePath + ".dcm";
236 
237  dcmFileFormat.saveFile(filePath.c_str(), EXS_LittleEndianExplicit);
238  }
239  catch (const std::exception &e)
240  {
241  MITK_ERROR << "An error occurred during writing the DICOM Seg: " << e.what() << endl;
242  return;
243  }
244  } // Write a dcm file for the next layer
245  }
246 
248  {
250  return Unsupported;
251 
252  const std::string fileName = this->GetLocalFileName();
253 
254  DcmFileFormat dcmFileFormat;
255  OFCondition status = dcmFileFormat.loadFile(fileName.c_str());
256 
257  if (status.bad())
258  return Unsupported;
259 
260  OFString modality;
261  if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good())
262  {
263  if (modality.compare("SEG") == 0)
264  return Supported;
265  else
266  return Unsupported;
267  }
268  return Unsupported;
269  }
270 
271  std::vector<BaseData::Pointer> DICOMSegmentationIO::Read()
272  {
273  mitk::LocaleSwitch localeSwitch("C");
274 
275  LabelSetImage::Pointer labelSetImage;
276  std::vector<BaseData::Pointer> result;
277 
278  const std::string path = this->GetLocalFileName();
279 
280  MITK_INFO << "loading " << path << std::endl;
281 
282  if (path.empty())
283  mitkThrow() << "Empty filename in mitk::ItkImageIO ";
284 
285  try
286  {
287  // Get the dcm data set from file path
288  DcmFileFormat dcmFileFormat;
289  OFCondition status = dcmFileFormat.loadFile(path.c_str());
290  if (status.bad())
291  mitkThrow() << "Can't read the input file!";
292 
293  DcmDataset *dataSet = dcmFileFormat.getDataset();
294  if (dataSet == nullptr)
295  mitkThrow() << "Can't read data from input file!";
296 
297  //=============================== dcmqi part ====================================
298  // Read the DICOM SEG images (segItkImages) and DICOM tags (metaInfo)
299  std::unique_ptr<dcmqi::ImageSEGConverter> converter = std::make_unique<dcmqi::ImageSEGConverter>();
300  pair<map<unsigned, itkInternalImageType::Pointer>, string> dcmqiOutput =
301  converter->dcmSegmentation2itkimage(dataSet);
302 
303  map<unsigned, itkInternalImageType::Pointer> segItkImages = dcmqiOutput.first;
304 
305  dcmqi::JSONSegmentationMetaInformationHandler metaInfo(dcmqiOutput.second.c_str());
306  metaInfo.read();
307 
308  MITK_INFO << "Input " << metaInfo.getJSONOutputAsString();
309  //===============================================================================
310 
311  // Get the label information from segment attributes for each itk image
312  vector<map<unsigned, dcmqi::SegmentAttributes *>>::const_iterator segmentIter =
313  metaInfo.segmentsAttributesMappingList.begin();
314 
315  // For each itk image add a layer to the LabelSetImage output
316  for (auto &element : segItkImages)
317  {
318  // Get the labeled image and cast it to mitkImage
319  typedef itk::CastImageFilter<itkInternalImageType, itkInputImageType> castItkImageFilterType;
320  castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New();
321  castFilter->SetInput(element.second);
322  castFilter->Update();
323 
324  Image::Pointer layerImage;
325  CastToMitkImage(castFilter->GetOutput(), layerImage);
326 
327  // Get pixel value of the label
328  itkInternalImageType::ValueType segValue = 1;
329  typedef itk::ImageRegionIterator<const itkInternalImageType> IteratorType;
330  // Iterate over the image to find the pixel value of the label
331  IteratorType iter(element.second, element.second->GetLargestPossibleRegion());
332  iter.GoToBegin();
333  while (!iter.IsAtEnd())
334  {
335  itkInputImageType::PixelType value = iter.Get();
336  if (value != 0)
337  {
338  segValue = value;
339  break;
340  }
341  ++iter;
342  }
343  // Get Segment information map
344  map<unsigned, dcmqi::SegmentAttributes *> segmentMap = (*segmentIter);
345  map<unsigned, dcmqi::SegmentAttributes *>::const_iterator segmentMapIter = (*segmentIter).begin();
346  dcmqi::SegmentAttributes *segmentAttribute = (*segmentMapIter).second;
347 
348  OFString labelName;
349 
350  if (segmentAttribute->getSegmentedPropertyTypeCodeSequence() != nullptr)
351  {
352  segmentAttribute->getSegmentedPropertyTypeCodeSequence()->getCodeMeaning(labelName);
353  if (segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence() != nullptr)
354  {
355  OFString modifier;
356  segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence()->getCodeMeaning(modifier);
357  labelName.append(" (").append(modifier).append(")");
358  }
359  }
360  else
361  {
362  labelName = std::to_string(segmentAttribute->getLabelID()).c_str();
363  if (labelName.empty())
364  labelName = "Unnamed";
365  }
366 
367  float tmp[3] = { 0.0, 0.0, 0.0 };
368  if (segmentAttribute->getRecommendedDisplayRGBValue() != nullptr)
369  {
370  tmp[0] = segmentAttribute->getRecommendedDisplayRGBValue()[0] / 255.0;
371  tmp[1] = segmentAttribute->getRecommendedDisplayRGBValue()[1] / 255.0;
372  tmp[2] = segmentAttribute->getRecommendedDisplayRGBValue()[2] / 255.0;
373  }
374 
375  Label *newLabel = nullptr;
376  // If labelSetImage do not exists (first image)
377  if (labelSetImage.IsNull())
378  {
379  // Initialize the labelSetImage with the read image
380  labelSetImage = LabelSetImage::New();
381  labelSetImage->InitializeByLabeledImage(layerImage);
382  // Already a label was generated, so set the information to this
383  newLabel = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer());
384  newLabel->SetName(labelName.c_str());
385  newLabel->SetColor(Color(tmp));
386  newLabel->SetValue(segValue);
387  }
388  else
389  {
390  // Add a new layer to the labelSetImage. Background label is set automatically
391  labelSetImage->AddLayer(layerImage);
392 
393  // Add new label
394  newLabel = new Label;
395  newLabel->SetName(labelName.c_str());
396  newLabel->SetColor(Color(tmp));
397  newLabel->SetValue(segValue);
398  labelSetImage->GetLabelSet(labelSetImage->GetActiveLayer())->AddLabel(newLabel);
399  }
400 
401  // Add some more label properties
402  this->SetLabelProperties(newLabel, segmentAttribute);
403  ++segmentIter;
404  }
405 
406  labelSetImage->GetLabelSet()->SetAllLabelsVisible(true);
407 
408  // Add some general DICOM Segmentation properties
410  auto tagsOfInterest = toiSrv->GetTagsOfInterest();
411  DICOMTagPathList tagsOfInterestList;
412  for (const auto &tag : tagsOfInterest)
413  {
414  tagsOfInterestList.push_back(tag.first);
415  }
416 
417  mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New();
418  scanner->SetInputFiles({ GetInputLocation() });
419  scanner->AddTagPaths(tagsOfInterestList);
420  scanner->Scan();
421 
422  mitk::DICOMDatasetAccessingImageFrameList frames = scanner->GetFrameInfoList();
423  if (frames.empty())
424  {
425  MITK_ERROR << "Error reading the DICOM Seg file" << std::endl;
426  return result;
427  }
428 
429  auto findings = ExtractPathsOfInterest(tagsOfInterestList, frames);
430  SetProperties(labelSetImage, findings);
431 
432  // Set active layer to the first layer of the labelset image
433  if (labelSetImage->GetNumberOfLayers() > 1 && labelSetImage->GetActiveLayer() != 0)
434  labelSetImage->SetActiveLayer(0);
435  }
436  catch (const std::exception &e)
437  {
438  MITK_ERROR << "An error occurred while reading the DICOM Seg file: " << e.what();
439  return result;
440  }
441  catch (...)
442  {
443  MITK_ERROR << "An error occurred in dcmqi while reading the DICOM Seg file";
444  return result;
445  }
446 
447  result.push_back(labelSetImage.GetPointer());
448  return result;
449  }
450 
451  const std::string mitk::DICOMSegmentationIO::CreateMetaDataJsonFile(int layer)
452  {
453  const mitk::LabelSetImage *image = dynamic_cast<const mitk::LabelSetImage *>(this->GetInput());
454 
455  const std::string output;
456  dcmqi::JSONSegmentationMetaInformationHandler handler;
457 
458 
459  // 1. Metadata attributes that will be listed in the resulting DICOM SEG object
460  std::string contentCreatorName;
461  if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0070, 0x0084).c_str(),
462  contentCreatorName))
463  contentCreatorName = "MITK";
464  handler.setContentCreatorName(contentCreatorName);
465 
466  std::string clinicalTrailSeriesId;
467  if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0071).c_str(),
468  clinicalTrailSeriesId))
469  clinicalTrailSeriesId = "Session 1";
470  handler.setClinicalTrialSeriesID(clinicalTrailSeriesId);
471 
472  std::string clinicalTrialTimePointID;
473  if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0050).c_str(),
474  clinicalTrialTimePointID))
475  clinicalTrialTimePointID = "0";
476  handler.setClinicalTrialTimePointID(clinicalTrialTimePointID);
477 
478  std::string clinicalTrialCoordinatingCenterName = "";
479  if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0060).c_str(),
480  clinicalTrialCoordinatingCenterName))
481  clinicalTrialCoordinatingCenterName = "Unknown";
482  handler.setClinicalTrialCoordinatingCenterName(clinicalTrialCoordinatingCenterName);
483 
484  std::string seriesDescription;
485  if (!image->GetPropertyList()->GetStringProperty("name", seriesDescription))
486  seriesDescription = "MITK Segmentation";
487  handler.setSeriesDescription(seriesDescription);
488 
489  handler.setSeriesNumber("0" + std::to_string(layer));
490  handler.setInstanceNumber("1");
491  handler.setBodyPartExamined("");
492 
493  const LabelSet *labelSet = image->GetLabelSet(layer);
494  auto labelIter = labelSet->IteratorConstBegin();
495  // Ignore background label
496  ++labelIter;
497 
498  for (; labelIter != labelSet->IteratorConstEnd(); ++labelIter)
499  {
500  const Label *label = labelIter->second;
501 
502  if (label != nullptr)
503  {
504  TemporoSpatialStringProperty *segmentNumberProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
506 
507  TemporoSpatialStringProperty *segmentLabelProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
509 
510  TemporoSpatialStringProperty *algorithmTypeProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
512 
513  TemporoSpatialStringProperty *segmentCategoryCodeValueProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
515 
516  TemporoSpatialStringProperty *segmentCategoryCodeSchemeProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
518 
519  TemporoSpatialStringProperty *segmentCategoryCodeMeaningProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
521 
522  TemporoSpatialStringProperty *segmentTypeCodeValueProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
524 
525  TemporoSpatialStringProperty *segmentTypeCodeSchemeProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
527 
528  TemporoSpatialStringProperty *segmentTypeCodeMeaningProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
530 
531  TemporoSpatialStringProperty *segmentModifierCodeValueProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
533 
534  TemporoSpatialStringProperty *segmentModifierCodeSchemeProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
536 
537  TemporoSpatialStringProperty *segmentModifierCodeMeaningProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
539 
540  dcmqi::SegmentAttributes *segmentAttribute = nullptr;
541 
542  if (segmentNumberProp->GetValue() == "")
543  {
544  MITK_ERROR << "Something went wrong with the label ID.";
545  }
546  else
547  {
548  int labelId = std::stoi(segmentNumberProp->GetValue());
549  segmentAttribute = handler.createAndGetNewSegment(labelId);
550  }
551  if (segmentAttribute != nullptr)
552  {
553  segmentAttribute->setSegmentDescription(segmentLabelProp->GetValueAsString());
554  segmentAttribute->setSegmentAlgorithmType(algorithmTypeProp->GetValueAsString());
555  segmentAttribute->setSegmentAlgorithmName("MITK Segmentation");
556  if (segmentCategoryCodeValueProp != nullptr && segmentCategoryCodeSchemeProp != nullptr &&
557  segmentCategoryCodeMeaningProp != nullptr)
558  segmentAttribute->setSegmentedPropertyCategoryCodeSequence(
559  segmentCategoryCodeValueProp->GetValueAsString(),
560  segmentCategoryCodeSchemeProp->GetValueAsString(),
561  segmentCategoryCodeMeaningProp->GetValueAsString());
562  else
563  // some default values
564  segmentAttribute->setSegmentedPropertyCategoryCodeSequence(
565  "M-01000", "SRT", "Morphologically Altered Structure");
566 
567  if (segmentTypeCodeValueProp != nullptr && segmentTypeCodeSchemeProp != nullptr &&
568  segmentTypeCodeMeaningProp != nullptr)
569  {
570  segmentAttribute->setSegmentedPropertyTypeCodeSequence(segmentTypeCodeValueProp->GetValueAsString(),
571  segmentTypeCodeSchemeProp->GetValueAsString(),
572  segmentTypeCodeMeaningProp->GetValueAsString());
573  handler.setBodyPartExamined(segmentTypeCodeMeaningProp->GetValueAsString());
574  }
575  else
576  {
577  // some default values
578  segmentAttribute->setSegmentedPropertyTypeCodeSequence("M-03000", "SRT", "Mass");
579  handler.setBodyPartExamined("Mass");
580  }
581  if (segmentModifierCodeValueProp != nullptr && segmentModifierCodeSchemeProp != nullptr &&
582  segmentModifierCodeMeaningProp != nullptr)
583  segmentAttribute->setSegmentedPropertyTypeModifierCodeSequence(
584  segmentModifierCodeValueProp->GetValueAsString(),
585  segmentModifierCodeSchemeProp->GetValueAsString(),
586  segmentModifierCodeMeaningProp->GetValueAsString());
587 
588  Color color = label->GetColor();
589  segmentAttribute->setRecommendedDisplayRGBValue(color[0] * 255, color[1] * 255, color[2] * 255);
590  }
591  }
592  }
593  return handler.getJSONOutputAsString();
594  }
595 
596  void mitk::DICOMSegmentationIO::SetLabelProperties(mitk::Label *label, dcmqi::SegmentAttributes *segmentAttribute)
597  {
598  // Segment Number:Identification number of the segment.The value of Segment Number(0062, 0004) shall be unique
599  // within the Segmentation instance in which it is created
601  TemporoSpatialStringProperty::New(std::to_string(label->GetValue())));
602 
603  // Segment Label: User-defined label identifying this segment.
606 
607  // Segment Algorithm Type: Type of algorithm used to generate the segment.
608  if (!segmentAttribute->getSegmentAlgorithmType().empty())
610  TemporoSpatialStringProperty::New(segmentAttribute->getSegmentAlgorithmType()));
611 
612  // Add Segmented Property Category Code Sequence tags
613  auto categoryCodeSequence = segmentAttribute->getSegmentedPropertyCategoryCodeSequence();
614  if (categoryCodeSequence != nullptr)
615  {
616  OFString codeValue; // (0008,0100) Code Value
617  categoryCodeSequence->getCodeValue(codeValue);
618  label->SetProperty(
620  TemporoSpatialStringProperty::New(codeValue.c_str()));
621 
622  OFString codeScheme; // (0008,0102) Coding Scheme Designator
623  categoryCodeSequence->getCodingSchemeDesignator(codeScheme);
624  label->SetProperty(
626  TemporoSpatialStringProperty::New(codeScheme.c_str()));
627 
628  OFString codeMeaning; // (0008,0104) Code Meaning
629  categoryCodeSequence->getCodeMeaning(codeMeaning);
630  label->SetProperty(
632  TemporoSpatialStringProperty::New(codeMeaning.c_str()));
633  }
634 
635  // Add Segmented Property Type Code Sequence tags
636  auto typeCodeSequence = segmentAttribute->getSegmentedPropertyTypeCodeSequence();
637  if (typeCodeSequence != nullptr)
638  {
639  OFString codeValue; // (0008,0100) Code Value
640  typeCodeSequence->getCodeValue(codeValue);
642  TemporoSpatialStringProperty::New(codeValue.c_str()));
643 
644  OFString codeScheme; // (0008,0102) Coding Scheme Designator
645  typeCodeSequence->getCodingSchemeDesignator(codeScheme);
646  label->SetProperty(
648  TemporoSpatialStringProperty::New(codeScheme.c_str()));
649 
650  OFString codeMeaning; // (0008,0104) Code Meaning
651  typeCodeSequence->getCodeMeaning(codeMeaning);
652  label->SetProperty(
654  TemporoSpatialStringProperty::New(codeMeaning.c_str()));
655  }
656 
657  // Add Segmented Property Type Modifier Code Sequence tags
658  auto modifierCodeSequence = segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence();
659  if (modifierCodeSequence != nullptr)
660  {
661  OFString codeValue; // (0008,0100) Code Value
662  modifierCodeSequence->getCodeValue(codeValue);
663  label->SetProperty(
665  TemporoSpatialStringProperty::New(codeValue.c_str()));
666 
667  OFString codeScheme; // (0008,0102) Coding Scheme Designator
668  modifierCodeSequence->getCodingSchemeDesignator(codeScheme);
669  label->SetProperty(
671  TemporoSpatialStringProperty::New(codeScheme.c_str()));
672 
673  OFString codeMeaning; // (0008,0104) Code Meaning
674  modifierCodeSequence->getCodeMeaning(codeMeaning);
675  label->SetProperty(
677  TemporoSpatialStringProperty::New(codeMeaning.c_str()));
678  }
679 
680  // Add Atomic RegionSequence tags
681  auto atomicRegionSequence = segmentAttribute->getAnatomicRegionSequence();
682  if (atomicRegionSequence != nullptr)
683  {
684  OFString codeValue; // (0008,0100) Code Value
685  atomicRegionSequence->getCodeValue(codeValue);
686  label->SetProperty(
688  TemporoSpatialStringProperty::New(codeValue.c_str()));
689 
690  OFString codeScheme; // (0008,0102) Coding Scheme Designator
691  atomicRegionSequence->getCodingSchemeDesignator(codeScheme);
692  label->SetProperty(
694  TemporoSpatialStringProperty::New(codeScheme.c_str()));
695 
696  OFString codeMeaning; // (0008,0104) Code Meaning
697  atomicRegionSequence->getCodeMeaning(codeMeaning);
698  label->SetProperty(
700  TemporoSpatialStringProperty::New(codeMeaning.c_str()));
701  }
702  }
703 
704  DICOMSegmentationIO *DICOMSegmentationIO::IOClone() const { return new DICOMSegmentationIO(*this); }
705 } // namespace
706 
707 #endif //__mitkDICOMSegmentationIO__cpp
MITKDICOMREADER_EXPORT FindingsListVectorType ExtractPathsOfInterest(const DICOMTagPathList &pathsOfInterest, const DICOMDatasetAccessingImageFrameList &frames)
LabelContainerConstIteratorType IteratorConstBegin() const
Returns a const iterator poiting to the begining of the container.
static MsgHandler handler
Definition: usUtils.cpp:261
std::map< IdentifierType, ValueType > LookupTableType
Provides the custom mime types for dicom qi objects loaded with DCMQI.
void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName="", bool fallBackOnDefaultContext=false) override
Add new or change existent property.
Definition: mitkLabel.cpp:83
LabelContainerConstIteratorType IteratorConstEnd() const
Returns a const iterator pointing to the end of the container.
#define MITK_INFO
Definition: mitkLogMacros.h:18
ConfidenceLevel GetReaderConfidenceLevel() const override
#define MITK_ERROR
Definition: mitkLogMacros.h:20
std::string MITKCORE_EXPORT GeneratePropertyNameForDICOMTag(unsigned int group, unsigned int element)
static DICOMTagPath SEGMENTED_PROPERTY_MODIFIER_SEQUENCE_PATH()
DataCollection - Class to facilitate loading/accessing structured data.
void SetValue(PixelType pixelValue)
Definition: mitkLabel.cpp:158
A data structure describing a label.
Definition: mitkLabel.h:31
ConfidenceLevel GetWriterConfidenceLevel() const override
ConfidenceLevel GetReaderConfidenceLevel() const override
Interface of DICOM tags of interest service.
MITKDICOMREADER_EXPORT std::string DICOMTagPathToPropertyName(const DICOMTagPath &tagPath)
void SetRanking(int ranking)
Set the service ranking for this file writer.
std::string GetLocalFileName() const
Get a local file name for reading.
const LookupTableType & GetLookupTable() const
void SetColor(const mitk::Color &)
Definition: mitkLabel.cpp:203
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:106
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.
std::pair< us::ServiceRegistration< IFileReader >, us::ServiceRegistration< IFileWriter > > RegisterService(us::ModuleContext *context=us::GetModuleContext())
virtual void AddTagOfInterest(const DICOMTagPath &tag, bool makePersistant=true)=0
Add an tag to the TOI. If the tag was already added it will be overwritten with the passed values...
ValueType
Type of the value held by a Value object.
Definition: jsoncpp.h:345
#define mitkThrow()
const BaseData * GetInput() const override
Get the input data set via SetInput().
const mitk::Color & GetColor() const
Definition: mitkLabel.cpp:197
A local file representation for streams.
mitk::Image::Pointer image
PixelType GetValue() const
Definition: mitkLabel.cpp:169
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
std::vector< DICOMTagPath > DICOMTagPathList
void SetActiveLayer(unsigned int layer)
MITKDICOMREADER_EXPORT void SetProperties(BaseDataPointer image, const FindingsListVectorType &findings)
void SetRanking(int ranking)
Set the service ranking for this file reader.
mitk::PropertyList::Pointer GetPropertyList() const
Get the data&#39;s property list.
mitk::BaseProperty::Pointer GetProperty(const char *propertyKey) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList, and set it to this, respectively;.
void Write() override
Write the base data to the specified location or output stream.
static Pointer New()
static Pointer New()
std::vector< DICOMDatasetAccessingImageFrameInfo::Pointer > DICOMDatasetAccessingImageFrameList
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
Definition: mitkImageCast.h:74
LabelSetImage class for handling labels and layers in a segmentation session.
MITKDICOMREADER_EXPORT mitk::IDICOMTagsOfInterest * GetDicomTagsOfInterestService()
mitk::BaseProperty * GetProperty(const std::string &propertyKey) const
Get a property by its name.
virtual DICOMTagPathMapType GetTagsOfInterest() const =0
ConfidenceLevel GetWriterConfidenceLevel() const override
static DICOMTagPath SEGMENTED_PROPERTY_CATEGORY_SEQUENCE_PATH()
std::string GetInputLocation() const override
Get the current input location.
Abstract class for implementing a reader and writer.
mitk::LabelSet * GetLabelSet(unsigned int layer=0)
Gets the mitk::LabelSet for the given layer.
std::vector< BaseData::Pointer > Read() override
Reads a number of DICOM segmentation from the file system.
void SetName(const std::string &name)
Definition: mitkLabel.cpp:146
Property for time and space resolved string values.
std::string GetName() const
Definition: mitkLabel.cpp:151