diff --git a/CMake/FindDCMTK.cmake b/CMake/FindDCMTK.cmake index 1ebd82cb10..7996817cd4 100644 --- a/CMake/FindDCMTK.cmake +++ b/CMake/FindDCMTK.cmake @@ -1,180 +1,183 @@ # adapted version of FindDCMTK, better suited for super-builds # - find DCMTK libraries and applications # # DCMTK_INCLUDE_DIRS - Directories to include to use DCMTK # DCMTK_LIBRARIES - Files to link against to use DCMTK # DCMTK_FOUND - If false, don't try to use DCMTK # DCMTK_DIR - (optional) Source directory for DCMTK # # DCMTK_DIR can be used to make it simpler to find the various include # directories and compiled libraries if you've just compiled it in the # source tree. Just set it to the root of the tree where you extracted # the source (default to /usr/include/dcmtk/) #============================================================================= # Copyright 2004-2009 Kitware, Inc. # Copyright 2009-2010 Mathieu Malaterre # Copyright 2010 Thomas Sondergaard # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distributed this file outside of CMake, substitute the full # License text for the above reference.) # # Written for VXL by Amitha Perera. # Upgraded for GDCM by Mathieu Malaterre. # Modified for EasyViz by Thomas Sondergaard. # # prefer DCMTK_DIR over default system paths like /usr/lib set(CMAKE_PREFIX_PATH ${DCMTK_DIR}/lib ${CMAKE_PREFIX_PATH}) # this is given to FIND_LIBRARY or FIND_PATH if(NOT DCMTK_FOUND AND NOT DCMTK_DIR) set(DCMTK_DIR "/usr/include/dcmtk/" CACHE PATH "Root of DCMTK source tree (optional).") mark_as_advanced(DCMTK_DIR) endif() # Find all libraries, store debug and release separately foreach(lib dcmpstat dcmsr dcmsign dcmtls dcmqrdb dcmnet dcmjpeg dcmimage dcmimgle dcmdata + dcmrt oflog ofstd ijg12 ijg16 ijg8 ) # Find Release libraries find_library(DCMTK_${lib}_LIBRARY_RELEASE ${lib} PATHS ${DCMTK_DIR}/${lib}/libsrc ${DCMTK_DIR}/${lib}/libsrc/Release ${DCMTK_DIR}/${lib}/Release ${DCMTK_DIR}/lib ${DCMTK_DIR}/lib/Release ${DCMTK_DIR}/dcmjpeg/lib${lib}/Release NO_DEFAULT_PATH ) # Find Debug libraries find_library(DCMTK_${lib}_LIBRARY_DEBUG ${lib} PATHS ${DCMTK_DIR}/${lib}/libsrc ${DCMTK_DIR}/${lib}/libsrc/Debug ${DCMTK_DIR}/${lib}/Debug ${DCMTK_DIR}/lib ${DCMTK_DIR}/lib/Debug ${DCMTK_DIR}/dcmjpeg/lib${lib}/Debug NO_DEFAULT_PATH ) mark_as_advanced(DCMTK_${lib}_LIBRARY_RELEASE) mark_as_advanced(DCMTK_${lib}_LIBRARY_DEBUG) # Add libraries to variable according to build type set(DCMTK_${lib}_LIBRARY) if(DCMTK_${lib}_LIBRARY_RELEASE) list(APPEND DCMTK_LIBRARIES optimized ${DCMTK_${lib}_LIBRARY_RELEASE}) list(APPEND DCMTK_${lib}_LIBRARY optimized ${DCMTK_${lib}_LIBRARY_RELEASE}) endif() if(DCMTK_${lib}_LIBRARY_DEBUG) list(APPEND DCMTK_LIBRARIES debug ${DCMTK_${lib}_LIBRARY_DEBUG}) list(APPEND DCMTK_${lib}_LIBRARY debug ${DCMTK_${lib}_LIBRARY_DEBUG}) endif() endforeach() set(DCMTK_config_TEST_HEADER osconfig.h) set(DCMTK_dcmdata_TEST_HEADER dctypes.h) set(DCMTK_dcmimage_TEST_HEADER dicoimg.h) set(DCMTK_dcmimgle_TEST_HEADER dcmimage.h) set(DCMTK_dcmjpeg_TEST_HEADER djdecode.h) set(DCMTK_dcmnet_TEST_HEADER assoc.h) set(DCMTK_dcmpstat_TEST_HEADER dcmpstat.h) set(DCMTK_dcmqrdb_TEST_HEADER dcmqrdba.h) set(DCMTK_dcmsign_TEST_HEADER sicert.h) set(DCMTK_dcmsr_TEST_HEADER dsrtree.h) set(DCMTK_dcmtls_TEST_HEADER tlslayer.h) set(DCMTK_ofstd_TEST_HEADER ofstdinc.h) +set(DCMTK_dcmrt_TEST_HEADER drtstrct.h) foreach(dir config dcmdata dcmimage dcmimgle dcmjpeg dcmnet dcmpstat dcmqrdb dcmsign dcmsr dcmtls + dcmrt ofstd) find_path(DCMTK_${dir}_INCLUDE_DIR ${DCMTK_${dir}_TEST_HEADER} PATHS ${DCMTK_DIR}/${dir}/include ${DCMTK_DIR}/${dir} ${DCMTK_DIR}/include/dcmtk/${dir} ${DCMTK_DIR}/include/${dir}) mark_as_advanced(DCMTK_${dir}_INCLUDE_DIR) #message("** DCMTKs ${dir} found at ${DCMTK_${dir}_INCLUDE_DIR}") if(DCMTK_${dir}_INCLUDE_DIR) list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_${dir}_INCLUDE_DIR}) endif() endforeach() if(WIN32) list(APPEND DCMTK_LIBRARIES netapi32 wsock32) endif() if(DCMTK_ofstd_INCLUDE_DIR) get_filename_component(DCMTK_dcmtk_INCLUDE_DIR ${DCMTK_ofstd_INCLUDE_DIR} PATH CACHE) list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_dcmtk_INCLUDE_DIR}) mark_as_advanced(DCMTK_dcmtk_INCLUDE_DIR) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DCMTK DEFAULT_MSG DCMTK_config_INCLUDE_DIR DCMTK_ofstd_INCLUDE_DIR DCMTK_ofstd_LIBRARY DCMTK_dcmdata_INCLUDE_DIR DCMTK_dcmdata_LIBRARY DCMTK_dcmimgle_INCLUDE_DIR DCMTK_dcmimgle_LIBRARY ) # Compatibility: This variable is deprecated set(DCMTK_INCLUDE_DIR ${DCMTK_INCLUDE_DIRS}) diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index 0ba98bf6e5..495bff51bb 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -1,77 +1,78 @@ # Modules must be listed according to their dependencies set(module_dirs DataTypesExt AlgorithmsExt MapperExt IOExt Qt4Qt5TestModule SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction ImageStatistics LegacyAdaptors IpPicSupport Ext SceneSerialization GraphAlgorithms ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation OpenViewCore QmlItems QtWidgets QtWidgetsExt SegmentationUI DiffusionImaging GPGPU IGTBase IGT CameraCalibration RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport Overlays InputDevices ToFHardware ToFProcessing ToFUI US USUI DicomUI Simulation Remeshing Python Persistence IGTUI VtkShaders + DicomRT ) if(MITK_ENABLE_PIC_READER) list(APPEND module_dirs IpPicSupportIO) endif() set(MITK_DEFAULT_SUBPROJECTS MITK-Modules) foreach(module_dir ${module_dirs}) add_subdirectory(${module_dir}) endforeach() if(MITK_PRIVATE_MODULES) file(GLOB all_subdirs RELATIVE ${MITK_PRIVATE_MODULES} ${MITK_PRIVATE_MODULES}/*) foreach(subdir ${all_subdirs}) string(FIND ${subdir} "." _result) if(_result EQUAL -1) if(EXISTS ${MITK_PRIVATE_MODULES}/${subdir}/CMakeLists.txt) message(STATUS "Found private module ${subdir}") add_subdirectory(${MITK_PRIVATE_MODULES}/${subdir} private_modules/${subdir}) endif() endif() endforeach() endif(MITK_PRIVATE_MODULES) diff --git a/Modules/DicomRT/CMakeLists.txt b/Modules/DicomRT/CMakeLists.txt new file mode 100644 index 0000000000..56e50c2ab7 --- /dev/null +++ b/Modules/DicomRT/CMakeLists.txt @@ -0,0 +1,12 @@ +# CREATE MODULE HERE +IF (NOT DEFINED DCMTK_dcmrt_LIBRARY OR DCMTK_dcmrt_LIBRARY) +MITK_CREATE_MODULE( + INCLUDE_DIRS DataStructures + DEPENDS MitkSegmentation MitkSceneSerializationBase + PACKAGE_DEPENDS DCMTK + QT_MODULE +) +ADD_SUBDIRECTORY(Testing) +ELSE() +MESSAGE("MITK DicomRT Support disabled because the DCMTK dcmrt library not found") +ENDIF() diff --git a/Modules/DicomRT/Testing/CMakeLists.txt b/Modules/DicomRT/Testing/CMakeLists.txt new file mode 100644 index 0000000000..153cd81e2e --- /dev/null +++ b/Modules/DicomRT/Testing/CMakeLists.txt @@ -0,0 +1 @@ +MITK_CREATE_MODULE_TESTS() diff --git a/Modules/DicomRT/Testing/files.cmake b/Modules/DicomRT/Testing/files.cmake new file mode 100644 index 0000000000..a8c3f2d6c5 --- /dev/null +++ b/Modules/DicomRT/Testing/files.cmake @@ -0,0 +1,3 @@ +SET(MODULE_TESTS + mitkRTDoseReaderTest.cpp +) diff --git a/Modules/DicomRT/Testing/mitkRTDoseReaderTest.cpp b/Modules/DicomRT/Testing/mitkRTDoseReaderTest.cpp new file mode 100644 index 0000000000..122349cae6 --- /dev/null +++ b/Modules/DicomRT/Testing/mitkRTDoseReaderTest.cpp @@ -0,0 +1,28 @@ +/*=================================================================== + +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 "mitkTestingMacros.h" +#include "mitkRTDoseReader.h" +#include + + +int mitkRTDoseReaderTest(int argc , char* argv[]) +{ + // always start with this! + MITK_TEST_BEGIN("DicomRTReader") + + MITK_TEST_END() +} diff --git a/Modules/DicomRT/files.cmake b/Modules/DicomRT/files.cmake new file mode 100644 index 0000000000..41bcf84e33 --- /dev/null +++ b/Modules/DicomRT/files.cmake @@ -0,0 +1,24 @@ +SET(CPP_FILES + mitkRTDoseReader.cpp + DataStructures/mitkRTConstants.cpp + DataStructures/mitkIsoDoseLevel.cpp + DataStructures/mitkIsoDoseLevelCollections.cpp + DataStructures/mitkIsoDoseLevelSetProperty.cpp + DataStructures/mitkIsoDoseLevelVectorProperty.cpp +) + +set(H_FILES + mitkRTDoseReader.h + DataStructures/mitkIsoDoseLevel.h + DataStructures/mitkIsoDoseLevelCollections.h + DataStructures/mitkIsoDoseLevelSetProperty.h + DataStructures/mitkIsoDoseLevelVectorProperty.h + DataStructures/mitkDoseValueType.h + DataStructures/mitkRTConstants.h +) + +set(TPP_FILES +) + +set(MOC_H_FILES +) diff --git a/Modules/DicomRT/mitkRTDoseReader.cpp b/Modules/DicomRT/mitkRTDoseReader.cpp new file mode 100644 index 0000000000..e96ead1d9e --- /dev/null +++ b/Modules/DicomRT/mitkRTDoseReader.cpp @@ -0,0 +1,137 @@ +/*=================================================================== + +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 "mitkRTDoseReader.h" + +#include +#include +#include +#include +#include +#include + +#include + +namespace mitk +{ + + RTDoseReader::RTDoseReader(){} + + RTDoseReader::~RTDoseReader(){} + + mitk::DataNode::Pointer RTDoseReader:: + LoadRTDose(DcmDataset* dataset, char* filename) + { + std::string name = filename; + itk::FilenamesContainer file; + file.push_back(name); + + mitk::DicomSeriesReader* reader = new mitk::DicomSeriesReader; + + mitk::DataNode::Pointer originalNode = reader->LoadDicomSeries(file,false); + + if(originalNode.IsNull()) + { + MITK_ERROR << "Error reading the dcm file" << endl; + return 0; + } + + mitk::Image::Pointer originalImage + = dynamic_cast(originalNode->GetData()); + + DRTDoseIOD doseObject; + OFCondition result = doseObject.read(*dataset); + + if(result.bad()) + { + MITK_ERROR << "Error reading the Dataset" << endl; + return 0; + } + + OFString gridScaling; + Float32 gridscale; + + doseObject.getDoseGridScaling(gridScaling); + gridscale = OFStandard::atof(gridScaling.c_str()); + + AccessByItk_1(originalImage, MultiplayGridScaling, gridscale); + + double prescripeDose = this->GetMaxDoseValue(dataset); + + originalNode->SetName("RT Dose"); + originalNode->SetFloatProperty(mitk::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),prescripeDose); + originalNode->SetFloatProperty(mitk::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), 40); + originalNode->SetBoolProperty(mitk::Constants::DOSE_PROPERTY_NAME.c_str(),true); + return originalNode; + } + + template + void RTDoseReader::MultiplayGridScaling(itk::Image* image, + Float32 gridscale) + { + typedef itk::Image InputImageType; + itk::ImageRegionIterator it(image, + image->GetRequestedRegion()); + for(it=it.Begin(); !it.IsAtEnd(); ++it) + { + it.Set(it.Get()*gridscale); + } + } + + double RTDoseReader::GetMaxDoseValue(DcmDataset* dataSet) + { + DRTDoseIOD doseObject; + OFCondition result = doseObject.read(*dataSet); + if(result.bad()) + { + MITK_ERROR << "Error reading the RT Dose dataset" << endl; + return 0; + } + + Uint16 rows, columns, frames; + OFString nrframes, gridScaling; + const Uint16 *pixelData = NULL; + Float32 gridscale; + + Uint16 &rows_ref = rows; + Uint16 &columns_ref = columns; + + doseObject.getRows(rows_ref); + doseObject.getColumns(columns_ref); + doseObject.getNumberOfFrames(nrframes); + doseObject.getDoseGridScaling(gridScaling); + + frames = atoi(nrframes.c_str()); + gridscale = OFStandard::atof(gridScaling.c_str()); + dataSet->findAndGetUint16Array(DCM_PixelData, pixelData, 0); + + int size = columns*rows*frames; + double highest = 0; + + for(int i=0; ihighest) + { + highest = pixelData[i] * gridscale; + } + } + + return highest; + } + +} diff --git a/Modules/DicomRT/mitkRTDoseReader.h b/Modules/DicomRT/mitkRTDoseReader.h new file mode 100644 index 0000000000..1a6a9f988f --- /dev/null +++ b/Modules/DicomRT/mitkRTDoseReader.h @@ -0,0 +1,86 @@ +/*=================================================================== + +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 mitkDicomRTReader_h +#define mitkDicomRTReader_h + +#include +#include +#include +#include + +#include "dcmtk/dcmrt/drtdose.h" + +#include +#include +#include + +namespace mitk +{ + + class MitkDicomRT_EXPORT RTDoseReader: public itk::Object + { + + public: + + mitkClassMacro( RTDoseReader, itk::Object ); + itkNewMacro( Self ); + + template + void MultiplayGridScaling( itk::Image< TPixel, VImageDimension>* image, Float32 gridscale); + + /** + * @brief Get the maximum dose value from the dose file + * @param dataSet The DcmDataset of the DicomRTDose file + * @return The dose value + * + * Checks all pixel values for the maximum value + */ + double GetMaxDoseValue(DcmDataset* dataSet); + + /** + * @brief Reads a DcmDataset from a DicomRT dose file + * @param dataset DcmDataset-object from DCMTK + * @param filename The path with the dose file used for getting the geometry + * @return Returns a mitkDataNode::Pointer in which a mitk::Image is stored + * + * The method reads the PixelData from the DicomRT dose file and scales + * them with a factor for getting Gray-values instead of pixel-values. + * The Gray-values are stored in a mitkImage with a vtkColorTransferFunc. + * Relative values are used for coloring the image. The relative values are + * relative to a PrescriptionDose definied in the RT-Plan. If there is no + * RT-Plan file PrescriptionDose is set to 80% of the maximum dose. + */ + mitk::DataNode::Pointer LoadRTDose(DcmDataset* dataset, char* filename); + + /** + * Virtual destructor. + */ + virtual ~RTDoseReader(); + + protected: + + /** + * Constructor. + */ + RTDoseReader(); + + }; + +} + +#endif