diff --git a/Modules/BasicImageProcessing/MiniApps/CMakeLists.txt b/Modules/BasicImageProcessing/MiniApps/CMakeLists.txt index 2df1db81db..c4254f4df3 100644 --- a/Modules/BasicImageProcessing/MiniApps/CMakeLists.txt +++ b/Modules/BasicImageProcessing/MiniApps/CMakeLists.txt @@ -1,98 +1,99 @@ option(BUILD_BasicImageProcessingMiniApps "Build commandline tools for Basic Image Processing" OFF) if(BUILD_BasicImageProcessingMiniApps OR MITK_BUILD_ALL_APPS) include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # list of miniapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" set( basicImageProcessingMiniApps FileConverter^^MitkCore ImageTypeConverter^^MitkCore + RectifyImage^^MitkCore SingleImageArithmetic^^MitkCore_MitkBasicImageProcessing TwoImageArithmetic^^MitkCore_MitkBasicImageProcessing ImageAndValueArithmetic^^MitkCore_MitkBasicImageProcessing MaskRangeBasedFiltering^^MitkCore_MitkBasicImageProcessing MaskOutlierFiltering^^MitkCore_MitkBasicImageProcessing ResampleImage^^MitkCore_MitkBasicImageProcessing ResampleMask^^MitkCore_MitkBasicImageProcessing LaplacianOfGaussian^^MitkCore_MitkBasicImageProcessing MultiResolutionPyramid^^MitkCore_MitkBasicImageProcessing ForwardWavelet^^MitkCore_MitkBasicImageProcessing ) foreach(basicImageProcessingMiniApp ${basicImageProcessingMiniApps}) # extract mini app name and dependencies string(REPLACE "^^" "\\;" miniapp_info ${basicImageProcessingMiniApp}) set(miniapp_info_list ${miniapp_info}) list(GET miniapp_info_list 0 appname) list(GET miniapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitk_create_executable(${appname} DEPENDS MitkCore MitkCommandLine ${dependencies_list} PACKAGE_DEPENDS ITK CPP_FILES ${appname}.cpp ) # CPP_FILES ${appname}.cpp mitkCommandLineParser.cpp if(EXECUTABLE_IS_ENABLED) # On Linux, create a shell script to start a relocatable application if(UNIX AND NOT APPLE) install(PROGRAMS "${MITK_SOURCE_DIR}/CMake/RunInstalledApp.sh" DESTINATION "." RENAME ${EXECUTABLE_TARGET}.sh) endif() get_target_property(_is_bundle ${EXECUTABLE_TARGET} MACOSX_BUNDLE) if(APPLE) if(_is_bundle) set(_target_locations ${EXECUTABLE_TARGET}.app) set(${_target_locations}_qt_plugins_install_dir ${EXECUTABLE_TARGET}.app/Contents/MacOS) set(_bundle_dest_dir ${EXECUTABLE_TARGET}.app/Contents/MacOS) set(_qt_plugins_for_current_bundle ${EXECUTABLE_TARGET}.app/Contents/MacOS) set(_qt_conf_install_dirs ${EXECUTABLE_TARGET}.app/Contents/Resources) install(TARGETS ${EXECUTABLE_TARGET} BUNDLE DESTINATION . ) else() if(NOT MACOSX_BUNDLE_NAMES) set(_qt_conf_install_dirs bin) set(_target_locations bin/${EXECUTABLE_TARGET}) set(${_target_locations}_qt_plugins_install_dir bin) install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) else() foreach(bundle_name ${MACOSX_BUNDLE_NAMES}) list(APPEND _qt_conf_install_dirs ${bundle_name}.app/Contents/Resources) set(_current_target_location ${bundle_name}.app/Contents/MacOS/${EXECUTABLE_TARGET}) list(APPEND _target_locations ${_current_target_location}) set(${_current_target_location}_qt_plugins_install_dir ${bundle_name}.app/Contents/MacOS) message( " set(${_current_target_location}_qt_plugins_install_dir ${bundle_name}.app/Contents/MacOS) ") install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION ${bundle_name}.app/Contents/MacOS/) endforeach() endif() endif() else() set(_target_locations bin/${EXECUTABLE_TARGET}${CMAKE_EXECUTABLE_SUFFIX}) set(${_target_locations}_qt_plugins_install_dir bin) set(_qt_conf_install_dirs bin) install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) endif() endif() endforeach() # On Linux, create a shell script to start a relocatable application if(UNIX AND NOT APPLE) install(PROGRAMS "${MITK_SOURCE_DIR}/CMake/RunInstalledApp.sh" DESTINATION "." RENAME ${EXECUTABLE_TARGET}.sh) endif() if(EXECUTABLE_IS_ENABLED) MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET}) endif() endif() diff --git a/Modules/RectifyImage/cmdapps/RectifyImageMiniApp.cpp b/Modules/BasicImageProcessing/MiniApps/RectifyImage.cpp similarity index 93% rename from Modules/RectifyImage/cmdapps/RectifyImageMiniApp.cpp rename to Modules/BasicImageProcessing/MiniApps/RectifyImage.cpp index 305cbcbee1..664c13adb0 100644 --- a/Modules/RectifyImage/cmdapps/RectifyImageMiniApp.cpp +++ b/Modules/BasicImageProcessing/MiniApps/RectifyImage.cpp @@ -1,194 +1,194 @@ /*=================================================================== 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 template void RectifyImage(mitk::Image::Pointer inputImage, mitk::Image::Pointer outputImage) { mitk::ImagePixelReadAccessor pixelReadAccess(inputImage); mitk::ImagePixelWriteAccessor pixelWriteAccess(outputImage); const auto DEPTH = static_cast(outputImage->GetDimension(2)); const auto HEIGHT = static_cast(outputImage->GetDimension(1)); const auto WIDTH = static_cast(outputImage->GetDimension(0)); auto geometry = outputImage->GetGeometry(); itk::Index<3> index; mitk::Point3D worldCoords; for (index[2] = 0; index[2] < DEPTH; ++index[2]) { for (index[1] = 0; index[1] < HEIGHT; ++index[1]) { for (index[0] = 0; index[0] < WIDTH; ++index[0]) { geometry->IndexToWorld(index, worldCoords); pixelWriteAccess.SetPixelByIndex(index, pixelReadAccess.GetPixelByWorldCoordinates(worldCoords)); } } } } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Rectify Image"); - parser.setCategory("Preprocessing Tools"); + parser.setCategory("Basic Image Processing"); parser.setDescription("Resample image based on standard world to index transform"); - parser.setContributor("MBI"); + parser.setContributor("German Cancer Research Center (DKFZ)"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "Input Image", "Path to input image", us::Any(), false); - parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output Image", "Path to output image", us::Any(), false); + parser.addArgument("input", "i", mitkCommandLineParser::Image, "Input Image", "Path to input image", us::Any(), false); + parser.addArgument("output", "o", mitkCommandLineParser::Image, "Output Image", "Path to output image", us::Any(), false); auto parsedArgs = parser.parseArguments(argc, argv); if (2 != parsedArgs.size() || 0 == parsedArgs.count("input") || 0 == parsedArgs.count("output")) return EXIT_FAILURE; auto inputImagePath = us::any_value_to_string(parsedArgs["input"]); mitk::Image::Pointer inputImage; try { inputImage = dynamic_cast(mitk::IOUtil::Load(inputImagePath)[0].GetPointer()); } catch (const mitk::Exception&) { return EXIT_FAILURE; } if (3 != inputImage->GetDimension()) { MITK_ERROR << "Only 3-d images are supported."; return EXIT_FAILURE; } auto inputGeometry = inputImage->GetGeometry(); mitk::Point3D minInputIndex; mitk::FillVector3D(minInputIndex, 0.0, 0.0, 0.0); mitk::Point3D minInputIndexInWorld; inputGeometry->IndexToWorld(minInputIndex, minInputIndexInWorld); mitk::Point3D maxInputIndex; for (int i = 0; i < 3; ++i) maxInputIndex[i] = inputGeometry->GetExtent(i) - 1; mitk::Point3D maxInputIndexInWorld; inputGeometry->IndexToWorld(maxInputIndex, maxInputIndexInWorld); mitk::Point3D minOutputIndexInWorld; for (int i = 0; i < 3; ++i) minOutputIndexInWorld[i] = std::min(minInputIndexInWorld[i], maxInputIndexInWorld[i]); mitk::Point3D maxOutputIndexInWorld; for (int i = 0; i < 3; ++i) maxOutputIndexInWorld[i] = std::max(minInputIndexInWorld[i], maxInputIndexInWorld[i]); mitk::Vector3D spacing = inputGeometry->GetSpacing(); auto transform = inputGeometry->GetIndexToWorldTransform()->Clone(); auto matrix = transform->GetMatrix(); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { matrix[i][j] = std::abs(matrix[i][j]) / spacing[j]; } } transform->SetMatrix(matrix); spacing = transform->TransformVector(spacing); mitk::Vector3D outputExtent = (maxOutputIndexInWorld - minOutputIndexInWorld + spacing); for (int i = 0; i < 3; ++i) outputExtent[i] /= spacing[i]; mitk::Point3D origin = minOutputIndexInWorld; mitk::Vector3D right; mitk::FillVector3D(right, outputExtent[0], 0.0, 0.0); mitk::Vector3D down; mitk::FillVector3D(down, 0.0, outputExtent[1], 0.0); auto planeGeometry = mitk::PlaneGeometry::New(); planeGeometry->InitializeStandardPlane(right, down, &spacing); planeGeometry->SetOrigin(origin); planeGeometry->SetImageGeometry(true); auto slicedGeometry = mitk::SlicedGeometry3D::New(); slicedGeometry->InitializeEvenlySpaced(planeGeometry, static_cast(outputExtent[2])); auto outputGeometry = mitk::ProportionalTimeGeometry::New(); outputGeometry->SetTimeStepGeometry(slicedGeometry, 0); auto pixelType = inputImage->GetPixelType(); auto outputImage = mitk::Image::New(); outputImage->Initialize(pixelType, *outputGeometry); try { switch (pixelType.GetComponentType()) { case itk::ImageIOBase::CHAR: RectifyImage(inputImage, outputImage); break; case itk::ImageIOBase::UCHAR: RectifyImage(inputImage, outputImage); break; case itk::ImageIOBase::SHORT: RectifyImage(inputImage, outputImage); break; case itk::ImageIOBase::USHORT: RectifyImage(inputImage, outputImage); break; default: MITK_ERROR << "Pixel type is not supported."; return EXIT_FAILURE; } } catch (const mitk::Exception &e) { MITK_ERROR << e.GetDescription(); return EXIT_FAILURE; } auto outputImagePath = us::any_value_to_string(parsedArgs["output"]); try { mitk::IOUtil::Save(outputImage, outputImagePath); } catch (const mitk::Exception &) { return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DICOMPM/autoload/DICOMPMIO/mitkDICOMPMIO.cpp b/Modules/DICOMPM/autoload/DICOMPMIO/mitkDICOMPMIO.cpp index a6f23cf779..643fd7dc94 100644 --- a/Modules/DICOMPM/autoload/DICOMPMIO/mitkDICOMPMIO.cpp +++ b/Modules/DICOMPM/autoload/DICOMPMIO/mitkDICOMPMIO.cpp @@ -1,220 +1,217 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef __mitkDICOMPMIO__cpp #define __mitkDICOMPMIO__cpp #include "mitkDICOMPMIO.h" #include "mitkDICOMPMIOMimeTypes.h" #include #include #include #include #include #include #include #include #include #include "mitkParamapPresetsParser.h" // us #include #include // model fit parameters #include "mitkModelFitConstants.h" namespace mitk { DICOMPMIO::DICOMPMIO() : AbstractFileIO(Image::GetStaticNameOfClass(), mitk::MitkDICOMPMIOMimeTypes::DICOMPM_MIMETYPE_NAME(), "DICOM PM") { AbstractFileWriter::SetRanking(10); AbstractFileReader::SetRanking(10); this->RegisterService(); } IFileIO::ConfidenceLevel DICOMPMIO::GetWriterConfidenceLevel() const { if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; const Image *PMinput = static_cast(this->GetInput()); if (PMinput) { auto modalityProperty = PMinput->GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x0060).c_str()); if (modalityProperty.IsNotNull()) { std::string modality = modalityProperty->GetValueAsString(); if (modality == "PM") { return Supported; } else return Unsupported; } else return Unsupported; } else return Unsupported; } void DICOMPMIO::Write() { ValidateOutputLocation(); mitk::LocaleSwitch localeSwitch("C"); LocalFile localFile(this); const std::string path = localFile.GetFileName(); auto PMinput = dynamic_cast(this->GetInput()); if (PMinput == nullptr) mitkThrow() << "Cannot write non-image data"; // Get DICOM information from referenced image vector> dcmDatasetsSourceImage; std::unique_ptr readFileFormat(new DcmFileFormat()); try { // Generate dcmdataset witk DICOM tags from property list; ATM the source are the filepaths from the // property list mitk::StringLookupTableProperty::Pointer filesProp = dynamic_cast(PMinput->GetProperty("referenceFiles").GetPointer()); if (filesProp.IsNull()) { mitkThrow() << "No property with dicom file path."; return; } // returns a list of all referenced files 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()) { std::unique_ptr readDCMDataset(readFileFormat->getAndRemoveDataset()); dcmDatasetsSourceImage.push_back(std::move(readDCMDataset)); } } } catch (const std::exception &e) { MITK_ERROR << "An error occurred while getting the dicom information: " << e.what() << endl; return; } mitk::Image *mitkPMImage = const_cast(PMinput); // Cast input PMinput to itk image ImageToItk::Pointer PMimageToItkFilter = ImageToItk::New(); PMimageToItkFilter->SetInput(mitkPMImage); // Cast from original itk type to dcmqi input itk image type typedef itk::CastImageFilter castItkImageFilterType; castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New(); castFilter->SetInput(PMimageToItkFilter->GetOutput()); castFilter->Update(); PMitkInternalImageType::Pointer itkParamapImage = castFilter->GetOutput(); // Create PM meta information const std::string tmpMetaInfoFile = this->CreateMetaDataJsonFilePM(); // Convert itk PM images to dicom image MITK_INFO << "Writing PM image: " << path << std::endl; try { // convert from unique to raw pointer vector rawVecDataset; for ( const auto& dcmDataSet : dcmDatasetsSourceImage ) { rawVecDataset.push_back( dcmDataSet.get() ); } std::unique_ptr PMconverter(new dcmqi::ParaMapConverter()); std::unique_ptr PMresult (PMconverter->itkimage2paramap(itkParamapImage, rawVecDataset, tmpMetaInfoFile)); // Write dicom file DcmFileFormat dcmFileFormat(PMresult.get()); std::string filePath = path.substr(0, path.find_last_of(".")); filePath = filePath + ".dcm"; dcmFileFormat.saveFile(filePath.c_str(), EXS_LittleEndianExplicit); } catch (const std::exception &e) { MITK_ERROR << "An error occurred during writing the DICOM Paramap: " << e.what() << endl; return; } } const std::string mitk::DICOMPMIO::CreateMetaDataJsonFilePM() const { const mitk::Image *PMimage = dynamic_cast(this->GetInput()); dcmqi::JSONParametricMapMetaInformationHandler PMhandler; // Get Metadata from modelFitConstants std::string parameterName; PMimage->GetPropertyList()->GetStringProperty(ModelFitConstants::PARAMETER_NAME_PROPERTY_NAME().c_str(), parameterName); std::string modelName; PMimage->GetPropertyList()->GetStringProperty(ModelFitConstants::MODEL_NAME_PROPERTY_NAME().c_str(), modelName); mitk::ParamapPresetsParser* pmPresets = mitk::ParamapPresetsParser::New(); // Here the mitkParamapPresets.xml file containing the Coding Schmeme Designator and Code Value are parsed and the relevant values extracted pmPresets->LoadPreset(); auto pmType_parameterName = pmPresets->GetType(parameterName); auto pmType_modelName = pmPresets->GetType(modelName); // Pass codes to Paramap Converter PMhandler.setDerivedPixelContrast("TCS"); PMhandler.setFrameLaterality("U"); PMhandler.setQuantityValueCode(pmType_parameterName.codeValue, pmType_parameterName.codeScheme, parameterName); PMhandler.setMeasurementMethodCode(pmType_modelName.codeValue, pmType_modelName.codeScheme, modelName); PMhandler.setMeasurementUnitsCode("/min", "UCUM", "/m"); PMhandler.setSeriesNumber("1"); PMhandler.setInstanceNumber("1"); PMhandler.setDerivationCode("129104", "DCM", "Perfusion image analysis"); PMhandler.setRealWorldValueSlope("1"); - - return PMhandler.getJSONOutputAsString(); - } std::vector DICOMPMIO::Read() { mitk::LocaleSwitch localeSwitch("C"); std::vector result; return result; } IFileIO::ConfidenceLevel DICOMPMIO::GetReaderConfidenceLevel() const { return Unsupported; } DICOMPMIO *DICOMPMIO::IOClone() const { return new DICOMPMIO(*this); } } // namespace #endif //__mitkDICOMPMIO__cpp diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index 9f3b9c9722..4daa70f838 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,86 +1,85 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(MITK_MODULES Core CommandLine - RectifyImage AppUtil LegacyIO DataTypesExt Annotation LegacyGL AlgorithmsExt MapperExt DICOMReader DICOMReaderServices DICOMQI DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction SceneSerialization Gizmo GraphAlgorithms Multilabel Chart ImageStatistics ContourModel SurfaceInterpolation Segmentation QtWidgets QtWidgetsExt ImageStatisticsUI SegmentationUI MatchPointRegistration MatchPointRegistrationUI Classification OpenIGTLink IGTBase IGT CameraCalibration OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI PhotoacousticsHardware PhotoacousticsAlgorithms PhotoacousticsLib US USUI DicomUI Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI DicomRT RTUI IOExt XNAT TubeGraph BiophotonicsHardware BoundingShape RenderWindowManager RenderWindowManagerUI SemanticRelations SemanticRelationsUI CEST BasicImageProcessing ModelFit ModelFitUI Pharmacokinetics PharmacokineticsUI DICOMPM REST RESTService DICOMweb ) if(MITK_ENABLE_PIC_READER) list(APPEND MITK_MODULES IpPicSupportIO) endif() diff --git a/Modules/RectifyImage/CMakeLists.txt b/Modules/RectifyImage/CMakeLists.txt deleted file mode 100644 index d7589da3d7..0000000000 --- a/Modules/RectifyImage/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(cmdapps) diff --git a/Modules/RectifyImage/cmdapps/CMakeLists.txt b/Modules/RectifyImage/cmdapps/CMakeLists.txt deleted file mode 100644 index 324aa61e78..0000000000 --- a/Modules/RectifyImage/cmdapps/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -option(BUILD_RectifyImageMiniApps "" OFF) - -if(BUILD_RectifyImageMiniApps) - mitkFunctionCreateCommandLineApp( - NAME RectifyImageMiniApp - DEPENDS MitkCore MitkCommandLine - ) -endif()