diff --git a/Modules/DICOMReaderServices/CMakeLists.txt b/Modules/DICOMReaderServices/CMakeLists.txt index 218118c204..2400f84511 100644 --- a/Modules/DICOMReaderServices/CMakeLists.txt +++ b/Modules/DICOMReaderServices/CMakeLists.txt @@ -1,6 +1,6 @@ MITK_CREATE_MODULE( DEPENDS MitkCore MitkDICOMReader PACKAGE_DEPENDS - PRIVATE ITK|ITKIOGDCM + PRIVATE ITK|ITKIOGDCM+ITKIOImageBase DCMQI DCMTK AUTOLOAD_WITH MitkCore ) diff --git a/Modules/DICOMReaderServices/files.cmake b/Modules/DICOMReaderServices/files.cmake index c8987299cc..070dd706c3 100644 --- a/Modules/DICOMReaderServices/files.cmake +++ b/Modules/DICOMReaderServices/files.cmake @@ -1,10 +1,12 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkBaseDICOMReaderService.cpp mitkAutoSelectingDICOMReaderService.cpp mitkClassicDICOMSeriesReaderService.cpp mitkDICOMReaderServicesActivator.cpp mitkDICOMFilesHelper.cpp mitkDICOMTagsOfInterestService.cpp + mitkDICOMSegmentationWriterService.cpp + #mitkDICOMSegmentationReaderService.cpp ) diff --git a/Modules/DICOMReaderServices/include/mitkDICOMSegmentationReaderService.h b/Modules/DICOMReaderServices/include/mitkDICOMSegmentationReaderService.h new file mode 100644 index 0000000000..4eccb60351 --- /dev/null +++ b/Modules/DICOMReaderServices/include/mitkDICOMSegmentationReaderService.h @@ -0,0 +1,52 @@ +/*=================================================================== + +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 _MITK_DICOM_SEGMENTATION_READER_SERVICE__H_ +#define _MITK_DICOM_SEGMENTATION_READER_SERVICE__H_ + +// MITK +#include + +namespace mitk +{ +//TODO: Docu +/** + * @internal + * + * @brief + * + * @ingroup IO + */ +class DICOMSegmentationService: public AbstractFileReader +{ +public: + + DICOMSegmentationService(); + virtual ~DICOMSegmentationService(); + + using AbstractFileReader::Read; + virtual std::vector< itk::SmartPointer > Read() override; + +private: + + DICOMSegmentationService(const DICOMSegmentationService& other); + + virtual DICOMSegmentationService* Clone() const override; +}; + +} + +#endif diff --git a/Modules/DICOMReaderServices/include/mitkDICOMSegmentationWriterService.h b/Modules/DICOMReaderServices/include/mitkDICOMSegmentationWriterService.h new file mode 100644 index 0000000000..eaf38d5860 --- /dev/null +++ b/Modules/DICOMReaderServices/include/mitkDICOMSegmentationWriterService.h @@ -0,0 +1,55 @@ +/*=================================================================== + +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 _MITK_DICOM_SEGMENTATION_WRITER_SERVICE__H_ +#define _MITK_DICOM_SEGMENTATION_WRITER_SERVICE__H_ + +#include + +namespace mitk +{ +//TODO: Docu +/** + * @internal + * + * @brief + * + * @ingroup IO + */ +class DICOMSegmentationWriterService : public AbstractFileWriter +{ +public: + + DICOMSegmentationWriterService(); + virtual ~DICOMSegmentationWriterService(); + + using AbstractFileWriter::Write; + virtual void Write() override; + + virtual ConfidenceLevel GetConfidenceLevel() const override; + +private: + + DICOMSegmentationWriterService(const DICOMSegmentationWriterService& other); + + virtual mitk::DICOMSegmentationWriterService* Clone() const override; + +}; + +} + +#endif diff --git a/Modules/DICOMReaderServices/src/mitkDICOMSegmentationReaderService.cpp b/Modules/DICOMReaderServices/src/mitkDICOMSegmentationReaderService.cpp new file mode 100644 index 0000000000..495435b4b3 --- /dev/null +++ b/Modules/DICOMReaderServices/src/mitkDICOMSegmentationReaderService.cpp @@ -0,0 +1,118 @@ +/*=================================================================== + +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. + +===================================================================*/ + +// MITK +#include "mitkDICOMSegmentationReaderService.h" +#include "mitkIOMimeTypes.h" + +// STL +#include +#include +#include + + +mitk::DICOMSegmentationReaderService::DICOMSegmentationReaderService() + : AbstractFileReader(CustomMimeType(IOMimeTypes::DICOM_MIMETYPE()), "DICOM Segmentation Reader") +{ + RegisterService(); +} + +mitk::DICOMSegmentationReaderService::~DICOMSegmentationReaderService() +{} + +std::vector< itk::SmartPointer > mitk::DICOMSegmentationReaderService::Read() +{ + //// Switch the current locale to "C" + //LocaleSwitch localeSwitch("C"); + + //std::vector< itk::SmartPointer > result; + + //InputStream stream(this); + + //TiXmlDocument doc; + //stream >> doc; + //if (!doc.Error()) + //{ + // TiXmlHandle docHandle( &doc ); + // //unsigned int pointSetCounter(0); + // for( TiXmlElement* currentPointSetElement = docHandle.FirstChildElement("point_set_file").FirstChildElement("point_set").ToElement(); + // currentPointSetElement != NULL; currentPointSetElement = currentPointSetElement->NextSiblingElement()) + // { + // mitk::PointSet::Pointer newPointSet = mitk::PointSet::New(); + + // // time geometry assembled for addition after all points + // // else the SetPoint method would already transform the points that we provide it + // mitk::ProportionalTimeGeometry::Pointer timeGeometry = mitk::ProportionalTimeGeometry::New(); + + // if(currentPointSetElement->FirstChildElement("time_series") != NULL) + // { + // for( TiXmlElement* currentTimeSeries = currentPointSetElement->FirstChildElement("time_series")->ToElement(); + // currentTimeSeries != NULL; currentTimeSeries = currentTimeSeries->NextSiblingElement()) + // { + // unsigned int currentTimeStep(0); + // TiXmlElement* currentTimeSeriesID = currentTimeSeries->FirstChildElement("time_series_id"); + + // currentTimeStep = atoi(currentTimeSeriesID->GetText()); + + // timeGeometry->Expand( currentTimeStep + 1 ); // expand (default to identity) in any case + // TiXmlElement* geometryElem = currentTimeSeries->FirstChildElement("Geometry3D"); + // if ( geometryElem ) + // { + // Geometry3D::Pointer geometry = Geometry3DToXML::FromXML(geometryElem); + // if (geometry.IsNotNull()) + // { + // timeGeometry->SetTimeStepGeometry(geometry,currentTimeStep); + // } + // else + // { + // MITK_ERROR << "Could not deserialize Geometry3D element."; + // } + // } + // else + // { + // MITK_WARN << "Fallback to legacy behavior: defining PointSet geometry as identity"; + // } + + // newPointSet = this->ReadPoints(newPointSet, currentTimeSeries, currentTimeStep); + // } + // } + // else + // { + // newPointSet = this->ReadPoints(newPointSet, currentPointSetElement, 0); + // } + + // newPointSet->SetTimeGeometry(timeGeometry); + + // result.push_back( newPointSet.GetPointer() ); + // } + //} + //else + //{ + // mitkThrow() << "Parsing error at line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc(); + //} + + //return result; +} + +mitk::DICOMSegmentationReaderService::DICOMSegmentationReaderService(const mitk::DICOMSegmentationReaderService& other) + : mitk::AbstractFileReader(other) +{ +} + +mitk::DICOMSegmentationReaderService* mitk::DICOMSegmentationReaderService::Clone() const +{ + return new mitk::DICOMSegmentationReaderService(*this); +} diff --git a/Modules/DICOMReaderServices/src/mitkDICOMSegmentationWriterService.cpp b/Modules/DICOMReaderServices/src/mitkDICOMSegmentationWriterService.cpp new file mode 100644 index 0000000000..cad55d15ef --- /dev/null +++ b/Modules/DICOMReaderServices/src/mitkDICOMSegmentationWriterService.cpp @@ -0,0 +1,122 @@ +/*=================================================================== + +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 "mitkDICOMSegmentationWriterService.h" +#include "mitkIOMimeTypes.h" +#include "mitkLocaleSwitch.h" +#include "mitkImage.h" +#include "mitkImageToItk.h" +#include "ImageSEGConverter.h" + +#include + + +mitk::DICOMSegmentationWriterService::DICOMSegmentationWriterService() + : AbstractFileWriter(mitk::Image::GetStaticNameOfClass(), CustomMimeType(IOMimeTypes::DICOM_MIMETYPE()), "DICOM Segmentation Writer") +{ + RegisterService(); +} + +mitk::DICOMSegmentationWriterService::DICOMSegmentationWriterService(const mitk::DICOMSegmentationWriterService& other) + : AbstractFileWriter(other) +{ +} + +mitk::DICOMSegmentationWriterService::~DICOMSegmentationWriterService() +{ +} + +void mitk::DICOMSegmentationWriterService::Write() +{ + typedef itk::Image ImageType; + vector segmentations; + + // Switch the current locale to "C" + LocaleSwitch localeSwitch("C"); + + LocalFile localFile(this); + const std::string path = localFile.GetFileName(); + + //1. Handle segmentation as image + const mitk::Image* image = dynamic_cast(this->GetInput()); + + if (image == NULL) + { + mitkThrow() << "Cannot write non-image data"; + } + + + ImageToItk::Pointer imageToItkFilter = ImageToItk::New(); + try + { + imageToItkFilter->SetInput(image); + } + catch (const itk::ExceptionObject &e) + { + // Most probably the input image type is wrong. Binary images are expected to be + // >unsigned< char images. + MITK_ERROR << e.GetDescription() << endl; + return; + } + + imageToItkFilter->Update(); + ImageType::Pointer itkImage = imageToItkFilter->GetOutput(); + + segmentations.push_back(itkImage); + + //TODO: 2. LabelSetImage + try + { + //TODO: Fill dcmDatasets with information + vector dcmDatasets; + //TODO: Fill meta data with information + const std::string &tmpMetaInfoFile = ""; + + MITK_INFO << "Writing image: " << path << std::endl; + + //Convert itk image to dicom image + dcmqi::ImageSEGConverter* converter = new dcmqi::ImageSEGConverter(); + DcmDataset* result = converter->itkimage2dcmSegmentation(dcmDatasets, segmentations, tmpMetaInfoFile); + + //write dicom file + DcmFileFormat dcmFileFormat(result); + //TODO: Check if path contains filename with ending .dcm + dcmFileFormat.saveFile(path.c_str(), EXS_LittleEndianExplicit); + } + catch (const std::exception& e) + { + mitkThrow() << e.what(); + } + +} + +mitk::DICOMSegmentationWriterService*mitk::DICOMSegmentationWriterService::Clone() const +{ + return new DICOMSegmentationWriterService(*this); +} + +mitk::IFileWriter::ConfidenceLevel mitk::DICOMSegmentationWriterService::GetConfidenceLevel() const +{//TODO check if segmentation with dicom infos + mitk::Image::ConstPointer input = dynamic_cast(this->GetInput()); + if (input.IsNull() /*|| !mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(input)*/) + { + return Unsupported; + } + else + { + return Supported; + } +} \ No newline at end of file