diff --git a/Modules/DICOMQI/autoload/IO/files.cmake b/Modules/DICOMQI/autoload/IO/files.cmake index b6faaec765..4a67569bd4 100644 --- a/Modules/DICOMQI/autoload/IO/files.cmake +++ b/Modules/DICOMQI/autoload/IO/files.cmake @@ -1,5 +1,6 @@ set(CPP_FILES + mitkDICOMParametricMapReaderService.cpp mitkDICOMSegmentationIO.cpp mitkDICOMQIIOMimeTypes.cpp mitkDICOMQIActivator.cpp ) diff --git a/Modules/DICOMQI/autoload/IO/mitkDICOMParametricMapReaderService.cpp b/Modules/DICOMQI/autoload/IO/mitkDICOMParametricMapReaderService.cpp new file mode 100644 index 0000000000..cf25d49bac --- /dev/null +++ b/Modules/DICOMQI/autoload/IO/mitkDICOMParametricMapReaderService.cpp @@ -0,0 +1,127 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkDICOMParametricMapReaderService.h" + +#include "mitkDICOMQIIOMimeTypes.h" +#include "mitkTemporoSpatialStringProperty.h" +#include +#include +#include +#include + +// dcmqi +#include "dcmqi/JSONParametricMapMetaInformationHandler.h" +#include + +namespace mitk +{ + DICOMParametricMapReaderService::DICOMParametricMapReaderService() + : AbstractFileReader(MitkDICOMQIIOMimeTypes::DICOMPM_MIMETYPE_NAME(), "MITK DICOM Parametric Map") + { + m_FileReaderServiceReg = RegisterService(); + } + + DICOMParametricMapReaderService::DICOMParametricMapReaderService(const DICOMParametricMapReaderService &other) + : mitk::AbstractFileReader(other) + { + } + + DICOMParametricMapReaderService::~DICOMParametricMapReaderService() {} + + std::vector> DICOMParametricMapReaderService::Read() + { + LocaleSwitch localeSwitch("C"); + + std::vector result; + Image::Pointer pmImage = Image::New(); + + const std::string path = this->GetLocalFileName(); + MITK_INFO << "loading " << path << std::endl; + + if (path.empty()) + MITK_ERROR << "Empty filename in mitk::ItkImageIO "; + + try + { + // Get the dcm data set from file path + DcmFileFormat dcmFileFormat; + OFCondition status = dcmFileFormat.loadFile(path.c_str()); + if (status.bad()) + mitkThrow() << "Can't read the input file!"; + + DcmDataset *dataSet = dcmFileFormat.getDataset(); + if (dataSet == nullptr) + mitkThrow() << "Can't read data from input file!"; + + //=============================== dcmqi part ==================================== + // Read the DICOM PM images (pmItkImage) and DICOM tags (metaInfo) + dcmqi::ParaMapConverter *converter = new dcmqi::ParaMapConverter(); + + pair dcmqiOutput = converter->paramap2itkimage(dataSet); + + itkInternalImageType::Pointer pmItkImage = dcmqiOutput.first; + + dcmqi::JSONParametricMapMetaInformationHandler metaInfo(dcmqiOutput.second.c_str()); + metaInfo.read(); + MITK_INFO << metaInfo.getJSONOutputAsString(); + //=============================================================================== + + CastToMitkImage(pmItkImage, pmImage); + } + catch (const std::exception &e) + { + MITK_ERROR << "An error occurred while reading the DICOM PM file: " << e.what(); + return result; + } + + // Get general DICOM tags of interest + auto DICOMTagsOfInterestService = GetDicomTagsOfInterestService(); + auto tagsOfInterest = DICOMTagsOfInterestService->GetTagsOfInterest(); + DICOMTagPathList tagsOfInterestList; + for (const auto &tag : tagsOfInterest) + { + tagsOfInterestList.push_back(tag.first); + } + + std::string location = GetInputLocation(); + StringList files = {location}; + DICOMDCMTKTagScanner::Pointer scanner = DICOMDCMTKTagScanner::New(); + scanner->SetInputFiles(files); + scanner->AddTagPaths(tagsOfInterestList); + scanner->Scan(); + + DICOMDatasetAccessingImageFrameList frames = scanner->GetFrameInfoList(); + if (frames.empty()) + { + MITK_ERROR << "Error reading the DICOM Seg file" << std::endl; + return result; + } + + auto findings = ExtractPathsOfInterest(tagsOfInterestList, frames); + SetProperties(pmImage, findings); + + // return the result + result.push_back(pmImage.GetPointer()); + + return result; + } + + DICOMParametricMapReaderService *DICOMParametricMapReaderService::Clone() const + { + return new DICOMParametricMapReaderService(*this); + } +} diff --git a/Modules/DICOMQI/autoload/IO/mitkDICOMParametricMapReaderService.h b/Modules/DICOMQI/autoload/IO/mitkDICOMParametricMapReaderService.h new file mode 100644 index 0000000000..d21ab3adc8 --- /dev/null +++ b/Modules/DICOMQI/autoload/IO/mitkDICOMParametricMapReaderService.h @@ -0,0 +1,54 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef MITKDICOMPARAMETRICMAPREADER_H +#define MITKDICOMPARAMETRICMAPREADER_H + +#include "MitkDICOMQIIOExports.h" +#include +#include + +#include + +namespace mitk +{ + class MITKDICOMQIIO_EXPORT DICOMParametricMapReaderService : public mitk::AbstractFileReader + { + public: + typedef IODFloatingPointImagePixelModule::value_type FloatPixelType; + typedef itk::Image itkInternalImageType; + + DICOMParametricMapReaderService(); + DICOMParametricMapReaderService(const DICOMParametricMapReaderService &other); + + virtual ~DICOMParametricMapReaderService(); + + /** + * @brief Reads DICOM parametric maps from the file system + * @return a vector of mitk::Images + * @throws throws an mitk::Exception if an error ocurrs + */ + using AbstractFileReader::Read; + virtual std::vector> Read() override; + + private: + DICOMParametricMapReaderService *Clone() const override; + + us::ServiceRegistration m_FileReaderServiceReg; + }; +} + +#endif // MITKDICOMPARAMETRICMAPREADER_H diff --git a/Modules/DICOMQI/autoload/IO/mitkDICOMQIActivator.cpp b/Modules/DICOMQI/autoload/IO/mitkDICOMQIActivator.cpp index b84c883fc7..22adf310a8 100644 --- a/Modules/DICOMQI/autoload/IO/mitkDICOMQIActivator.cpp +++ b/Modules/DICOMQI/autoload/IO/mitkDICOMQIActivator.cpp @@ -1,62 +1,65 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include "mitkDICOMSegmentationIO.h" - +#include "mitkDICOMParametricMapReaderService.h" #include "mitkDICOMQIIOMimeTypes.h" namespace mitk { /** \brief Registers services for multilabel dicom module. */ class DICOMQIIOModulActivator : public us::ModuleActivator { std::vector m_FileIOs; + std::unique_ptr m_AbstractFileReaders; public: void Load(us::ModuleContext * context) override { us::ServiceProperties props; props[us::ServiceConstants::SERVICE_RANKING()] = 10; std::vector mimeTypes = mitk::MitkDICOMQIIOMimeTypes::Get(); for (std::vector::const_iterator mimeTypeIter = mimeTypes.begin(), iterEnd = mimeTypes.end(); mimeTypeIter != iterEnd; ++mimeTypeIter) { context->RegisterService(*mimeTypeIter, props); } m_FileIOs.push_back(new DICOMSegmentationIO()); + m_AbstractFileReaders.reset(new DICOMParametricMapReaderService()); } + void Unload(us::ModuleContext *) override { for (auto &elem : m_FileIOs) { delete elem; } } }; } US_EXPORT_MODULE_ACTIVATOR(mitk::DICOMQIIOModulActivator) diff --git a/Modules/DICOMQI/autoload/IO/mitkDICOMQIIOMimeTypes.cpp b/Modules/DICOMQI/autoload/IO/mitkDICOMQIIOMimeTypes.cpp index 49d8bfcea3..67e87754b9 100644 --- a/Modules/DICOMQI/autoload/IO/mitkDICOMQIIOMimeTypes.cpp +++ b/Modules/DICOMQI/autoload/IO/mitkDICOMQIIOMimeTypes.cpp @@ -1,115 +1,163 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDICOMQIIOMimeTypes.h" #include "mitkIOMimeTypes.h" #include #include #include #include #include -// dcmqi -#include -#include - +#include namespace mitk { std::vector MitkDICOMQIIOMimeTypes::Get() { std::vector mimeTypes; // order matters here (descending rank for mime types) - mimeTypes.push_back(DICOMQI_MIMETYPE().Clone()); + mimeTypes.push_back(DICOMSEG_MIMETYPE().Clone()); + mimeTypes.push_back(DICOMPM_MIMETYPE().Clone()); return mimeTypes; } // Mime Types - - MitkDICOMQIIOMimeTypes::MitkDICOMQIMimeType::MitkDICOMQIMimeType() : CustomMimeType(DICOMQI_MIMETYPE_NAME()) + // Mime Type DICOM SEG + MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::MitkDICOMSEGMimeType() : CustomMimeType(DICOMSEG_MIMETYPE_NAME()) { this->AddExtension("dcm"); this->SetCategory(IOMimeTypes::CATEGORY_IMAGES()); this->SetComment("DICOM SEG"); } - bool MitkDICOMQIIOMimeTypes::MitkDICOMQIMimeType::AppliesTo(const std::string &path) const + bool MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::AppliesTo(const std::string &path) const { bool canRead(CustomMimeType::AppliesTo(path)); // fix for bug 18572 // Currently this function is called for writing as well as reading, in that case // the image information can of course not be read // This is a bug, this function should only be called for reading. if (!itksys::SystemTools::FileExists(path.c_str())) { return canRead; } // end fix for bug 18572 DcmFileFormat dcmFileFormat; OFCondition status = dcmFileFormat.loadFile(path.c_str()); if (status.bad()) - { canRead = false; - } if (!canRead) + return canRead; + + OFString modality; + if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good()) + { + if (modality.compare("SEG") == 0) + canRead = true; + else + canRead = false; + } + + return canRead; + } + + MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType *MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType::Clone() const + { + return new MitkDICOMSEGMimeType(*this); + } + + MitkDICOMQIIOMimeTypes::MitkDICOMSEGMimeType MitkDICOMQIIOMimeTypes::DICOMSEG_MIMETYPE() + { + return MitkDICOMSEGMimeType(); + } + + // Names + std::string MitkDICOMQIIOMimeTypes::DICOMSEG_MIMETYPE_NAME() + { + // create a unique and sensible name for this mime type + static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".image.dicom.seg"; + return name; + } + + // Mime Type DICOM PM + MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType::MitkDICOMPMMimeType() : CustomMimeType(DICOMPM_MIMETYPE_NAME()) + { + this->AddExtension("dcm"); + this->SetCategory(IOMimeTypes::CATEGORY_IMAGES()); + this->SetComment("DICOM PM"); + } + + bool MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType::AppliesTo(const std::string &path) const + { + bool canRead(CustomMimeType::AppliesTo(path)); + + // fix for bug 18572 + // Currently this function is called for writing as well as reading, in that case + // the image information can of course not be read + // This is a bug, this function should only be called for reading. + if (!itksys::SystemTools::FileExists(path.c_str())) { return canRead; } + // end fix for bug 18572 + DcmFileFormat dcmFileFormat; + OFCondition status = dcmFileFormat.loadFile(path.c_str()); + if (status.bad()) + canRead = false; + if (!canRead) + return canRead; OFString modality; if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good()) { - if (modality.compare("SEG") == 0) - { + if (modality.compare("RWV") == 0) canRead = true; - } else - { canRead = false; - } } return canRead; } - MitkDICOMQIIOMimeTypes::MitkDICOMQIMimeType *MitkDICOMQIIOMimeTypes::MitkDICOMQIMimeType::Clone() const + MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType *MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType::Clone() const { - return new MitkDICOMQIMimeType(*this); + return new MitkDICOMPMMimeType(*this); } - MitkDICOMQIIOMimeTypes::MitkDICOMQIMimeType MitkDICOMQIIOMimeTypes::DICOMQI_MIMETYPE() + MitkDICOMQIIOMimeTypes::MitkDICOMPMMimeType MitkDICOMQIIOMimeTypes::DICOMPM_MIMETYPE() { - return MitkDICOMQIMimeType(); + return MitkDICOMPMMimeType(); } // Names - std::string MitkDICOMQIIOMimeTypes::DICOMQI_MIMETYPE_NAME() + std::string MitkDICOMQIIOMimeTypes::DICOMPM_MIMETYPE_NAME() { // create a unique and sensible name for this mime type - static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".image.dicom.seg"; + static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".image.dicom.PM"; return name; } } diff --git a/Modules/DICOMQI/autoload/IO/mitkDICOMQIIOMimeTypes.h b/Modules/DICOMQI/autoload/IO/mitkDICOMQIIOMimeTypes.h index d596b88956..e44d98558e 100644 --- a/Modules/DICOMQI/autoload/IO/mitkDICOMQIIOMimeTypes.h +++ b/Modules/DICOMQI/autoload/IO/mitkDICOMQIIOMimeTypes.h @@ -1,53 +1,64 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKDICOMQIIOMIMETYPES_H #define MITKDICOMQIIOMIMETYPES_H #include "mitkCustomMimeType.h" #include namespace mitk { /// Provides the custom mime types for dicom segmentation objects loaded with DCMQI class MitkDICOMQIIOMimeTypes { public: /** Mime type that parses dicom files to determine whether they are dicom segmentation objects. - */ - class MitkDICOMQIMimeType : public CustomMimeType + */ + class MitkDICOMSEGMimeType : public CustomMimeType { public: - MitkDICOMQIMimeType(); + MitkDICOMSEGMimeType(); virtual bool AppliesTo(const std::string &path) const override; - virtual MitkDICOMQIMimeType *Clone() const override; + virtual MitkDICOMSEGMimeType *Clone() const override; }; - static MitkDICOMQIMimeType DICOMQI_MIMETYPE(); - static std::string DICOMQI_MIMETYPE_NAME(); + static MitkDICOMSEGMimeType DICOMSEG_MIMETYPE(); + static std::string DICOMSEG_MIMETYPE_NAME(); + + class MitkDICOMPMMimeType : public CustomMimeType + { + public: + MitkDICOMPMMimeType(); + virtual bool AppliesTo(const std::string &path) const override; + virtual MitkDICOMPMMimeType *Clone() const override; + }; + + static MitkDICOMPMMimeType DICOMPM_MIMETYPE(); + static std::string DICOMPM_MIMETYPE_NAME(); // Get all Mime Types static std::vector Get(); private: // purposely not implemented MitkDICOMQIIOMimeTypes(); MitkDICOMQIIOMimeTypes(const MitkDICOMQIIOMimeTypes &); }; } #endif // MITKDICOMQIIOMIMETYPES_H diff --git a/Modules/DICOMQI/autoload/IO/mitkDICOMSegmentationIO.cpp b/Modules/DICOMQI/autoload/IO/mitkDICOMSegmentationIO.cpp index ef10baed96..ece88b222f 100644 --- a/Modules/DICOMQI/autoload/IO/mitkDICOMSegmentationIO.cpp +++ b/Modules/DICOMQI/autoload/IO/mitkDICOMSegmentationIO.cpp @@ -1,700 +1,700 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkDICOMSegmentationIO__cpp #define __mitkDICOMSegmentationIO__cpp #include "mitkDICOMSegmentationIO.h" #include "mitkDICOMQIIOMimeTypes.h" #include "mitkDICOMSegmentationConstants.h" #include #include #include #include #include #include #include #include // itk #include // dcmqi #include // us #include #include namespace mitk { DICOMSegmentationIO::DICOMSegmentationIO() : AbstractFileIO(LabelSetImage::GetStaticNameOfClass(), - mitk::MitkDICOMQIIOMimeTypes::DICOMQI_MIMETYPE_NAME(), - "DICOM Segmentation") + MitkDICOMQIIOMimeTypes::DICOMSEG_MIMETYPE_NAME(), + "MITK DICOM Segmentation") { AbstractFileWriter::SetRanking(10); AbstractFileReader::SetRanking(10); this->RegisterService(); this->AddDICOMTagsToService(); } void DICOMSegmentationIO::AddDICOMTagsToService() { IDICOMTagsOfInterest *toiService = GetDicomTagsOfInterestService(); if (toiService != nullptr) { toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_SEQUENCE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_NUMBER_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_LABEL_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_ALGORITHM_TYPE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::ANATOMIC_REGION_SEQUENCE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_VALUE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_SCHEME_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_MEANING_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENTED_PROPERTY_CATEGORY_SEQUENCE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENTED_PROPERTY_TYPE_SEQUENCE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_VALUE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_SCHEME_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_MEANING_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENTED_PROPERTY_MODIFIER_SEQUENCE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_VALUE_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_SCHEME_PATH()); toiService->AddTagOfInterest(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_MEANING_PATH()); } } IFileIO::ConfidenceLevel DICOMSegmentationIO::GetWriterConfidenceLevel() const { if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; const LabelSetImage *input = static_cast(this->GetInput()); if (input) return Supported; else return Unsupported; } void DICOMSegmentationIO::Write() { ValidateOutputLocation(); - mitk::LocaleSwitch localeSwitch("C"); + LocaleSwitch localeSwitch("C"); LocalFile localFile(this); const std::string path = localFile.GetFileName(); auto input = dynamic_cast(this->GetInput()); if (input == nullptr) mitkThrow() << "Cannot write non-image data"; // Get DICOM information from referenced image vector dcmDatasets; DcmFileFormat *readFileFormat = new DcmFileFormat(); try { // TODO: Generate dcmdataset witk DICOM tags from property list; ATM the source are the filepaths from the // property list - mitk::StringLookupTableProperty::Pointer filesProp = - dynamic_cast(input->GetProperty("referenceFiles").GetPointer()); + StringLookupTableProperty::Pointer filesProp = + dynamic_cast(input->GetProperty("referenceFiles").GetPointer()); if (filesProp.IsNull()) { mitkThrow() << "No property with dicom file path."; return; } StringLookupTable filesLut = filesProp->GetValue(); const StringLookupTable::LookupTableType &lookUpTableMap = filesLut.GetLookupTable(); for (auto it : lookUpTableMap) { const char *fileName = (it.second).c_str(); if (readFileFormat->loadFile(fileName, EXS_Unknown).good()) dcmDatasets.push_back(readFileFormat->getAndRemoveDataset()); } } catch (const std::exception &e) { MITK_ERROR << "An error occurred while getting the dicom informations: " << e.what() << endl; return; } // Iterate over all layers. For each a dcm file will be generated for (unsigned int layer = 0; layer < input->GetNumberOfLayers(); ++layer) { vector segmentations; try { // Hack: Remove the const attribute to switch between the layer images. Normally you could get the different // layer images by input->GetLayerImage(layer) - mitk::LabelSetImage *mitkLayerImage = const_cast(input); + LabelSetImage *mitkLayerImage = const_cast(input); mitkLayerImage->SetActiveLayer(layer); // Cast mitk layer image to itk ImageToItk::Pointer imageToItkFilter = ImageToItk::New(); imageToItkFilter->SetInput(mitkLayerImage); imageToItkFilter->Update(); // Cast from original itk type to dcmqi input itk image type typedef itk::CastImageFilter castItkImageFilterType; castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New(); castFilter->SetInput(imageToItkFilter->GetOutput()); castFilter->Update(); itkInternalImageType::Pointer itkLabelImage = castFilter->GetOutput(); itkLabelImage->DisconnectPipeline(); // Iterate over all labels. For each label a segmentation image will be created const LabelSet *labelSet = input->GetLabelSet(layer); auto labelIter = labelSet->IteratorConstBegin(); // Ignore background label ++labelIter; for (; labelIter != labelSet->IteratorConstEnd(); ++labelIter) { // Thresold over the image with the given label value itk::ThresholdImageFilter::Pointer thresholdFilter = itk::ThresholdImageFilter::New(); thresholdFilter->SetInput(itkLabelImage); thresholdFilter->ThresholdOutside(labelIter->first, labelIter->first); thresholdFilter->SetOutsideValue(0); thresholdFilter->Update(); itkInternalImageType::Pointer segmentImage = thresholdFilter->GetOutput(); segmentImage->DisconnectPipeline(); segmentations.push_back(segmentImage); } } catch (const itk::ExceptionObject &e) { MITK_ERROR << e.GetDescription() << endl; return; } // Create segmentation meta information const std::string &tmpMetaInfoFile = this->CreateMetaDataJsonFile(layer); MITK_INFO << "Writing image: " << path << std::endl; try { // Convert itk segmentation images to dicom image dcmqi::ImageSEGConverter *converter = new dcmqi::ImageSEGConverter(); DcmDataset *result = converter->itkimage2dcmSegmentation(dcmDatasets, segmentations, tmpMetaInfoFile); // Write dicom file DcmFileFormat dcmFileFormat(result); std::string filePath = path.substr(0, path.find_last_of(".")); // If there is more than one layer, we have to write more than 1 dicom file if (input->GetNumberOfLayers() != 1) filePath = filePath + std::to_string(layer) + ".dcm"; else filePath = filePath + ".dcm"; dcmFileFormat.saveFile(filePath.c_str(), EXS_LittleEndianExplicit); // Clean up if (converter != nullptr) delete converter; if (result != nullptr) delete result; } catch (const std::exception &e) { MITK_ERROR << "An error occurred during writing the DICOM Seg: " << e.what() << endl; return; } } // Write a dcm file for the next layer // End of image writing; clean up if (readFileFormat) delete readFileFormat; for (auto obj : dcmDatasets) delete obj; dcmDatasets.clear(); } IFileIO::ConfidenceLevel DICOMSegmentationIO::GetReaderConfidenceLevel() const { if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; const std::string fileName = this->GetLocalFileName(); DcmFileFormat dcmFileFormat; OFCondition status = dcmFileFormat.loadFile(fileName.c_str()); if (status.bad()) return Unsupported; OFString modality; if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good()) { if (modality.compare("SEG") == 0) return Supported; else return Unsupported; } return Unsupported; } std::vector DICOMSegmentationIO::Read() { - mitk::LocaleSwitch localeSwitch("C"); + LocaleSwitch localeSwitch("C"); LabelSetImage::Pointer labelSetImage; std::vector result; const std::string path = this->GetLocalFileName(); MITK_INFO << "loading " << path << std::endl; if (path.empty()) mitkThrow() << "Empty filename in mitk::ItkImageIO "; try { // Get the dcm data set from file path DcmFileFormat dcmFileFormat; OFCondition status = dcmFileFormat.loadFile(path.c_str()); if (status.bad()) mitkThrow() << "Can't read the input file!"; DcmDataset *dataSet = dcmFileFormat.getDataset(); if (dataSet == nullptr) mitkThrow() << "Can't read data from input file!"; //=============================== dcmqi part ==================================== // Read the DICOM SEG images (segItkImages) and DICOM tags (metaInfo) dcmqi::ImageSEGConverter *converter = new dcmqi::ImageSEGConverter(); pair, string> dcmqiOutput = converter->dcmSegmentation2itkimage(dataSet); map segItkImages = dcmqiOutput.first; dcmqi::JSONSegmentationMetaInformationHandler metaInfo(dcmqiOutput.second.c_str()); metaInfo.read(); - MITK_INFO << "Input " << metaInfo.getJSONOutputAsString(); + MITK_INFO << metaInfo.getJSONOutputAsString(); //=============================================================================== // Get the label information from segment attributes for each itk image vector>::const_iterator segmentIter = metaInfo.segmentsAttributesMappingList.begin(); // For each itk image add a layer to the LabelSetImage output for (auto &element : segItkImages) { // Get the labeled image and cast it to mitkImage typedef itk::CastImageFilter castItkImageFilterType; castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New(); castFilter->SetInput(element.second); castFilter->Update(); Image::Pointer layerImage; CastToMitkImage(castFilter->GetOutput(), layerImage); // Get pixel value of the label itkInternalImageType::ValueType segValue = 1; typedef itk::ImageRegionIterator IteratorType; // Iterate over the image to find the pixel value of the label IteratorType iter(element.second, element.second->GetLargestPossibleRegion()); iter.GoToBegin(); while (!iter.IsAtEnd()) { itkInputImageType::PixelType value = iter.Get(); if (value != 0) { segValue = value; break; } ++iter; } // Get Segment information map map segmentMap = (*segmentIter); map::const_iterator segmentMapIter = (*segmentIter).begin(); dcmqi::SegmentAttributes *segmentAttribute = (*segmentMapIter).second; OFString labelName; if (segmentAttribute->getSegmentedPropertyTypeCodeSequence() != nullptr) { segmentAttribute->getSegmentedPropertyTypeCodeSequence()->getCodeMeaning(labelName); if (segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence() != nullptr) { OFString modifier; segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence()->getCodeMeaning(modifier); labelName.append(" (").append(modifier).append(")"); } } else { labelName = std::to_string(segmentAttribute->getLabelID()).c_str(); if (labelName.empty()) labelName = "Unnamed"; } float tmp[3] = {0.0, 0.0, 0.0}; if (segmentAttribute->getRecommendedDisplayRGBValue() != nullptr) { tmp[0] = segmentAttribute->getRecommendedDisplayRGBValue()[0] / 255.0; tmp[1] = segmentAttribute->getRecommendedDisplayRGBValue()[1] / 255.0; tmp[2] = segmentAttribute->getRecommendedDisplayRGBValue()[2] / 255.0; } Label *newLabel = nullptr; // If labelSetImage do not exists (first image) if (labelSetImage.IsNull()) { // Initialize the labelSetImage with the read image labelSetImage = LabelSetImage::New(); labelSetImage->InitializeByLabeledImage(layerImage); // Already a label was generated, so set the information to this newLabel = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer()); newLabel->SetName(labelName.c_str()); newLabel->SetColor(Color(tmp)); newLabel->SetValue(segValue); } else { // Add a new layer to the labelSetImage. Background label is set automatically labelSetImage->AddLayer(layerImage); // Add new label newLabel = new Label; newLabel->SetName(labelName.c_str()); newLabel->SetColor(Color(tmp)); newLabel->SetValue(segValue); labelSetImage->GetLabelSet(labelSetImage->GetActiveLayer())->AddLabel(newLabel); } // Add some more label properties this->SetLabelProperties(newLabel, segmentAttribute); ++segmentIter; } // Add some general DICOM Segmentation properties - mitk::IDICOMTagsOfInterest *toiSrv = GetDicomTagsOfInterestService(); + IDICOMTagsOfInterest *toiSrv = GetDicomTagsOfInterestService(); auto tagsOfInterest = toiSrv->GetTagsOfInterest(); DICOMTagPathList tagsOfInterestList; for (const auto &tag : tagsOfInterest) { tagsOfInterestList.push_back(tag.first); } - mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New(); + DICOMDCMTKTagScanner::Pointer scanner = DICOMDCMTKTagScanner::New(); scanner->SetInputFiles({GetInputLocation()}); scanner->AddTagPaths(tagsOfInterestList); scanner->Scan(); - mitk::DICOMDatasetAccessingImageFrameList frames = scanner->GetFrameInfoList(); + DICOMDatasetAccessingImageFrameList frames = scanner->GetFrameInfoList(); if (frames.empty()) { MITK_ERROR << "Error reading the DICOM Seg file" << std::endl; return result; } auto findings = ExtractPathsOfInterest(tagsOfInterestList, frames); SetProperties(labelSetImage, findings); // Set active layer to the first layer of the labelset image if (labelSetImage->GetNumberOfLayers() > 1 && labelSetImage->GetActiveLayer() != 0) labelSetImage->SetActiveLayer(0); // Clean up if (converter != nullptr) delete converter; } catch (const std::exception &e) { MITK_ERROR << "An error occurred while reading the DICOM Seg file: " << e.what(); return result; } result.push_back(labelSetImage.GetPointer()); return result; } - const std::string mitk::DICOMSegmentationIO::CreateMetaDataJsonFile(int layer) + const std::string DICOMSegmentationIO::CreateMetaDataJsonFile(int layer) { - const mitk::LabelSetImage *image = dynamic_cast(this->GetInput()); + const LabelSetImage *image = dynamic_cast(this->GetInput()); const std::string output; dcmqi::JSONSegmentationMetaInformationHandler handler; // 1. Metadata attributes that will be listed in the resulting DICOM SEG object std::string contentCreatorName; if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0070, 0x0084).c_str(), contentCreatorName)) contentCreatorName = "MITK"; handler.setContentCreatorName(contentCreatorName); std::string clinicalTrailSeriesId; if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0071).c_str(), clinicalTrailSeriesId)) clinicalTrailSeriesId = "Session 1"; handler.setClinicalTrialSeriesID(clinicalTrailSeriesId); std::string clinicalTrialTimePointID; if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0050).c_str(), clinicalTrialTimePointID)) clinicalTrialTimePointID = "0"; handler.setClinicalTrialTimePointID(clinicalTrialTimePointID); std::string clinicalTrialCoordinatingCenterName = ""; if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0060).c_str(), clinicalTrialCoordinatingCenterName)) clinicalTrialCoordinatingCenterName = "Unknown"; handler.setClinicalTrialCoordinatingCenterName(clinicalTrialCoordinatingCenterName); std::string seriesDescription; if (!image->GetPropertyList()->GetStringProperty("name", seriesDescription)) seriesDescription = "MITK Segmentation"; handler.setSeriesDescription(seriesDescription); handler.setSeriesNumber("0" + std::to_string(layer)); handler.setInstanceNumber("1"); handler.setBodyPartExamined(""); const LabelSet *labelSet = image->GetLabelSet(layer); auto labelIter = labelSet->IteratorConstBegin(); // Ignore background label ++labelIter; for (; labelIter != labelSet->IteratorConstEnd(); ++labelIter) { const Label *label = labelIter->second; if (label != nullptr) { - StringProperty *segmentNumberProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_NUMBER_PATH()).c_str())); + StringProperty *segmentNumberProp = dynamic_cast( + label->GetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_NUMBER_PATH()).c_str())); - StringProperty *segmentLabelProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_LABEL_PATH()).c_str())); + StringProperty *segmentLabelProp = dynamic_cast( + label->GetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_LABEL_PATH()).c_str())); - StringProperty *algorithmTypeProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_ALGORITHM_TYPE_PATH()).c_str())); + StringProperty *algorithmTypeProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_ALGORITHM_TYPE_PATH()).c_str())); - StringProperty *segmentCategoryCodeValueProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH()).c_str())); + StringProperty *segmentCategoryCodeValueProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH()).c_str())); - StringProperty *segmentCategoryCodeSchemeProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH()).c_str())); + StringProperty *segmentCategoryCodeSchemeProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH()).c_str())); - StringProperty *segmentCategoryCodeMeaningProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH()).c_str())); + StringProperty *segmentCategoryCodeMeaningProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH()).c_str())); - StringProperty *segmentTypeCodeValueProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_VALUE_PATH()).c_str())); + StringProperty *segmentTypeCodeValueProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_VALUE_PATH()).c_str())); - StringProperty *segmentTypeCodeSchemeProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_SCHEME_PATH()).c_str())); + StringProperty *segmentTypeCodeSchemeProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_SCHEME_PATH()).c_str())); - StringProperty *segmentTypeCodeMeaningProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_MEANING_PATH()).c_str())); + StringProperty *segmentTypeCodeMeaningProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_MEANING_PATH()).c_str())); - StringProperty *segmentModifierCodeValueProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_VALUE_PATH()).c_str())); + StringProperty *segmentModifierCodeValueProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_VALUE_PATH()).c_str())); - StringProperty *segmentModifierCodeSchemeProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_SCHEME_PATH()).c_str())); + StringProperty *segmentModifierCodeSchemeProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_SCHEME_PATH()).c_str())); - StringProperty *segmentModifierCodeMeaningProp = dynamic_cast(label->GetProperty( - mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_MEANING_PATH()).c_str())); + StringProperty *segmentModifierCodeMeaningProp = dynamic_cast(label->GetProperty( + DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_MEANING_PATH()).c_str())); dcmqi::SegmentAttributes *segmentAttribute = nullptr; if (segmentNumberProp->GetValue() == nullptr) { MITK_ERROR << "Something went wrong with the label ID."; } else { int labelId = std::stoi(segmentNumberProp->GetValue()); segmentAttribute = handler.createAndGetNewSegment(labelId); } if (segmentAttribute != nullptr) { segmentAttribute->setSegmentDescription(segmentLabelProp->GetValueAsString()); segmentAttribute->setSegmentAlgorithmType(algorithmTypeProp->GetValueAsString()); segmentAttribute->setSegmentAlgorithmName("MITK Segmentation"); if (segmentCategoryCodeValueProp != nullptr && segmentCategoryCodeSchemeProp != nullptr && segmentCategoryCodeMeaningProp != nullptr) segmentAttribute->setSegmentedPropertyCategoryCodeSequence( segmentCategoryCodeValueProp->GetValueAsString(), segmentCategoryCodeSchemeProp->GetValueAsString(), segmentCategoryCodeMeaningProp->GetValueAsString()); else // some default values segmentAttribute->setSegmentedPropertyCategoryCodeSequence( "M-01000", "SRT", "Morphologically Altered Structure"); if (segmentTypeCodeValueProp != nullptr && segmentTypeCodeSchemeProp != nullptr && segmentTypeCodeMeaningProp != nullptr) { segmentAttribute->setSegmentedPropertyTypeCodeSequence(segmentTypeCodeValueProp->GetValueAsString(), segmentTypeCodeSchemeProp->GetValueAsString(), segmentTypeCodeMeaningProp->GetValueAsString()); handler.setBodyPartExamined(segmentTypeCodeMeaningProp->GetValueAsString()); } else { // some default values segmentAttribute->setSegmentedPropertyTypeCodeSequence("M-03000", "SRT", "Mass"); handler.setBodyPartExamined("Mass"); } if (segmentModifierCodeValueProp != nullptr && segmentModifierCodeSchemeProp != nullptr && segmentModifierCodeMeaningProp != nullptr) segmentAttribute->setSegmentedPropertyTypeModifierCodeSequence( segmentModifierCodeValueProp->GetValueAsString(), segmentModifierCodeSchemeProp->GetValueAsString(), segmentModifierCodeMeaningProp->GetValueAsString()); Color color = label->GetColor(); segmentAttribute->setRecommendedDisplayRGBValue(color[0] * 255, color[1] * 255, color[2] * 255); } } } return handler.getJSONOutputAsString(); } - void mitk::DICOMSegmentationIO::SetLabelProperties(mitk::Label *label, dcmqi::SegmentAttributes *segmentAttribute) + void DICOMSegmentationIO::SetLabelProperties(Label *label, dcmqi::SegmentAttributes *segmentAttribute) { // Segment Number:Identification number of the segment.The value of Segment Number(0062, 0004) shall be unique // within the Segmentation instance in which it is created label->SetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_NUMBER_PATH()).c_str(), StringProperty::New(std::to_string(label->GetValue()))); // Segment Label: User-defined label identifying this segment. label->SetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_LABEL_PATH()).c_str(), StringProperty::New(label->GetName())); // Segment Algorithm Type: Type of algorithm used to generate the segment. if (!segmentAttribute->getSegmentAlgorithmType().empty()) label->SetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_ALGORITHM_TYPE_PATH()).c_str(), StringProperty::New(segmentAttribute->getSegmentAlgorithmType())); // Add Segmented Property Category Code Sequence tags auto categoryCodeSequence = segmentAttribute->getSegmentedPropertyCategoryCodeSequence(); if (categoryCodeSequence != nullptr) { OFString codeValue; // (0008,0100) Code Value categoryCodeSequence->getCodeValue(codeValue); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH()).c_str(), StringProperty::New(codeValue.c_str())); OFString codeScheme; // (0008,0102) Coding Scheme Designator categoryCodeSequence->getCodingSchemeDesignator(codeScheme); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH()).c_str(), StringProperty::New(codeScheme.c_str())); OFString codeMeaning; // (0008,0104) Code Meaning categoryCodeSequence->getCodeMeaning(codeMeaning); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH()).c_str(), StringProperty::New(codeMeaning.c_str())); } // Add Segmented Property Type Code Sequence tags auto typeCodeSequence = segmentAttribute->getSegmentedPropertyTypeCodeSequence(); if (typeCodeSequence != nullptr) { OFString codeValue; // (0008,0100) Code Value typeCodeSequence->getCodeValue(codeValue); label->SetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_VALUE_PATH()).c_str(), StringProperty::New(codeValue.c_str())); OFString codeScheme; // (0008,0102) Coding Scheme Designator typeCodeSequence->getCodingSchemeDesignator(codeScheme); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_SCHEME_PATH()).c_str(), StringProperty::New(codeScheme.c_str())); OFString codeMeaning; // (0008,0104) Code Meaning typeCodeSequence->getCodeMeaning(codeMeaning); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_MEANING_PATH()).c_str(), StringProperty::New(codeMeaning.c_str())); } // Add Segmented Property Type Modifier Code Sequence tags auto modifierCodeSequence = segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence(); if (modifierCodeSequence != nullptr) { OFString codeValue; // (0008,0100) Code Value modifierCodeSequence->getCodeValue(codeValue); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_VALUE_PATH()).c_str(), StringProperty::New(codeValue.c_str())); OFString codeScheme; // (0008,0102) Coding Scheme Designator modifierCodeSequence->getCodingSchemeDesignator(codeScheme); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_SCHEME_PATH()).c_str(), StringProperty::New(codeScheme.c_str())); OFString codeMeaning; // (0008,0104) Code Meaning modifierCodeSequence->getCodeMeaning(codeMeaning); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_MEANING_PATH()).c_str(), StringProperty::New(codeMeaning.c_str())); } // Add Atomic RegionSequence tags auto atomicRegionSequence = segmentAttribute->getAnatomicRegionSequence(); if (atomicRegionSequence != nullptr) { OFString codeValue; // (0008,0100) Code Value atomicRegionSequence->getCodeValue(codeValue); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_VALUE_PATH()).c_str(), StringProperty::New(codeValue.c_str())); OFString codeScheme; // (0008,0102) Coding Scheme Designator atomicRegionSequence->getCodingSchemeDesignator(codeScheme); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_SCHEME_PATH()).c_str(), StringProperty::New(codeScheme.c_str())); OFString codeMeaning; // (0008,0104) Code Meaning atomicRegionSequence->getCodeMeaning(codeMeaning); label->SetProperty( DICOMTagPathToPropertyName(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_MEANING_PATH()).c_str(), StringProperty::New(codeMeaning.c_str())); } } DICOMSegmentationIO *DICOMSegmentationIO::IOClone() const { return new DICOMSegmentationIO(*this); } } // namespace #endif //__mitkDICOMSegmentationIO__cpp