diff --git a/Modules/Core/src/IO/mitkDicomSeriesReaderService.cpp b/Modules/Core/src/IO/mitkDicomSeriesReaderService.cpp index f8a6b20d78..96b7722800 100644 --- a/Modules/Core/src/IO/mitkDicomSeriesReaderService.cpp +++ b/Modules/Core/src/IO/mitkDicomSeriesReaderService.cpp @@ -1,134 +1,134 @@ /*=================================================================== 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 "mitkDicomSeriesReaderService.h" #include <mitkCustomMimeType.h> #include <mitkIOMimeTypes.h> #include <mitkDicomSeriesReader.h> #include <mitkProgressBar.h> #include <mitkImage.h> #include <iostream> namespace mitk { DicomSeriesReaderService::DicomSeriesReaderService() - : AbstractFileReader(CustomMimeType(IOMimeTypes::DICOM_MIMETYPE()), "MITK DICOM Reader") + : AbstractFileReader(CustomMimeType(IOMimeTypes::DICOM_MIMETYPE()), "Classic MITK DICOM Reader") { this->RegisterService(); } std::vector<itk::SmartPointer<BaseData> > DicomSeriesReaderService::Read() { std::vector<BaseData::Pointer> result; const char* previousCLocale = setlocale(LC_NUMERIC, NULL); setlocale(LC_NUMERIC, "C"); std::locale previousCppLocale( std::cin.getloc() ); std::locale l( "C" ); std::cin.imbue(l); std::string fileName = this->GetLocalFileName(); if ( DicomSeriesReader::IsPhilips3DDicom(fileName) ) { MITK_INFO << "it is a Philips3D US Dicom file" << std::endl; DataNode::Pointer node = DataNode::New(); mitk::DicomSeriesReader::StringContainer stringvec; stringvec.push_back(fileName); if (DicomSeriesReader::LoadDicomSeries(stringvec, *node)) { BaseData::Pointer data = node->GetData(); StringProperty::Pointer nameProp = StringProperty::New(itksys::SystemTools::GetFilenameName(fileName)); data->GetPropertyList()->SetProperty("name", nameProp); result.push_back(data); } setlocale(LC_NUMERIC, previousCLocale); std::cin.imbue(previousCppLocale); return result; } DicomSeriesReader::FileNamesGrouping imageBlocks = DicomSeriesReader::GetSeries(itksys::SystemTools::GetFilenamePath(fileName), true); // true = group gantry tilt images const unsigned int size = imageBlocks.size(); ProgressBar::GetInstance()->AddStepsToDo(size); ProgressBar::GetInstance()->Progress(); unsigned int outputIndex = 0u; const DicomSeriesReader::FileNamesGrouping::const_iterator n_end = imageBlocks.end(); for (DicomSeriesReader::FileNamesGrouping::const_iterator n_it = imageBlocks.begin(); n_it != n_end; ++n_it) { const std::string &uid = n_it->first; DataNode::Pointer node = DataNode::New(); const DicomSeriesReader::ImageBlockDescriptor& imageBlockDescriptor( n_it->second ); MITK_INFO << "--------------------------------------------------------------------------------"; MITK_INFO << "DicomSeriesReader: Loading DICOM series " << outputIndex << ": Series UID " << imageBlockDescriptor.GetSeriesInstanceUID() << std::endl; MITK_INFO << " " << imageBlockDescriptor.GetFilenames().size() << " '" << imageBlockDescriptor.GetModality() << "' files (" << imageBlockDescriptor.GetSOPClassUIDAsString() << ") loaded into 1 mitk::Image"; MITK_INFO << " multi-frame: " << (imageBlockDescriptor.IsMultiFrameImage()?"Yes":"No"); MITK_INFO << " reader support: " << DicomSeriesReader::ReaderImplementationLevelToString(imageBlockDescriptor.GetReaderImplementationLevel()); MITK_INFO << " pixel spacing type: " << DicomSeriesReader::PixelSpacingInterpretationToString( imageBlockDescriptor.GetPixelSpacingType() ); MITK_INFO << " gantry tilt corrected: " << (imageBlockDescriptor.HasGantryTiltCorrected()?"Yes":"No"); MITK_INFO << " 3D+t: " << (imageBlockDescriptor.HasMultipleTimePoints()?"Yes":"No"); MITK_INFO << "--------------------------------------------------------------------------------"; if (DicomSeriesReader::LoadDicomSeries(n_it->second.GetFilenames(), *node, true, true, true)) { BaseData::Pointer data = node->GetData(); PropertyList::Pointer dataProps = data->GetPropertyList(); std::string nodeName(uid); std::string studyDescription; if ( dataProps->GetStringProperty( "dicom.study.StudyDescription", studyDescription ) ) { nodeName = studyDescription; std::string seriesDescription; if ( dataProps->GetStringProperty( "dicom.series.SeriesDescription", seriesDescription ) ) { nodeName += "/" + seriesDescription; } } StringProperty::Pointer nameProp = StringProperty::New(nodeName); data->SetProperty("name", nameProp); result.push_back(data); ++outputIndex; } else { MITK_ERROR << "DicomSeriesReader: Skipping series " << outputIndex << " due to some unspecified error..." << std::endl; } ProgressBar::GetInstance()->Progress(); } setlocale(LC_NUMERIC, previousCLocale); std::cin.imbue(previousCppLocale); return result; } DicomSeriesReaderService* DicomSeriesReaderService::Clone() const { return new DicomSeriesReaderService(*this); } } diff --git a/Modules/DICOMReaderServices/CMakeLists.txt b/Modules/DICOMReaderServices/CMakeLists.txt new file mode 100644 index 0000000000..e6e85fa8e6 --- /dev/null +++ b/Modules/DICOMReaderServices/CMakeLists.txt @@ -0,0 +1,5 @@ +MITK_CREATE_MODULE( + DEPENDS MitkCore MitkDICOMReader + PACKAGE_DEPENDS + PRIVATE ITK|ITKIOGDCM +) diff --git a/Modules/DICOMReaderServices/files.cmake b/Modules/DICOMReaderServices/files.cmake new file mode 100644 index 0000000000..c16bb0e0c0 --- /dev/null +++ b/Modules/DICOMReaderServices/files.cmake @@ -0,0 +1,7 @@ +file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") + +set(CPP_FILES + mitkAutoSelectingDICOMReaderService.cpp + mitkDICOMReaderServicesActivator.cpp + mitkDICOMFilesHelper.cpp +) diff --git a/Modules/DICOMReaderServices/include/mitkAutoSelectingDICOMReaderService.h b/Modules/DICOMReaderServices/include/mitkAutoSelectingDICOMReaderService.h new file mode 100644 index 0000000000..6b67339cc5 --- /dev/null +++ b/Modules/DICOMReaderServices/include/mitkAutoSelectingDICOMReaderService.h @@ -0,0 +1,43 @@ +/*=================================================================== + +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 MITKAUTOSELECTINGDICOMREADERSERVICE_H +#define MITKAUTOSELECTINGDICOMREADERSERVICE_H + +#include <mitkAbstractFileReader.h> + +namespace mitk { + + /** + Service wrapper that auto selects (using the mitk::DICOMFileReaderSelector) the best DICOMFileReader from + the DICOMReader module. + */ +class AutoSelectingDICOMReaderService : public AbstractFileReader +{ +public: + AutoSelectingDICOMReaderService(); + + using AbstractFileReader::Read; + virtual std::vector<itk::SmartPointer<BaseData> > Read() override; + +private: + + virtual AutoSelectingDICOMReaderService* Clone() const override; +}; + +} + +#endif // MITKDICOMSERIESREADERSERVICE_H diff --git a/Modules/DICOMReaderServices/include/mitkDICOMFilesHelper.h b/Modules/DICOMReaderServices/include/mitkDICOMFilesHelper.h new file mode 100644 index 0000000000..e355270b00 --- /dev/null +++ b/Modules/DICOMReaderServices/include/mitkDICOMFilesHelper.h @@ -0,0 +1,41 @@ +/*=================================================================== + +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 MITKDICOMFILESHELPER_H +#define MITKDICOMFILESHELPER_H + +#include <string> +#include <vector> + +#include <MitkDICOMReaderExports.h> + +namespace mitk { + +typedef std::vector<std::string> DICOMFilePathList; + +/** Helper functions. Searches for all files in the directory of the passed file path. + All files will be checked if they are DICOM files. All DICOM files will be added to the result and + returned. + @remark The helper does no sorting of any kind.*/ +DICOMFilePathList MITKDICOMREADER_EXPORT GetDICOMFilesInSameDirectory(const std::string& filePath); + +/** All passed files will be checked if they are DICOM files. +All DICOM files will be added to the result and returned. +@remark The helper does no sorting of any kind.*/ +DICOMFilePathList MITKDICOMREADER_EXPORT FilterForDICOMFiles(const DICOMFilePathList& fileList); +} + +#endif // MITKDICOMFILESHELPER_H diff --git a/Modules/DICOMReaderServices/src/mitkAutoSelectingDICOMReaderService.cpp b/Modules/DICOMReaderServices/src/mitkAutoSelectingDICOMReaderService.cpp new file mode 100644 index 0000000000..721f49db7e --- /dev/null +++ b/Modules/DICOMReaderServices/src/mitkAutoSelectingDICOMReaderService.cpp @@ -0,0 +1,92 @@ +/*=================================================================== + +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 "mitkAutoSelectingDICOMReaderService.h" + +#include <mitkCustomMimeType.h> +#include <mitkIOMimeTypes.h> +#include <mitkDICOMFileReaderSelector.h> +#include <mitkImage.h> +#include <mitkDICOMFilesHelper.h> + +#include <iostream> + +namespace mitk { + +AutoSelectingDICOMReaderService::AutoSelectingDICOMReaderService() + : AbstractFileReader(CustomMimeType(IOMimeTypes::DICOM_MIMETYPE()), "MITK DICOM Reader (auto)") +{ + this->RegisterService(); +} + +std::vector<itk::SmartPointer<BaseData> > AutoSelectingDICOMReaderService::Read() +{ + std::vector<BaseData::Pointer> result; + std::string fileName = this->GetLocalFileName(); + + mitk::StringList relevantFiles = mitk::GetDICOMFilesInSameDirectory(fileName); + + mitk::DICOMFileReaderSelector::Pointer selector = mitk::DICOMFileReaderSelector::New(); + + selector->LoadBuiltIn3DConfigs(); + selector->LoadBuiltIn3DnTConfigs(); + selector->SetInputFiles(relevantFiles); + + mitk::DICOMFileReader::Pointer reader = selector->GetFirstReaderWithMinimumNumberOfOutputImages(); + + reader->SetInputFiles(relevantFiles); + reader->AnalyzeInputFiles(); + reader->LoadImages(); + + for (unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i) + { + const mitk::DICOMImageBlockDescriptor& desc = reader->GetOutput(i); + mitk::BaseData::Pointer data = desc.GetMitkImage(); + + std::string nodeName = "Unamed_DICOM"; + + std::string studyDescription = desc.GetPropertyAsString("studyDescription"); + std::string seriesDescription = desc.GetPropertyAsString("seriesDescription"); + + if (!studyDescription.empty()) + { + nodeName = studyDescription; + } + + if (!seriesDescription.empty()) + { + if (!studyDescription.empty()) + { + nodeName += "/"; + } + nodeName += seriesDescription; + } + + StringProperty::Pointer nameProp = StringProperty::New(nodeName); + data->SetProperty("name", nameProp); + + result.push_back(data); + } + + return result; +} + +AutoSelectingDICOMReaderService* AutoSelectingDICOMReaderService::Clone() const +{ + return new AutoSelectingDICOMReaderService(*this); +} + +} diff --git a/Modules/DICOMReaderServices/src/mitkDICOMFilesHelper.cpp b/Modules/DICOMReaderServices/src/mitkDICOMFilesHelper.cpp new file mode 100644 index 0000000000..84edcb0986 --- /dev/null +++ b/Modules/DICOMReaderServices/src/mitkDICOMFilesHelper.cpp @@ -0,0 +1,53 @@ +/*=================================================================== + +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 "mitkDICOMFilesHelper.h" + +#include <itkGDCMImageIO.h> +#include <itksys/SystemTools.hxx> +#include <gdcmDirectory.h> + +mitk::DICOMFilePathList mitk::GetDICOMFilesInSameDirectory(const std::string& filePath) +{ + DICOMFilePathList result; + + if (!filePath.empty()) + { + std::string dir = itksys::SystemTools::GetFilenamePath(filePath); + + gdcm::Directory directoryLister; + directoryLister.Load(dir.c_str(), false); // non-recursive + result = FilterForDICOMFiles(directoryLister.GetFilenames()); + } + + return result; +}; + +mitk::DICOMFilePathList mitk::FilterForDICOMFiles(const DICOMFilePathList& fileList) +{ + mitk::DICOMFilePathList result; + + itk::GDCMImageIO::Pointer io = itk::GDCMImageIO::New(); + for (auto aFile : fileList) + { + if (io->CanReadFile(aFile.c_str())) + { + result.push_back(aFile); + } + } + + return result; +}; diff --git a/Modules/DICOMReaderServices/src/mitkDICOMReaderServicesActivator.cpp b/Modules/DICOMReaderServices/src/mitkDICOMReaderServicesActivator.cpp new file mode 100644 index 0000000000..4ad13a18f9 --- /dev/null +++ b/Modules/DICOMReaderServices/src/mitkDICOMReaderServicesActivator.cpp @@ -0,0 +1,34 @@ +/*=================================================================== + +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 "mitkDICOMReaderServicesActivator.h" + +#include "mitkAutoSelectingDICOMReaderService.h" + +namespace mitk { + + void DICOMReaderServicesActivator::Load(us::ModuleContext*) + { + m_AutoSelectingDICOMReader.reset(new AutoSelectingDICOMReaderService()); + } + + void DICOMReaderServicesActivator::Unload(us::ModuleContext*) + { + } + +} + +US_EXPORT_MODULE_ACTIVATOR(mitk::DICOMReaderServicesActivator) diff --git a/Modules/DICOMReaderServices/src/mitkDICOMReaderServicesActivator.h b/Modules/DICOMReaderServices/src/mitkDICOMReaderServicesActivator.h new file mode 100644 index 0000000000..c93d3bdbae --- /dev/null +++ b/Modules/DICOMReaderServices/src/mitkDICOMReaderServicesActivator.h @@ -0,0 +1,42 @@ +/*=================================================================== + +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 MITKDICOMREADERSERVICESACTIVATOR_H +#define MITKDICOMREADERSERVICESACTIVATOR_H + +#include <usModuleActivator.h> + +#include <memory> + +namespace mitk { + +struct IFileReader; + +class DICOMReaderServicesActivator : public us::ModuleActivator +{ +public: + + void Load(us::ModuleContext*context) override; + void Unload(us::ModuleContext* context) override; + +private: + + std::unique_ptr<IFileReader> m_AutoSelectingDICOMReader; +}; + +} + +#endif // MITKDICOMREADERSERVICESACTIVATOR_H diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index 0f7d96d5ba..e92a7d6f91 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,76 +1,77 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(mitk_modules Core CommandLine AppUtil DCMTesting RDF LegacyIO DataTypesExt Overlays LegacyGL AlgorithmsExt MapperExt DICOMReader + DICOMReaderServices DICOMTesting Qt4Qt5TestModule SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction ImageStatistics LegacyAdaptors SceneSerialization GraphAlgorithms Multilabel ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation OpenViewCore QmlItems QtWidgets QtWidgetsExt SegmentationUI DiffusionImaging GPGPU OpenIGTLink IGTBase IGT CameraCalibration RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI US USUI DicomUI Simulation Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI VtkShaders DicomRT RTUI IOExt XNAT TubeGraph BiophotonicsHardware Classification TumorInvasionAnalysis ) if(MITK_ENABLE_PIC_READER) list(APPEND mitk_modules IpPicSupportIO) endif()