diff --git a/CMake/BuildConfigurations/All.cmake b/CMake/BuildConfigurations/All.cmake index c9871da2b7..0d24c5499d 100644 --- a/CMake/BuildConfigurations/All.cmake +++ b/CMake/BuildConfigurations/All.cmake @@ -1,69 +1,76 @@ set(MITK_CONFIG_PACKAGES ) set(_apple_package_excludes) if(APPLE) set(_apple_package_excludes SOFA ) endif() set(_python_excludes ) if(NOT (CMAKE_SIZEOF_VOID_P EQUAL 8) ) set(_python_excludes Python Numpy ) endif() set(_package_excludes ${_apple_package_excludes} ${_python_excludes} Gflags Caffe Caffe2 OpenCL SYSTEM_Boost Boost_LIBRARIES SYSTEM_PYTHON SOFA_PLUGINS SOFA_PLUGINS_DIR SUPERBUILD BiophotonicsHardware_SpectroCam KWSTYLE MICROBIRD_TRACKER MICROBIRD_TRACKER_INCLUDE_DIR MICROBIRD_TRACKER_LIB MICRON_TRACKER OPTITRACK_TRACKER SPACENAVIGATOR TOF_KINECT TOF_KINECTV2 TOF_MESASR4000 TOF_PMDCAMBOARD TOF_PMDCAMCUBE TOF_PMDO3 US_TELEMED_SDK videoInput WIIMOTE ) get_cmake_property(_cache_vars CACHE_VARIABLES) foreach(_cache_var ${_cache_vars}) string(REGEX REPLACE "MITK_USE_(.+)" "\\1" _package "${_cache_var}") if(_package AND NOT _package STREQUAL _cache_var) list(FIND _package_excludes ${_package} _index) if(_index EQUAL -1) list(APPEND MITK_CONFIG_PACKAGES ${_package}) endif() endif() endforeach() set(MITK_BUILD_ALL_APPS ON CACHE BOOL "Build all MITK applications" FORCE) set(MITK_BUILD_ALL_PLUGINS ON CACHE BOOL "Build all MITK plugins" FORCE) set(MITK_BUILD_EXAMPLES ON CACHE BOOL "Build the MITK examples" FORCE) set(BLUEBERRY_BUILD_ALL_PLUGINS ON CACHE BOOL "Build all BlueBerry plugins" FORCE) -set(BUILD_DiffusionCmdApps ON CACHE BOOL "Build MITK Diffusion MiniApps" FORCE) -set(BUILD_DiffusionCoreCmdApps ON CACHE BOOL "Build MITK Diffusion MiniApps" FORCE) + +set(BUILD_DiffusionCoreCmdApps ON CACHE BOOL "Build commandline tools for diffusion" FORCE) +set(BUILD_DiffusionFiberProcessingCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber processing" FORCE) +set(BUILD_DiffusionFiberfoxCmdApps ON CACHE BOOL "Build commandline tools for diffusion data simulation (Fiberfox)" FORCE) +set(BUILD_DiffusionMiscCmdApps ON CACHE BOOL "Build miscellaneous commandline tools for diffusion" FORCE) +set(BUILD_DiffusionQuantificationCmdApps ON CACHE BOOL "Build commandline tools for diffusion quantification (IVIM, ADC, ...)" FORCE) +set(BUILD_DiffusionTractographyCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber tractography" FORCE) +set(BUILD_DiffusionTractographyEvaluationCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber tractography evaluation" FORCE) +set(BUILD_DiffusionConnectomicsCmdApps ON CACHE BOOL "Build commandline tools for diffusion connectomics" FORCE) diff --git a/CMake/BuildConfigurations/mitkDiffusion.cmake b/CMake/BuildConfigurations/mitkDiffusion.cmake index 33903b27ee..15f355d054 100644 --- a/CMake/BuildConfigurations/mitkDiffusion.cmake +++ b/CMake/BuildConfigurations/mitkDiffusion.cmake @@ -1,72 +1,78 @@ message(STATUS "Configuring MITK Diffusion Release Build") # Enable non-optional external dependencies set(MITK_USE_Vigra ON CACHE BOOL "MITK Use Vigra Library" FORCE) set(MITK_USE_HDF5 ON CACHE BOOL "MITK Use HDF5 Library" FORCE) # Disable all apps but MITK Diffusion set(MITK_BUILD_ALL_APPS OFF CACHE BOOL "Build all MITK applications" FORCE) set(MITK_BUILD_APP_CoreApp OFF CACHE BOOL "Build the MITK CoreApp" FORCE) set(MITK_BUILD_APP_Workbench OFF CACHE BOOL "Build the MITK Workbench" FORCE) set(MITK_BUILD_APP_Diffusion ON CACHE BOOL "Build MITK Diffusion" FORCE) # Activate Diffusion Mini Apps -set(BUILD_DiffusionCmdApps ON CACHE BOOL "Build MITK Diffusion MiniApps" FORCE) -set(BUILD_DiffusionCoreCmdApps ON CACHE BOOL "Build MITK Diffusion Core MiniApps" FORCE) +set(BUILD_DiffusionCoreCmdApps ON CACHE BOOL "Build commandline tools for diffusion" FORCE) +set(BUILD_DiffusionFiberProcessingCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber processing" FORCE) +set(BUILD_DiffusionFiberfoxCmdApps ON CACHE BOOL "Build commandline tools for diffusion data simulation (Fiberfox)" FORCE) +set(BUILD_DiffusionMiscCmdApps ON CACHE BOOL "Build miscellaneous commandline tools for diffusion" FORCE) +set(BUILD_DiffusionQuantificationCmdApps ON CACHE BOOL "Build commandline tools for diffusion quantification (IVIM, ADC, ...)" FORCE) +set(BUILD_DiffusionTractographyCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber tractography" FORCE) +set(BUILD_DiffusionTractographyEvaluationCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber tractography evaluation" FORCE) +set(BUILD_DiffusionConnectomicsCmdApps ON CACHE BOOL "Build commandline tools for diffusion connectomics" FORCE) # Build neither all plugins nor examples set(MITK_BUILD_ALL_PLUGINS OFF CACHE BOOL "Build all MITK plugins" FORCE) set(MITK_BUILD_EXAMPLES OFF CACHE BOOL "Build the MITK examples" FORCE) # Activate in-application help generation set(MITK_DOXYGEN_GENERATE_QCH_FILES ON CACHE BOOL "Use doxygen to generate Qt compressed help files for MITK docs" FORCE) set(BLUEBERRY_USE_QT_HELP ON CACHE BOOL "Enable support for integrating bundle documentation into Qt Help" FORCE) # Disable console window set(MITK_SHOW_CONSOLE_WINDOW OFF CACHE BOOL "Use this to enable or disable the console window when starting MITK GUI Applications" FORCE) # Activate required plugins # should be identical to the list in /Applications/Diffusion/CMakeLists.txt set(_plugins org.commontk.configadmin org.commontk.eventadmin org.blueberry.compat org.blueberry.core.runtime org.blueberry.core.expressions org.blueberry.core.commands org.blueberry.ui.qt org.blueberry.ui.qt.log org.blueberry.ui.qt.help org.mitk.core.services org.mitk.gui.common org.mitk.planarfigure org.mitk.core.ext org.mitk.gui.qt.application org.mitk.gui.qt.ext org.mitk.gui.qt.diffusionimagingapp org.mitk.gui.qt.common org.mitk.gui.qt.stdmultiwidgeteditor org.mitk.gui.qt.common.legacy org.mitk.gui.qt.datamanager org.mitk.gui.qt.measurementtoolbox org.mitk.gui.qt.segmentation org.mitk.gui.qt.volumevisualization org.mitk.gui.qt.diffusionimaging org.mitk.gui.qt.diffusionimaging.connectomics org.mitk.gui.qt.diffusionimaging.denoising org.mitk.gui.qt.diffusionimaging.fiberfox org.mitk.gui.qt.diffusionimaging.fiberprocessing org.mitk.gui.qt.diffusionimaging.ivim org.mitk.gui.qt.diffusionimaging.odfpeaks org.mitk.gui.qt.diffusionimaging.partialvolume org.mitk.gui.qt.diffusionimaging.preprocessing org.mitk.gui.qt.diffusionimaging.reconstruction org.mitk.gui.qt.diffusionimaging.registration org.mitk.gui.qt.diffusionimaging.tbss org.mitk.gui.qt.diffusionimaging.tractography org.mitk.gui.qt.imagenavigator org.mitk.gui.qt.moviemaker org.mitk.gui.qt.basicimageprocessing org.mitk.gui.qt.properties org.mitk.gui.qt.viewnavigator ) diff --git a/CMake/BuildConfigurations/mitkFiberfox.cmake b/CMake/BuildConfigurations/mitkFiberfox.cmake index b0f8aadea0..49ca769240 100644 --- a/CMake/BuildConfigurations/mitkFiberfox.cmake +++ b/CMake/BuildConfigurations/mitkFiberfox.cmake @@ -1,48 +1,48 @@ message(STATUS "Configuring MITK Fiberfox Release Build") # Enable non-optional external dependencies set(MITK_USE_Vigra ON CACHE BOOL "MITK Use Vigra Library" FORCE) set(MITK_USE_HDF5 ON CACHE BOOL "MITK Use HDF5 Library" FORCE) # Disable all apps but MITK Fiberfox set(MITK_BUILD_ALL_APPS OFF CACHE BOOL "Build all MITK applications" FORCE) set(MITK_BUILD_APP_CoreApp OFF CACHE BOOL "Build the MITK CoreApp" FORCE) set(MITK_BUILD_APP_Workbench OFF CACHE BOOL "Build the MITK Workbench" FORCE) set(MITK_BUILD_APP_Fiberfox ON CACHE BOOL "Build MITK Fiberfox" FORCE) # Activate Diffusion Mini Apps -set(BUILD_DiffusionCmdApps ON CACHE BOOL "Build MITK Diffusion MiniApps" FORCE) +set(BUILD_DiffusionFiberfoxCmdApps ON CACHE BOOL "Build commandline tools for diffusion data simulation (Fiberfox)" FORCE) # Build neither all plugins nor examples set(MITK_BUILD_ALL_PLUGINS OFF CACHE BOOL "Build all MITK plugins" FORCE) set(MITK_BUILD_EXAMPLES OFF CACHE BOOL "Build the MITK examples" FORCE) # Activate in-application help generation set(MITK_DOXYGEN_GENERATE_QCH_FILES ON CACHE BOOL "Use doxygen to generate Qt compressed help files for MITK docs" FORCE) set(BLUEBERRY_USE_QT_HELP ON CACHE BOOL "Enable support for integrating bundle documentation into Qt Help" FORCE) # Disable console window set(MITK_SHOW_CONSOLE_WINDOW OFF CACHE BOOL "Use this to enable or disable the console window when starting MITK GUI Applications" FORCE) # Activate required plugins # should be identical to the list in /Applications/Fiberfox/CMakeLists.txt set(_plugins org_blueberry_ui_qt org_blueberry_ui_qt_help org_mitk_planarfigure org_mitk_gui_qt_extapplication org_mitk_gui_qt_common_legacy org_mitk_gui_qt_ext org_mitk_gui_qt_datamanager org_mitk_gui_qt_segmentation org_mitk_gui_qt_volumevisualization org_mitk_gui_qt_diffusionimaging org_mitk_gui_qt_diffusionimaging_fiberfox org_mitk_gui_qt_diffusionimaging_fiberprocessing org_mitk_gui_qt_diffusionimaging_preprocessing org_mitk_gui_qt_diffusionimaging_reconstruction org_mitk_gui_qt_imagenavigator org_mitk_gui_qt_moviemaker org_mitk_gui_qt_measurementtoolbox org_mitk_gui_qt_viewnavigator ) diff --git a/CMakeExternals/Caffe.cmake b/CMakeExternals/Caffe.cmake index 0b22496325..a586e27174 100644 --- a/CMakeExternals/Caffe.cmake +++ b/CMakeExternals/Caffe.cmake @@ -1,57 +1,64 @@ #----------------------------------------------------------------------------- # Caffe #----------------------------------------------------------------------------- if(MITK_USE_Caffe) # Sanity checks if(DEFINED Caffe_DIR AND NOT EXISTS ${Caffe_DIR}) message(FATAL_ERROR "Caffe_DIR variable is defined but corresponds to non-existing directory") endif() set(proj Caffe) set(proj_DEPENDENCIES ) set(Caffe_DEPENDS ${proj}) if(WIN32) set(COPY_COMMAND copy) else() set(COPY_COMMAND cp) endif() if(NOT DEFINED Caffe_DIR) find_path(Boost_INCLUDE_DIR boost) find_library(Boost_LIBRARY boost_system) get_filename_component(Boost_LIBRARY_DIR ${Boost_LIBRARY} DIRECTORY) + + if(${CMAKE_BUILD_TYPE} MATCHES "Debug") + find_library(GFLAGS_LIBRARY gflagsd PATHS ${ep_prefix}/lib NO_DEFAULT_PATH) + else() + find_library(GFLAGS_LIBRARY gflags PATHS ${ep_prefix}/lib NO_DEFAULT_PATH) + endif() #set(revision_tag 63cad96) ExternalProject_Add(${proj} GIT_REPOSITORY https://github.com/BVLC/caffe.git #GIT_TAG ${revision_tag} CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${additional_args} -DCMAKE_CXX_FLAGS=-std=c++11 -DCMAKE_CXX_STANDARD=11 -DUSE_OPENMP:BOOL=ON -DBoost_INCLUDE_DIR:PATH=${Boost_INCLUDE_DIR} -DBoost_LIBRARY_DIR_RELEASE:PATH=${Boost_LIBRARY_DIR} -DBoost_LIBRARY_DIR_DEBUG:PATH=${Boost_LIBRARY_DIR} + -DGFLAGS_LIBRARY:FILEPATH=${GFLAGS_LIBRARY} CMAKE_CACHE_ARGS ${ep_common_cache_args} CMAKE_CACHE_DEFAULT_ARGS ${ep_common_cache_default_args} DEPENDS ${proj_DEPENDENCIES} ) set(Caffe_DIR ${ep_prefix}) mitkFunctionInstallExternalCMakeProject(${proj}) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() endif(MITK_USE_Caffe) diff --git a/Modules/DiffusionImaging/CMakeLists.txt b/Modules/DiffusionImaging/CMakeLists.txt index f19c59e477..c649ff334d 100644 --- a/Modules/DiffusionImaging/CMakeLists.txt +++ b/Modules/DiffusionImaging/CMakeLists.txt @@ -1,15 +1,14 @@ set( diffusion_module_dirs DiffusionCore FiberTracking Connectomics Quantification DiffusionIO - cmdapps DeepDiffusion ) foreach(diffusion_module_dir ${diffusion_module_dirs}) add_subdirectory(${diffusion_module_dir}) endforeach() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/mitkDiffusionImagingConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/DiffusionCore/mitkDiffusionImagingConfigure.h) diff --git a/Modules/DiffusionImaging/Connectomics/CMakeLists.txt b/Modules/DiffusionImaging/Connectomics/CMakeLists.txt index 08091353cf..65b96ad200 100644 --- a/Modules/DiffusionImaging/Connectomics/CMakeLists.txt +++ b/Modules/DiffusionImaging/Connectomics/CMakeLists.txt @@ -1,9 +1,10 @@ MITK_CREATE_MODULE( SUBPROJECTS MITK-DTI INCLUDE_DIRS Algorithms Algorithms/BrainParcellation IODataStructures Rendering ${CMAKE_CURRENT_BINARY_DIR} DEPENDS MitkDiffusionCore MitkFiberTracking PACKAGE_DEPENDS VTK|vtkInfovisLayout # WARNINGS_AS_ERRORS ) add_subdirectory(Testing) +add_subdirectory(cmdapps) diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt b/Modules/DiffusionImaging/Connectomics/cmdapps/CMakeLists.txt old mode 100644 new mode 100755 similarity index 55% copy from Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt copy to Modules/DiffusionImaging/Connectomics/cmdapps/CMakeLists.txt index 1fe5feb7d2..c2050ff407 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt +++ b/Modules/DiffusionImaging/Connectomics/cmdapps/CMakeLists.txt @@ -1,44 +1,39 @@ -option(BUILD_DiffusionCoreCmdApps "Build commandline tools for diffusion" OFF) +option(BUILD_DiffusionConnectomicsCmdApps "Build commandline tools for diffusion connectomics" OFF) -if(BUILD_DiffusionCoreCmdApps OR MITK_BUILD_ALL_APPS) +if(BUILD_DiffusionConnectomicsCmdApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) - # list of diffusion cmdapps + # list of DiffusionConnectomics cmdapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" - set( diffusioncorecmdapps - DwiDenoising^^ - ImageResampler^^ - ExportShImage^^ - CopyGeometry^^ - DiffusionIndices^^ - QballReconstruction^^ - Registration^^ - TensorReconstruction^^ - TensorDerivedMapsExtraction^^ - DiffusionDICOMLoader^^ - DiffusionKurtosisFit^^ + set( DiffusionConnectomicscmdapps + NetworkCreation^^MitkFiberTracking_MitkConnectomics + NetworkStatistics^^MitkConnectomics ) - foreach(diffusioncorecmdapp ${diffusioncorecmdapps}) + foreach(DiffusionConnectomicscmdapp ${DiffusionConnectomicscmdapps}) # extract cmd app name and dependencies - string(REPLACE "^^" "\\;" cmdapp_info ${diffusioncorecmdapp}) + string(REPLACE "^^" "\\;" cmdapp_info ${DiffusionConnectomicscmdapp}) set(cmdapp_info_list ${cmdapp_info}) list(GET cmdapp_info_list 0 appname) list(GET cmdapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitkFunctionCreateCommandLineApp( NAME ${appname} DEPENDS MitkCore MitkDiffusionCore ${dependencies_list} PACKAGE_DEPENDS ITK ) endforeach() + if(EXECUTABLE_IS_ENABLED) + MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET}) + endif() + endif() diff --git a/Modules/DiffusionImaging/cmdapps/NetworkCreation.cpp b/Modules/DiffusionImaging/Connectomics/cmdapps/NetworkCreation.cpp similarity index 96% rename from Modules/DiffusionImaging/cmdapps/NetworkCreation.cpp rename to Modules/DiffusionImaging/Connectomics/cmdapps/NetworkCreation.cpp index 02d57fe5b9..95072fcd2e 100644 --- a/Modules/DiffusionImaging/cmdapps/NetworkCreation.cpp +++ b/Modules/DiffusionImaging/Connectomics/cmdapps/NetworkCreation.cpp @@ -1,140 +1,135 @@ /*=================================================================== 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. ===================================================================*/ // std includes #include // CTK includes #include "mitkCommandLineParser.h" // MITK includes #include "mitkConnectomicsNetworkCreator.h" #include #include using namespace std; int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Network Creation"); parser.setCategory("Connectomics"); parser.setDescription(""); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("fiberImage", "f", mitkCommandLineParser::InputFile, "Input image", "input fiber image (.fib)", us::Any(), false); parser.addArgument("parcellation", "p", mitkCommandLineParser::InputFile, "Parcellation image", "parcellation image", us::Any(), false); parser.addArgument("outputNetwork", "o", mitkCommandLineParser::String, "Output network", "where to save the output (.cnf)", us::Any(), false); parser.addArgument("radius", "r", mitkCommandLineParser::Int, "Radius", "Search radius in mm", 15, true); parser.addArgument("noCenterOfMass", "com", mitkCommandLineParser::Bool, "No center of mass", "Do not use center of mass for node positions"); - parser.setCategory("Connectomics"); - parser.setTitle("Network Creation"); - parser.setDescription(""); - parser.setContributor("MBI"); - map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; //default values int searchRadius( 15 ); bool noCenterOfMass( false ); // parse command line arguments std::string fiberFilename = us::any_cast(parsedArgs["fiberImage"]); std::string parcellationFilename = us::any_cast(parsedArgs["parcellation"]); std::string outputFilename = us::any_cast(parsedArgs["outputNetwork"]); if (parsedArgs.count("radius")) searchRadius = us::any_cast(parsedArgs["radius"]); if (parsedArgs.count("noCenterOfMass")) noCenterOfMass = us::any_cast(parsedArgs["noCenterOfMass"]); try { const std::string s1="", s2=""; // load fiber image std::vector fiberInfile = mitk::IOUtil::Load( fiberFilename); if( fiberInfile.empty() ) { std::string errorMessage = "Fiber Image at " + fiberFilename + " could not be read. Aborting."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } mitk::BaseData* fiberBaseData = fiberInfile.at(0); mitk::FiberBundle* fiberBundle = dynamic_cast( fiberBaseData ); // load parcellation std::vector parcellationInFile = mitk::IOUtil::Load( parcellationFilename); if( parcellationInFile.empty() ) { std::string errorMessage = "Parcellation at " + parcellationFilename + " could not be read. Aborting."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } mitk::BaseData* parcellationBaseData = parcellationInFile.at(0); mitk::Image* parcellationImage = dynamic_cast( parcellationBaseData ); // do creation mitk::ConnectomicsNetworkCreator::Pointer connectomicsNetworkCreator = mitk::ConnectomicsNetworkCreator::New(); connectomicsNetworkCreator->SetSegmentation( parcellationImage ); connectomicsNetworkCreator->SetFiberBundle( fiberBundle ); if( !noCenterOfMass ) { connectomicsNetworkCreator->CalculateCenterOfMass(); } connectomicsNetworkCreator->SetEndPointSearchRadius( searchRadius ); connectomicsNetworkCreator->CreateNetworkFromFibersAndSegmentation(); mitk::ConnectomicsNetwork::Pointer network = connectomicsNetworkCreator->GetNetwork(); std::cout << "searching writer"; mitk::IOUtil::SaveBaseData(network.GetPointer(), outputFilename ); return EXIT_SUCCESS; } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } std::cout << "DONE"; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/NetworkStatistics.cpp b/Modules/DiffusionImaging/Connectomics/cmdapps/NetworkStatistics.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/NetworkStatistics.cpp rename to Modules/DiffusionImaging/Connectomics/cmdapps/NetworkStatistics.cpp index 2d06d92c48..324a5f1c11 100644 --- a/Modules/DiffusionImaging/cmdapps/NetworkStatistics.cpp +++ b/Modules/DiffusionImaging/Connectomics/cmdapps/NetworkStatistics.cpp @@ -1,574 +1,569 @@ /*=================================================================== 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. ===================================================================*/ // std includes #include #include #include #include #include #include // boost includes #include // ITK includes #include // CTK includes #include "mitkCommandLineParser.h" // MITK includes #include #include #include #include int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Network Creation"); parser.setCategory("Connectomics"); parser.setDescription(""); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("inputNetwork", "i", mitkCommandLineParser::InputFile, "Input network", "input connectomics network (.cnf)", us::Any(), false); parser.addArgument("outputFile", "o", mitkCommandLineParser::OutputFile, "Output file", "name of output file", us::Any(), false); parser.addArgument("noGlobalStatistics", "g", mitkCommandLineParser::Bool, "No global statistics", "Do not calculate global statistics"); parser.addArgument("createConnectivityMatriximage", "I", mitkCommandLineParser::Bool, "Write connectivity matrix image", "Write connectivity matrix image"); parser.addArgument("binaryConnectivity", "b", mitkCommandLineParser::Bool, "Binary connectivity", "Whether to create a binary connectivity matrix"); parser.addArgument("rescaleConnectivity", "r", mitkCommandLineParser::Bool, "Rescale connectivity", "Whether to rescale the connectivity matrix"); parser.addArgument("localStatistics", "L", mitkCommandLineParser::StringList, "Local statistics", "Provide a list of node labels for local statistics", us::Any()); parser.addArgument("regionList", "R", mitkCommandLineParser::StringList, "Region list", "A space separated list of regions. Each region has the format\n regionname;label1;label2;...;labelN", us::Any()); parser.addArgument("granularity", "gr", mitkCommandLineParser::Int, "Granularity", "How finely to test the density range and how many thresholds to consider",1); parser.addArgument("startDensity", "d", mitkCommandLineParser::Float, "Start Density", "Largest density for the range",1.0); parser.addArgument("thresholdStepSize", "t", mitkCommandLineParser::Int, "Step size threshold", "Distance of two adjacent thresholds",3); - parser.setCategory("Connectomics"); - parser.setTitle("Network Statistics"); - parser.setDescription(""); - parser.setContributor("MBI"); - std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; //default values bool noGlobalStatistics( false ); bool binaryConnectivity( false ); bool rescaleConnectivity( false ); bool createConnectivityMatriximage( false ); int granularity( 1 ); double startDensity( 1.0 ); int thresholdStepSize( 3 ); // parse command line arguments std::string networkName = us::any_cast(parsedArgs["inputNetwork"]); std::string outName = us::any_cast(parsedArgs["outputFile"]); mitkCommandLineParser::StringContainerType localLabels; if(parsedArgs.count("localStatistics")) { localLabels = us::any_cast(parsedArgs["localStatistics"]); } mitkCommandLineParser::StringContainerType unparsedRegions; std::map< std::string, std::vector > parsedRegions; std::map< std::string, std::vector >::iterator parsedRegionsIterator; if(parsedArgs.count("regionList")) { unparsedRegions = us::any_cast(parsedArgs["regionList"]); for(unsigned int index(0); index < unparsedRegions.size(); index++ ) { std::vector< std::string > tempRegionVector; boost::split(tempRegionVector, unparsedRegions.at(index), boost::is_any_of(";")); std::vector< std::string >::const_iterator begin = tempRegionVector.begin(); std::vector< std::string >::const_iterator last = tempRegionVector.begin() + tempRegionVector.size(); std::vector< std::string > insertRegionVector(begin + 1, last); if( parsedRegions.count( tempRegionVector.at(0) ) == 0 ) { parsedRegions.insert( std::pair< std::string, std::vector >( tempRegionVector.at(0), insertRegionVector) ); } else { MITK_ERROR << "Region already exists. Skipping second occurrence."; } } } if (parsedArgs.count("noGlobalStatistics")) noGlobalStatistics = us::any_cast(parsedArgs["noGlobalStatistics"]); if (parsedArgs.count("binaryConnectivity")) binaryConnectivity = us::any_cast(parsedArgs["binaryConnectivity"]); if (parsedArgs.count("rescaleConnectivity")) rescaleConnectivity = us::any_cast(parsedArgs["rescaleConnectivity"]); if (parsedArgs.count("createConnectivityMatriximage")) createConnectivityMatriximage = us::any_cast(parsedArgs["createConnectivityMatriximage"]); if (parsedArgs.count("granularity")) granularity = us::any_cast(parsedArgs["granularity"]); if (parsedArgs.count("startDensity")) startDensity = us::any_cast(parsedArgs["startDensity"]); if (parsedArgs.count("thresholdStepSize")) thresholdStepSize = us::any_cast(parsedArgs["thresholdStepSize"]); try { // load network std::vector networkFile = mitk::IOUtil::Load( networkName); if( networkFile.empty() ) { std::string errorMessage = "File at " + networkName + " could not be read. Aborting."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } mitk::BaseData* networkBaseData = networkFile.at(0); mitk::ConnectomicsNetwork* network = dynamic_cast( networkBaseData ); if( !network ) { std::string errorMessage = "Read file at " + networkName + " could not be recognized as network. Aborting."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } // streams std::stringstream globalHeaderStream; globalHeaderStream << "NumberOfVertices " << "NumberOfEdges " << "AverageDegree " << "ConnectionDensity " << "NumberOfConnectedComponents " << "AverageComponentSize " << "LargestComponentSize " << "RatioOfNodesInLargestComponent " << "HopPlotExponent " << "EffectiveHopDiameter " << "AverageClusteringCoefficientsC " << "AverageClusteringCoefficientsD " << "AverageClusteringCoefficientsE " << "AverageVertexBetweennessCentrality " << "AverageEdgeBetweennessCentrality " << "NumberOfIsolatedPoints " << "RatioOfIsolatedPoints " << "NumberOfEndPoints " << "RatioOfEndPoints " << "Diameter " << "Diameter90 " << "Radius " << "Radius90 " << "AverageEccentricity " << "AverageEccentricity90 " << "AveragePathLength " << "NumberOfCentralPoints " << "RatioOfCentralPoints " << "SpectralRadius " << "SecondLargestEigenValue " << "AdjacencyTrace " << "AdjacencyEnergy " << "LaplacianTrace " << "LaplacianEnergy " << "LaplacianSpectralGap " << "NormalizedLaplacianTrace " << "NormalizedLaplacianEnergy " << "NormalizedLaplacianNumberOf2s " << "NormalizedLaplacianNumberOf1s " << "NormalizedLaplacianNumberOf0s " << "NormalizedLaplacianLowerSlope " << "NormalizedLaplacianUpperSlope " << "SmallWorldness" << std::endl; std::stringstream localHeaderStream; std::stringstream regionalHeaderStream; std::stringstream globalDataStream; std::stringstream localDataStream; std::stringstream regionalDataStream; std::string globalOutName = outName + "_global.txt"; std::string localOutName = outName + "_local.txt"; std::string regionalOutName = outName + "_regional.txt"; bool firstRun( true ); // iterate over all three possible methods for(unsigned int method( 0 ); method < 3; method++) { // 0 - Random removal threshold // 1 - Largest density below threshold // 2 - Threshold based // iterate over possible targets for( unsigned int step( 0 ); step < granularity; step++ ) { double targetValue( 0.0 ); bool newStep( true ); switch ( method ) { case mitk::ConnectomicsNetworkThresholder::RandomRemovalOfWeakest : case mitk::ConnectomicsNetworkThresholder::LargestLowerThanDensity : targetValue = startDensity * (1 - static_cast( step ) / ( granularity + 0.5 ) ); break; case mitk::ConnectomicsNetworkThresholder::ThresholdBased : targetValue = static_cast( thresholdStepSize * step ); break; default: MITK_ERROR << "Invalid thresholding method called, aborting."; return EXIT_FAILURE; break; } mitk::ConnectomicsNetworkThresholder::Pointer thresholder = mitk::ConnectomicsNetworkThresholder::New(); thresholder->SetNetwork( network ); thresholder->SetTargetThreshold( targetValue ); thresholder->SetTargetDensity( targetValue ); thresholder->SetThresholdingScheme( static_cast(method) ); mitk::ConnectomicsNetwork::Pointer thresholdedNetwork = thresholder->GetThresholdedNetwork(); mitk::ConnectomicsStatisticsCalculator::Pointer statisticsCalculator = mitk::ConnectomicsStatisticsCalculator::New(); statisticsCalculator->SetNetwork( thresholdedNetwork ); statisticsCalculator->Update(); // global statistics if( !noGlobalStatistics ) { globalDataStream << statisticsCalculator->GetNumberOfVertices() << " " << statisticsCalculator->GetNumberOfEdges() << " " << statisticsCalculator->GetAverageDegree() << " " << statisticsCalculator->GetConnectionDensity() << " " << statisticsCalculator->GetNumberOfConnectedComponents() << " " << statisticsCalculator->GetAverageComponentSize() << " " << statisticsCalculator->GetLargestComponentSize() << " " << statisticsCalculator->GetRatioOfNodesInLargestComponent() << " " << statisticsCalculator->GetHopPlotExponent() << " " << statisticsCalculator->GetEffectiveHopDiameter() << " " << statisticsCalculator->GetAverageClusteringCoefficientsC() << " " << statisticsCalculator->GetAverageClusteringCoefficientsD() << " " << statisticsCalculator->GetAverageClusteringCoefficientsE() << " " << statisticsCalculator->GetAverageVertexBetweennessCentrality() << " " << statisticsCalculator->GetAverageEdgeBetweennessCentrality() << " " << statisticsCalculator->GetNumberOfIsolatedPoints() << " " << statisticsCalculator->GetRatioOfIsolatedPoints() << " " << statisticsCalculator->GetNumberOfEndPoints() << " " << statisticsCalculator->GetRatioOfEndPoints() << " " << statisticsCalculator->GetDiameter() << " " << statisticsCalculator->GetDiameter90() << " " << statisticsCalculator->GetRadius() << " " << statisticsCalculator->GetRadius90() << " " << statisticsCalculator->GetAverageEccentricity() << " " << statisticsCalculator->GetAverageEccentricity90() << " " << statisticsCalculator->GetAveragePathLength() << " " << statisticsCalculator->GetNumberOfCentralPoints() << " " << statisticsCalculator->GetRatioOfCentralPoints() << " " << statisticsCalculator->GetSpectralRadius() << " " << statisticsCalculator->GetSecondLargestEigenValue() << " " << statisticsCalculator->GetAdjacencyTrace() << " " << statisticsCalculator->GetAdjacencyEnergy() << " " << statisticsCalculator->GetLaplacianTrace() << " " << statisticsCalculator->GetLaplacianEnergy() << " " << statisticsCalculator->GetLaplacianSpectralGap() << " " << statisticsCalculator->GetNormalizedLaplacianTrace() << " " << statisticsCalculator->GetNormalizedLaplacianEnergy() << " " << statisticsCalculator->GetNormalizedLaplacianNumberOf2s() << " " << statisticsCalculator->GetNormalizedLaplacianNumberOf1s() << " " << statisticsCalculator->GetNormalizedLaplacianNumberOf0s() << " " << statisticsCalculator->GetNormalizedLaplacianLowerSlope() << " " << statisticsCalculator->GetNormalizedLaplacianUpperSlope() << " " << statisticsCalculator->GetSmallWorldness() << std::endl; } // end global statistics //create connectivity matrix png if( createConnectivityMatriximage ) { std::string connectivity_png_postfix = "_connectivity"; if( binaryConnectivity ) { connectivity_png_postfix += "_binary"; } else if( rescaleConnectivity ) { connectivity_png_postfix += "_rescaled"; } connectivity_png_postfix += ".png"; /* File format * A png file depicting the binary connectivity matrix */ itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::Pointer filter = itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::New(); filter->SetInputNetwork( network ); filter->SetBinaryConnectivity( binaryConnectivity ); filter->SetRescaleConnectivity( rescaleConnectivity ); filter->Update(); typedef itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::OutputImageType connectivityMatrixImageType; itk::ImageFileWriter< connectivityMatrixImageType >::Pointer connectivityWriter = itk::ImageFileWriter< connectivityMatrixImageType >::New(); connectivityWriter->SetInput( filter->GetOutput() ); connectivityWriter->SetFileName( outName + connectivity_png_postfix); connectivityWriter->Update(); std::cout << "Connectivity matrix image written."; } // end create connectivity matrix png /* * We can either calculate local indices for specific nodes, or specific regions */ // Create LabelToIndex translation std::map< std::string, int > labelToIdMap; std::vector< mitk::ConnectomicsNetwork::NetworkNode > nodeVector = thresholdedNetwork->GetVectorOfAllNodes(); for(int loop(0); loop < nodeVector.size(); loop++) { labelToIdMap.insert( std::pair< std::string, int>(nodeVector.at(loop).label, nodeVector.at(loop).id) ); } std::vector< int > degreeVector = thresholdedNetwork->GetDegreeOfNodes(); std::vector< double > ccVector = thresholdedNetwork->GetLocalClusteringCoefficients( ); std::vector< double > bcVector = thresholdedNetwork->GetNodeBetweennessVector( ); // calculate local indices { // only add to header for the first step of the first method if( firstRun ) { localHeaderStream << "Th_method " << "Th_target " << "density"; } double density = statisticsCalculator->GetConnectionDensity(); localDataStream << "\n" << method << " " << targetValue << " " << density; for(unsigned int loop(0); loop < localLabels.size(); loop++ ) { if( network->CheckForLabel(localLabels.at( loop )) ) { if( firstRun ) { localHeaderStream << " " << localLabels.at( loop ) << "_Degree " << localLabels.at( loop ) << "_CC " << localLabels.at( loop ) << "_BC"; } localDataStream << " " << degreeVector.at( labelToIdMap.find( localLabels.at( loop ) )->second ) << " " << ccVector.at( labelToIdMap.find( localLabels.at( loop ) )->second ) << " " << bcVector.at( labelToIdMap.find( localLabels.at( loop ) )->second ); } else { MITK_ERROR << "Illegal label. Label: \"" << localLabels.at( loop ) << "\" not found."; } } } // calculate regional indices { // only add to header for the first step of the first method if( firstRun ) { regionalHeaderStream << "Th_method " << "Th_target " << "density"; } double density = statisticsCalculator->GetConnectionDensity(); regionalDataStream << "\n" << method << " " << targetValue << " " << density; for( parsedRegionsIterator = parsedRegions.begin(); parsedRegionsIterator != parsedRegions.end(); parsedRegionsIterator++ ) { std::vector regionLabelsVector = parsedRegionsIterator->second; std::string regionName = parsedRegionsIterator->first; double sumDegree( 0 ); double sumCC( 0 ); double sumBC( 0 ); double count( 0 ); for( int loop(0); loop < regionLabelsVector.size(); loop++ ) { if( thresholdedNetwork->CheckForLabel(regionLabelsVector.at( loop )) ) { sumDegree = sumDegree + degreeVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second ); sumCC = sumCC + ccVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second ); sumBC = sumBC + bcVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second ); count = count + 1; } else { MITK_ERROR << "Illegal label. Label: \"" << regionLabelsVector.at( loop ) << "\" not found."; } } // only add to header for the first step of the first method if( firstRun ) { regionalHeaderStream << " " << regionName << "_LocalAverageDegree " << regionName << "_LocalAverageCC " << regionName << "_LocalAverageBC " << regionName << "_NumberOfNodes"; } regionalDataStream << " " << sumDegree / count << " " << sumCC / count << " " << sumBC / count << " " << count; // count number of connections and fibers between regions std::map< std::string, std::vector >::iterator loopRegionsIterator; for (loopRegionsIterator = parsedRegionsIterator; loopRegionsIterator != parsedRegions.end(); loopRegionsIterator++) { int numberConnections(0), possibleConnections(0); double summedFiberCount(0.0); std::vector loopLabelsVector = loopRegionsIterator->second; std::string loopName = loopRegionsIterator->first; for (int loop(0); loop < regionLabelsVector.size(); loop++) { if (thresholdedNetwork->CheckForLabel(regionLabelsVector.at(loop))) { for (int innerLoop(0); innerLoop < loopLabelsVector.size(); innerLoop++) { if (thresholdedNetwork->CheckForLabel(loopLabelsVector.at(loop))) { bool exists = thresholdedNetwork->EdgeExists( labelToIdMap.find(regionLabelsVector.at(loop))->second, labelToIdMap.find(loopLabelsVector.at(innerLoop))->second); possibleConnections++; if (exists) { numberConnections++; summedFiberCount += thresholdedNetwork->GetEdge( labelToIdMap.find(regionLabelsVector.at(loop))->second, labelToIdMap.find(loopLabelsVector.at(innerLoop))->second).weight; } } else { MITK_ERROR << "Illegal label. Label: \"" << loopLabelsVector.at(loop) << "\" not found."; } } } else { MITK_ERROR << "Illegal label. Label: \"" << regionLabelsVector.at(loop) << "\" not found."; } } if (firstRun) { regionalHeaderStream << " " << regionName << "_" << loopName << "_Connections " << " " << regionName << "_" << loopName << "_possibleConnections " << " " << regionName << "_" << loopName << "_ConnectingFibers"; } regionalDataStream << " " << numberConnections << " " << possibleConnections << " " << summedFiberCount; } } } firstRun = false; } }// end calculate local averages if( !noGlobalStatistics ) { std::cout << "Writing to " << globalOutName; std::ofstream glocalOutFile( globalOutName.c_str(), ios::out ); if( ! glocalOutFile.is_open() ) { std::string errorMessage = "Could not open " + globalOutName + " for writing."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } glocalOutFile << globalHeaderStream.str() << globalDataStream.str(); glocalOutFile.close(); } if( localLabels.size() > 0 ) { std::cout << "Writing to " << localOutName; std::ofstream localOutFile( localOutName.c_str(), ios::out ); if( ! localOutFile.is_open() ) { std::string errorMessage = "Could not open " + localOutName + " for writing."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } localOutFile << localHeaderStream.str() << localDataStream.str(); localOutFile.close(); } if( parsedRegions.size() > 0 ) { std::cout << "Writing to " << regionalOutName; std::ofstream regionalOutFile( regionalOutName.c_str(), ios::out ); if( ! regionalOutFile.is_open() ) { std::string errorMessage = "Could not open " + regionalOutName + " for writing."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } regionalOutFile << regionalHeaderStream.str() << regionalDataStream.str(); regionalOutFile.close(); } return EXIT_SUCCESS; } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } std::cout << "DONE"; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DeepDiffusion/cmdapps/Caffe2Test.cpp b/Modules/DiffusionImaging/DeepDiffusion/cmdapps/Caffe2Test.cpp index b245a70053..696714589a 100755 --- a/Modules/DiffusionImaging/DeepDiffusion/cmdapps/Caffe2Test.cpp +++ b/Modules/DiffusionImaging/DeepDiffusion/cmdapps/Caffe2Test.cpp @@ -1,197 +1,197 @@ /*=================================================================== 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 #include "mitkCommandLineParser.h" #include // Caffe2 #include #include "caffe2/core/context.h" #include "caffe2/core/operator.h" #include "caffe2/core/predictor.h" #include "caffe2/core/tensor.h" #include "caffe2/utils/math.h" #include #include #include #include // OpenCV #include #include template void to_tensor(cv::Mat &img, TensorType &tensor) { const int num_channel = tensor.dim(1); const int height = tensor.dim(2); const int width = tensor.dim(3); assert(img.channels() == num_channel); assert(img.cols == width); assert(img.rows == height); // convert to float if (num_channel==3 && img.type()!=CV_32FC3) img.convertTo(img, CV_32FC3); else if(num_channel==1 && img.type()!=CV_32FC1) img.convertTo(img, CV_32FC1); // subtract mean img -= 128; // necessary? // caffe2::CPUContext cpu_context; // caffe2::TensorCPU cpu_input(tensor, &cpu_context); // float* tensor_data = cpu_input.template mutable_data(); float* tensor_data = tensor.template mutable_data(); // create array of cv::Mat where each matrix points to the tensor data std::vector bgr; for (int i = 0; i < num_channel; ++i) { bgr.push_back(cv::Mat(height, width, CV_32FC1, tensor_data)); tensor_data += width * height; } // HWC to CHW // splits 3 channel matrix into three single channel matrices cv::split(img, bgr); } /*! * \brief Minimal example for Caffe2 prediction in MITK * */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Caffe2Test"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("MITK Diffusion Deep Learning"); parser.setContributor("MIC"); parser.setDescription("Minimal example for Caffe2 prediction in MITK"); parser.setArgumentPrefix("--", "-"); parser.addArgument("image", "", mitkCommandLineParser::String, "image:", "", us::Any()); parser.addArgument("init_net", "", mitkCommandLineParser::String, "init_net:", "the network weights (.pb)", us::Any()); parser.addArgument("predict_net", "", mitkCommandLineParser::String, "predict_net:", "the network definition (.pb)", us::Any()); // typedef caffe2::TensorCPU TensorType; typedef caffe2::TensorCUDA TensorType; std::map parsedArgs = parser.parseArguments(argc, argv); std::string init_net_filename = us::any_cast(parsedArgs["init_net"]); std::string predict_net_filename = us::any_cast(parsedArgs["predict_net"]); // std::string image_filename = us::any_cast(parsedArgs["image"]); // cv::Mat img = cv::imread(image_filename, CV_LOAD_IMAGE_COLOR); // cv::Mat img = cv::Mat(64,64,CV_32FC3,128); // cv::namedWindow( "Display window", cv::WINDOW_AUTOSIZE );// Create a window for display. // cv::imshow( "Display w30indow", img2 ); // Show our image inside it. // cv::waitKey(0); // Wait for a keystroke in the window caffe2::NetDef init_net, predict_net; CAFFE_ENFORCE(ReadProtoFromFile(init_net_filename, &init_net)); CAFFE_ENFORCE(ReadProtoFromFile(predict_net_filename, &predict_net)); MITK_INFO << "Predict net: " << ProtoDebugString(predict_net); std::vector outputVec; int w,h,c; w=64; h=64; c=1; TensorType input(std::vector({1, h, w, c})); //// TRYING TO ACCESS TENSOR DATA (RESULTS IN ERROR FOR caffe2::TensorCUDA) // caffe2::CPUContext cpu_context; // caffe2::TensorCPU cpu_input(input, &cpu_context); // float* input_data = cpu_input.template mutable_data(); float* input_data = input.mutable_data(); // create input image (simply a square of size 10x10 in a 64x64 image) // test image for segmentation int counter = 0; for (int x = 0; x < h; x++) for (int y = 0; y < w; y++) { for (int j = 0; j < c; j++) { input_data[counter] = 0; if (x>20 && x<30 && y>20 && y<30) input_data[counter] = 1; counter++; } } // show input image cv::Mat img = cv::Mat(64,64,CV_32FC1,input_data); cv::namedWindow( "Display window", cv::WINDOW_AUTOSIZE );// Create a window for display. cv::imshow( "Display window", img ); // Show our image inside it. cv::waitKey(0); // Wait for a keystroke in the window // run network std::vector inputVec{input}; caffe2::Workspace ws; ws.RunNetOnce(init_net); ws.CreateNet(predict_net, true); for (auto i = 0; i < inputVec.size(); ++i) { auto* blob = ws.GetBlob(predict_net.external_input(i)); TensorType* tensor = blob->template GetMutable(); tensor->ResizeLike(inputVec[i]); tensor->ShareData(inputVec[i]); } CAFFE_ENFORCE(ws.RunNet(predict_net.name())); outputVec.resize(predict_net.external_output_size()); for (auto i = 0; i < outputVec.size(); ++i) { auto* blob = ws.GetBlob(predict_net.external_output(i)); outputVec[i] = blob->template GetMutable(); } //// auto predictor = caffe2::make_unique(init_net, predict_net); //// predictor->run(inputVec, &outputVec); // get ourput from network TensorType* output = outputVec[outputVec.size()]; const float* output_data = output->data(); cv::Mat out_img = cv::Mat(64,64,CV_32FC3,output->mutable_data()); cv::namedWindow( "Display window", cv::WINDOW_AUTOSIZE );// Create a window for display. cv::imshow( "Display window", out_img ); // Show our image inside it. cv::waitKey(0); // Wait for a keystroke in the window //// remainder of the classification test // int max_class = -1; // float max_prob = 0; // for (int i=0; isize(); i++) // { // if(output_data[i]>max_prob) // { // max_prob = output_data[i]; // max_class = i; // } // } // MITK_INFO << "Class: " << max_class; // MITK_INFO << "Probability: " << max_prob; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DeepDiffusion/cmdapps/CaffeSegmentationTest.cpp b/Modules/DiffusionImaging/DeepDiffusion/cmdapps/CaffeSegmentationTest.cpp index 75b62ad646..553d687d1b 100755 --- a/Modules/DiffusionImaging/DeepDiffusion/cmdapps/CaffeSegmentationTest.cpp +++ b/Modules/DiffusionImaging/DeepDiffusion/cmdapps/CaffeSegmentationTest.cpp @@ -1,123 +1,123 @@ /*=================================================================== 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 #include #include #include // Caffe #include #include #include #include // OpenCV #include #include std::default_random_engine generator; std::normal_distribution distribution(0.0,0.1); void predict(caffe::shared_ptr> network) { caffe::Blob* input_layer = network->input_blobs()[0]; float* input_data = input_layer->mutable_cpu_data(); int counter = 0; for (int x = 0; x < input_layer->height(); x++) for (int y = 0; y < input_layer->width(); y++) for (int j = 0; j < input_layer->channels(); j++) { input_data[counter] = 0; if (x>20 && x<40 && y>20 && y<40) input_data[counter] = 1; if (x>35 && x<55 && y>25 && y<45) input_data[counter] = 2; if (x>2 && x<12 && y>45 && y<55) input_data[counter] = 1; if (x>50 && x<60 && y>50 && y<60) input_data[counter] = 1; input_data[counter] += distribution(generator); counter++; } // // not necessary here // input_layer->Reshape(1, num_channels, height, width); // network->Reshape(); network->Forward(); cv::Mat input_img = cv::Mat(input_layer->height(), input_layer->width(), CV_32FC1, input_data) * 100; input_img.convertTo(input_img, CV_8UC1); cv::namedWindow( "Input", cv::WINDOW_NORMAL ); cv::imshow( "Input", input_img ); boost::shared_ptr > output_layer = network->blob_by_name("argmax"); cv::Mat out_img = cv::Mat(input_layer->height(), input_layer->width(), CV_32FC1, output_layer->mutable_cpu_data()) * 100; out_img.convertTo(out_img, CV_8UC1); cv::namedWindow( "Output", cv::WINDOW_NORMAL ); cv::imshow( "Output", out_img ); cv::waitKey(0); } /*! * \brief Segmentation example for Caffe in MITK * */ int main(int argc, char* argv[]) { caffe::Caffe::set_mode(caffe::Caffe::GPU); mitkCommandLineParser parser; parser.setTitle("CaffeTest"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("MITK Diffusion Deep Learning"); parser.setContributor("MIC"); parser.setDescription("Minimal example for Caffe usage in MITK"); parser.setArgumentPrefix("--", "-"); parser.addArgument("network_file", "", mitkCommandLineParser::String, "network_file:", ".prototxt", us::Any()); parser.addArgument("weights_file", "", mitkCommandLineParser::String, "weights_file:", ".caffemodel", us::Any()); // google::InitGoogleLogging(argv[0]); // google::SetCommandLineOption("GLOG_minloglevel", "0"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string network_file = us::any_cast(parsedArgs["network_file"]); std::string weights_file = us::any_cast(parsedArgs["weights_file"]); caffe::shared_ptr> network; const std::vector stages = {"deploy"}; network.reset(new caffe::Net(network_file, caffe::TEST, 0, &stages)); network->CopyTrainedLayersFrom(weights_file); predict(network); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DeepDiffusion/cmdapps/CaffeTest.cpp b/Modules/DiffusionImaging/DeepDiffusion/cmdapps/CaffeTest.cpp index de1e99be15..ca4d4aba30 100755 --- a/Modules/DiffusionImaging/DeepDiffusion/cmdapps/CaffeTest.cpp +++ b/Modules/DiffusionImaging/DeepDiffusion/cmdapps/CaffeTest.cpp @@ -1,189 +1,189 @@ /*=================================================================== 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 #include #include #include // Caffe #include #include #include #include // OpenCV #include #include caffe::shared_ptr> train(caffe::Solver* solver) { int num_samples = 64; int num_features = 100; float *data = new float[1*1*num_features*num_samples]; float *label = new float[1*1*1*num_samples]; float *directions = new float[1*1*3*num_samples]; caffe::MemoryDataLayer *image_input_layer = (caffe::MemoryDataLayer *) (solver->net()->layer_by_name("image_data").get()); caffe::MemoryDataLayer *target_input_layer = (caffe::MemoryDataLayer *) (solver->net()->layer_by_name("target_data").get()); image_input_layer->Reset(data, label, num_samples); target_input_layer->Reset(directions, label, num_samples); solver->Solve(); return solver->net(); } caffe::Solver* read_solver(std::string solver_file) { caffe::SolverParameter solver_param; caffe::ReadSolverParamsFromTextFileOrDie(solver_file, &solver_param); return new caffe::AdamSolver(solver_param); } std::default_random_engine generator; std::normal_distribution distribution(0.0,0.1); void predict(caffe::shared_ptr> network) { caffe::Blob* input_layer = network->input_blobs()[0]; float* input_data = input_layer->mutable_cpu_data(); int counter = 0; for (int x = 0; x < input_layer->height(); x++) for (int y = 0; y < input_layer->width(); y++) for (int j = 0; j < input_layer->channels(); j++) { input_data[counter] = 0; if (x>20 && x<40 && y>20 && y<40) input_data[counter] = 1; if (x>35 && x<55 && y>25 && y<45) input_data[counter] = 2; if (x>2 && x<12 && y>45 && y<55) input_data[counter] = 1; if (x>50 && x<60 && y>50 && y<60) input_data[counter] = 1; input_data[counter] += distribution(generator); counter++; } network->Forward(); cv::Mat input_img = cv::Mat(input_layer->height(), input_layer->width(), CV_32FC1, input_data) * 100; input_img.convertTo(input_img, CV_8UC1); cv::namedWindow( "Input", cv::WINDOW_NORMAL ); cv::imshow( "Input", input_img ); boost::shared_ptr > output_layer = network->blob_by_name("argmax"); cv::Mat out_img = cv::Mat(input_layer->height(), input_layer->width(), CV_32FC1, output_layer->mutable_cpu_data()) * 100; out_img.convertTo(out_img, CV_8UC1); cv::namedWindow( "Output", cv::WINDOW_NORMAL ); cv::imshow( "Output", out_img ); cv::waitKey(0); } std::vector predict_data_layer(const cv::Mat& img, caffe::shared_ptr> network) { caffe::Blob* input_layer = network->input_blobs()[0]; assert(img.channels() == input_layer->channels()); assert(img.cols == input_layer->width()); assert(img.rows == input_layer->height()); cv::Mat img2; // convert to float if (img.channels()==3 && img.type()!=CV_32FC3) img.convertTo(img2, CV_32FC3); else if(img.channels()==1 && img.type()!=CV_32FC1) img.convertTo(img2, CV_32FC1); float* input_data = input_layer->mutable_cpu_data(); // pointer to the memory data layer std::vector bgr; for (int i = 0; i < img2.channels(); ++i) { cv::Mat channel(input_layer->height(), input_layer->width(), CV_32FC1, input_data); bgr.push_back(channel); input_data += input_layer->width() * input_layer->height(); } cv::split(img2, bgr); network->Forward(); /* Copy the output layer to a std::vector */ caffe::Blob* output_layer = network->output_blobs()[0]; const float* begin = output_layer->cpu_data(); const float* end = begin + output_layer->channels(); return std::vector(begin, end); } /*! * \brief Segmentation example for Caffe in MITK * */ int main(int argc, char* argv[]) { caffe::Caffe::set_mode(caffe::Caffe::GPU); mitkCommandLineParser parser; parser.setTitle("CaffeTest"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("MITK Diffusion Deep Learning"); parser.setContributor("MIC"); parser.setDescription("Minimal example for Caffe usage in MITK"); parser.setArgumentPrefix("--", "-"); parser.addArgument("image", "", mitkCommandLineParser::String, "image:", "", us::Any()); parser.addArgument("solver_file", "", mitkCommandLineParser::String, "solver_file:", "the caffe solver file (.prototxt)", us::Any()); parser.addArgument("network_file", "", mitkCommandLineParser::String, "network_file:", ".prototxt", us::Any()); parser.addArgument("weights_file", "", mitkCommandLineParser::String, "weights_file:", ".caffemodel", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string image_filename = us::any_cast(parsedArgs["image"]); cv::Mat img = cv::imread(image_filename, CV_LOAD_IMAGE_GRAYSCALE); // cv::namedWindow( "Display window", cv::WINDOW_AUTOSIZE );// Create a window for display. // cv::imshow( "Display window", img ); // Show our image inside it. // cv::waitKey(0); // Wait for a keystroke in the window //// TRAINING // std::string solver_file = us::any_cast(parsedArgs["solver_file"]); // caffe::Solver* solver = read_solver(solver_file); // caffe::shared_ptr> trained_net = train(solver); // const float* test_output = test(trained_net); std::string network_file = us::any_cast(parsedArgs["network_file"]); std::string weights_file = us::any_cast(parsedArgs["weights_file"]); caffe::shared_ptr> network; const std::vector stages = {"deploy"}; network.reset(new caffe::Net(network_file, caffe::TEST, 0, &stages)); network->CopyTrainedLayersFrom(weights_file); MITK_INFO << "predicting"; predict(network); MITK_INFO << "DONE"; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt b/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt index 1fe5feb7d2..83a538fd92 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt @@ -1,44 +1,45 @@ option(BUILD_DiffusionCoreCmdApps "Build commandline tools for diffusion" OFF) if(BUILD_DiffusionCoreCmdApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # list of diffusion cmdapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" set( diffusioncorecmdapps DwiDenoising^^ ImageResampler^^ ExportShImage^^ CopyGeometry^^ - DiffusionIndices^^ - QballReconstruction^^ Registration^^ - TensorReconstruction^^ - TensorDerivedMapsExtraction^^ DiffusionDICOMLoader^^ - DiffusionKurtosisFit^^ + ResampleGradients^^ ) foreach(diffusioncorecmdapp ${diffusioncorecmdapps}) # extract cmd app name and dependencies string(REPLACE "^^" "\\;" cmdapp_info ${diffusioncorecmdapp}) set(cmdapp_info_list ${cmdapp_info}) list(GET cmdapp_info_list 0 appname) list(GET cmdapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitkFunctionCreateCommandLineApp( NAME ${appname} DEPENDS MitkCore MitkDiffusionCore ${dependencies_list} PACKAGE_DEPENDS ITK ) endforeach() + +endif() - endif() +mitkFunctionCreateCommandLineApp( + NAME Dicom2Nrrd + DEPENDS MitkCore ${dependencies_list} +) diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CopyGeometry.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/CopyGeometry.cpp index faef7719ce..e99ed7766e 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CopyGeometry.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/CopyGeometry.cpp @@ -1,117 +1,117 @@ /*=================================================================== 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 "mitkCommandLineParser.h" using namespace mitk; using namespace std; /*! \brief Copies transformation matrix of one image to another */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Copy Geometry"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Copies transformation matrix of one image to another"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(), false); parser.addArgument("ref", "r", mitkCommandLineParser::InputFile, "Reference:", "reference image", us::Any(), false); parser.addArgument("alignCentroid", "a", mitkCommandLineParser::Bool, "align centroids", "align centroids", us::Any(), true); parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output image", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments string imageName = us::any_cast(parsedArgs["in"]); string refImage = us::any_cast(parsedArgs["ref"]); string outImage = us::any_cast(parsedArgs["out"]); bool originOnly = false; // Show a help message if ( parsedArgs.count("alignCentroid") || parsedArgs.count("a")) { originOnly = true; } try { Image::Pointer source = mitk::IOUtil::LoadImage(refImage); Image::Pointer target = mitk::IOUtil::LoadImage(imageName); if (originOnly) { // Calculate correction to align centroids double c[3]; c[0] = source->GetGeometry()->GetOrigin()[0] + source->GetGeometry()->GetExtent(0)/2.0 - target->GetGeometry()->GetOrigin()[0] - target->GetGeometry()->GetExtent(0)/2.0; c[1] = source->GetGeometry()->GetOrigin()[1] + source->GetGeometry()->GetExtent(1)/2.0 - target->GetGeometry()->GetOrigin()[1] - target->GetGeometry()->GetExtent(1)/2.0; c[2] = source->GetGeometry()->GetOrigin()[2] + source->GetGeometry()->GetExtent(2)/2.0 - target->GetGeometry()->GetOrigin()[2] - target->GetGeometry()->GetExtent(2)/2.0; double newOrigin[3]; newOrigin[0] = target->GetGeometry()->GetOrigin()[0] +c[0]; newOrigin[1] = target->GetGeometry()->GetOrigin()[1] +c[1]; newOrigin[2] = target->GetGeometry()->GetOrigin()[2] +c[2]; target->GetGeometry()->SetOrigin(newOrigin); } else { mitk::BaseGeometry* s_geom = source->GetGeometry(); mitk::BaseGeometry* t_geom = target->GetGeometry(); t_geom->SetIndexToWorldTransform(s_geom->GetIndexToWorldTransform()); target->SetGeometry(t_geom); } mitk::IOUtil::SaveImage(target, outImage); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/Dicom2Nrrd.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/Dicom2Nrrd.cpp similarity index 98% rename from Modules/DiffusionImaging/cmdapps/Dicom2Nrrd.cpp rename to Modules/DiffusionImaging/DiffusionCore/cmdapps/Dicom2Nrrd.cpp index 9d0f6d82e1..43470988d3 100644 --- a/Modules/DiffusionImaging/cmdapps/Dicom2Nrrd.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/Dicom2Nrrd.cpp @@ -1,88 +1,88 @@ /*=================================================================== 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 "mitkDicomSeriesReader.h" #include "mitkProperties.h" #include "mitkCommandLineParser.h" #include "mitkIOUtil.h" using namespace std; int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Dicom Loader"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input folder:", "Input folder",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file",us::Any(),false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputFolder = us::any_cast(parsedArgs["input"]); std::string outFileName = us::any_cast(parsedArgs["output"]); //check if DICOMTags have been set as property for mitk::Image mitk::DicomSeriesReader::FileNamesGrouping seriesInFiles = mitk::DicomSeriesReader::GetSeries( inputFolder, true ); std::list images; std::map fileMap; // TODO sort series UIDs, implementation of map iterator might differ on different platforms (or verify this is a standard topic??) for (mitk::DicomSeriesReader::FileNamesGrouping::const_iterator seriesIter = seriesInFiles.begin(); seriesIter != seriesInFiles.end(); ++seriesIter) { mitk::DicomSeriesReader::StringContainer files = seriesIter->second.GetFilenames(); mitk::DataNode::Pointer node = mitk::DicomSeriesReader::LoadDicomSeries( files ); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); images.push_back( image ); fileMap.insert( std::pair(image,files)); } } // WARN: EXPECT ONLY ONE ITEM PER FOLDER for ( std::list::const_iterator imageIter = images.begin(); imageIter != images.end(); ++imageIter ) { const mitk::Image::Pointer image = *imageIter; mitk::IOUtil::SaveImage(image,outFileName); } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionDICOMLoader.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionDICOMLoader.cpp index 9b7cfbbb35..f3e82db6c1 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionDICOMLoader.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionDICOMLoader.cpp @@ -1,318 +1,318 @@ /*=================================================================== 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 "mitkImage.h" #include "mitkBaseData.h" #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include "mitkDiffusionDICOMFileReader.h" #include "mitkSortByImagePositionPatient.h" #include "mitkDICOMTagBasedSorter.h" #include "mitkDICOMSortByTag.h" #include "itkMergeDiffusionImagesFilter.h" #include using namespace std; static mitk::StringList& GetInputFilenames() { static mitk::StringList inputs; return inputs; } // FIXME slash at the end void SetInputFileNames( std::string input_directory ) { // I. Get all files in directory itksys::Directory input; input.Load( input_directory.c_str() ); // II. Push back files mitk::StringList inputlist;//, mergedlist; for( unsigned long idx=0; idxAddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0010) ); // Number of Rows tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0011) ); // Number of Columns tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0030) ); // Pixel Spacing tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x1164) ); // Imager Pixel Spacing tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0037) ); // Image Orientation (Patient) // TODO add tolerance parameter (l. 1572 of original code) // TODO handle as real vectors! cluster with configurable errors! tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x000e) ); // Series Instance UID tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x0050) ); // Slice Thickness tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0008) ); // Number of Frames //tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0052) ); // Frame of Reference UID // gdcmReader->AddSortingElement( tagSorter ); //mitk::DICOMFileReaderTestHelper::TestOutputsContainInputs( gdcmReader ); mitk::DICOMSortCriterion::ConstPointer sorting = mitk::SortByImagePositionPatient::New( // Image Position (Patient) //mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0013), // instance number mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0012), // aqcuisition number mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0032), // aqcuisition time mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0018, 0x1060), // trigger time mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0018) // SOP instance UID (last resort, not really meaningful but decides clearly) ).GetPointer() ).GetPointer() ).GetPointer() ).GetPointer() // ).GetPointer() ).GetPointer(); tagSorter->SetSortCriterion( sorting ); // mosaic //gdcmReader->SetResolveMosaic( this->m_Controls->m_SplitMosaicCheckBox->isChecked() ); gdcmReader->AddSortingElement( tagSorter );*/ gdcmReader->SetInputFiles( input_files ); try { gdcmReader->AnalyzeInputFiles(); } catch( const itk::ExceptionObject &e) { MITK_ERROR << "Failed to analyze data. " << e.what(); } catch( const std::exception &se) { MITK_ERROR << "Std Exception " << se.what(); } gdcmReader->LoadImages(); mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(0).GetMitkImage(); return loaded_image; } typedef short DiffusionPixelType; typedef itk::VectorImage DwiImageType; typedef DwiImageType::PixelType DwiPixelType; typedef DwiImageType::RegionType DwiRegionType; typedef std::vector< DwiImageType::Pointer > DwiImageContainerType; typedef mitk::Image DiffusionImageType; typedef mitk::DiffusionPropertyHelper::GradientDirectionsContainerType GradientContainerType; typedef std::vector< GradientContainerType::Pointer > GradientListContainerType; void SearchForInputInSubdirs( std::string root_directory, std::string subdir_prefix , std::vector& output_container) { // I. Get all dirs in directory itksys::Directory rootdir; rootdir.Load( root_directory.c_str() ); MITK_INFO("dicom.loader.setinputdirs.start") << "Prefix = " << subdir_prefix; for( unsigned int idx=0; idx parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } std::string inputDirectory = us::any_cast( parsedArgs["inputdir"] ); MITK_INFO << "Loading data from directory: " << inputDirectory; // retrieve the prefix flag (if set) bool search_for_subdirs = false; std::string subdir_prefix; if( parsedArgs.count("dwprefix")) { subdir_prefix = us::any_cast( parsedArgs["dwprefix"] ); if (subdir_prefix != "") { MITK_INFO << "Prefix specified, will search for subdirs in the input directory!"; search_for_subdirs = true; } } // retrieve the output std::string outputFile = us::any_cast< std::string >( parsedArgs["output"] ); // if the executable is called with a single directory, just parse the given folder for files and read them into a diffusion image if( !search_for_subdirs ) { SetInputFileNames( inputDirectory ); MITK_INFO << "Got " << GetInputFilenames().size() << " input files."; mitk::Image::Pointer d_img = ReadInDICOMFiles( GetInputFilenames(), outputFile ); try { mitk::IOUtil::Save(d_img, outputFile.c_str()); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Failed to write out the output file. \n\t Reason : ITK Exception " << e.what(); } } // if the --dwprefix flag is set, then we have to look for the directories, load each of them separately and afterwards merge the images else { std::vector output_container; SearchForInputInSubdirs( inputDirectory, subdir_prefix, output_container ); // final output image mitk::Image::Pointer image = mitk::Image::New(); if( output_container.size() > 1 ) { DwiImageContainerType imageContainer; GradientListContainerType gradientListContainer; std::vector< double > bValueContainer; for ( std::vector< mitk::Image::Pointer >::iterator dwi = output_container.begin(); dwi != output_container.end(); ++dwi ) { mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(*dwi, itkVectorImagePointer); imageContainer.push_back(itkVectorImagePointer); gradientListContainer.push_back( mitk::DiffusionPropertyHelper::GetGradientContainer(*dwi)); bValueContainer.push_back( mitk::DiffusionPropertyHelper::GetReferenceBValue(*dwi)); } typedef itk::MergeDiffusionImagesFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetImageVolumes(imageContainer); filter->SetGradientLists(gradientListContainer); filter->SetBValues(bValueContainer); filter->Update(); vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity(); image = mitk::GrabItkImageMemory( filter->GetOutput() ); image->SetProperty( mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetOutputGradients() ) ); image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( filter->GetB_Value() ) ); image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( mf ) ); mitk::DiffusionPropertyHelper propertyHelper( image ); propertyHelper.InitializeImage(); } // just output the image if there was only one folder found else { image = output_container.at(0); } MITK_INFO("dicom.import.writeout") << " [OutputFile] " << outputFile.c_str(); try { mitk::IOUtil::Save(image, outputFile.c_str()); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Failed to write out the output file. \n\t Reason : ITK Exception " << e.what(); } } return 1; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DwiDenoising.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/DwiDenoising.cpp index ecc9760b19..cedf6d0524 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DwiDenoising.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/DwiDenoising.cpp @@ -1,139 +1,139 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include using namespace std; typedef mitk::Image DiffusionImageType; typedef itk::Image ImageType; /** * Denoises DWI using the Nonlocal - Means algorithm */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("DWI Denoising"); parser.setCategory("Preprocessing Tools"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setDescription("Denoising for diffusion weighted images using a non-local means algorithm."); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image (DWI)", us::Any(), false); parser.addArgument("variance", "v", mitkCommandLineParser::Float, "Variance:", "noise variance", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "brainmask for input image", us::Any(), true); parser.addArgument("search", "s", mitkCommandLineParser::Int, "Search radius:", "search radius", us::Any(), true); parser.addArgument("compare", "c", mitkCommandLineParser::Int, "Comparison radius:", "comparison radius", us::Any(), true); parser.addArgument("joint", "j", mitkCommandLineParser::Bool, "Joint information:", "use joint information"); parser.addArgument("rician", "r", mitkCommandLineParser::Bool, "Rician adaption:", "use rician adaption"); parser.changeParameterGroup("Output", "Output of this miniapp"); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output:", "output image (DWI)", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFileName = us::any_cast(parsedArgs["input"]); double variance = static_cast(us::any_cast(parsedArgs["variance"])); string maskName; if (parsedArgs.count("mask")) maskName = us::any_cast(parsedArgs["mask"]); string outFileName = us::any_cast(parsedArgs["output"]); // boost::algorithm::erase_all(outFileName, ".dwi"); int search = 4; if (parsedArgs.count("search")) search = us::any_cast(parsedArgs["search"]); int compare = 1; if (parsedArgs.count("compare")) compare = us::any_cast(parsedArgs["compare"]); bool joint = false; if (parsedArgs.count("joint")) joint = true; bool rician = false; if (parsedArgs.count("rician")) rician = true; try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); DiffusionImageType::Pointer dwi = mitk::IOUtil::LoadImage(inFileName, &functor); mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); itk::NonLocalMeansDenoisingFilter::Pointer filter = itk::NonLocalMeansDenoisingFilter::New(); filter->SetNumberOfThreads(12); filter->SetInputImage( itkVectorImagePointer ); if (!maskName.empty()) { mitk::Image::Pointer mask = mitk::IOUtil::LoadImage(maskName); ImageType::Pointer itkMask = ImageType::New(); mitk::CastToItkImage(mask, itkMask); filter->SetInputMask(itkMask); } filter->SetUseJointInformation(joint); filter->SetUseRicianAdaption(rician); filter->SetSearchRadius(search); filter->SetComparisonRadius(compare); filter->SetVariance(variance); filter->Update(); DiffusionImageType::Pointer output = mitk::GrabItkImageMemory( filter->GetOutput() ); output->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi) ) ); output->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi) ) ); mitk::DiffusionPropertyHelper propertyHelper( output ); propertyHelper.InitializeImage(); // std::stringstream name; // name << outFileName << "_NLM_" << search << "-" << compare << "-" << variance << ".dwi"; mitk::IOUtil::Save(output, outFileName.c_str()); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ExportShImage.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ExportShImage.cpp index 9a00b545f2..79424657ff 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ExportShImage.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ExportShImage.cpp @@ -1,139 +1,139 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include using namespace std; /*! \brief Convert MITK spherical harmonics image type to MRtrix spherical harmonics image */ template int StartShConversion(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Export SH Image"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Convert MITK spherical harmonics image type to MRtrix spherical harmonics image"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "MITK SH image", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::InputFile, "Output", "MRtrix SH image", us::Any(), false); parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "SH order:", "spherical harmonics order"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFile = us::any_cast(parsedArgs["input"]); string outFile = us::any_cast(parsedArgs["output"]); try { typedef itk::Image< float, 4 > OutImageType; typedef itk::Image< itk::Vector< float, (shOrder*shOrder + shOrder + 2)/2 + shOrder >, 3 > InputImageType; typename InputImageType::Pointer itkInImage = InputImageType::New(); typedef itk::ImageFileReader< InputImageType > ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); std::cout << "reading " << inFile; reader->SetFileName(inFile.c_str()); reader->Update(); itkInImage = reader->GetOutput(); // extract directions from fiber bundle typename itk::ShCoefficientImageExporter::Pointer filter = itk::ShCoefficientImageExporter::New(); filter->SetInputImage(itkInImage); filter->GenerateData(); OutImageType::Pointer outImage = filter->GetOutputImage(); mitk::Image::Pointer image = mitk::GrabItkImageMemory(outImage.GetPointer()); mitk::IOUtil::Save(image, outFile ); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input image", "MITK SH image", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output image", "MRtrix SH image", us::Any(), false); parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order"); parser.setCategory("Preprocessing Tools"); parser.setTitle("Export SH Image"); parser.setDescription(" "); - parser.setContributor("MBI"); + parser.setContributor("MIC"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; int shOrder = -1; if (parsedArgs.count("shOrder")) shOrder = us::any_cast(parsedArgs["shOrder"]); switch (shOrder) { case 4: return StartShConversion<4>(argc, argv); case 6: return StartShConversion<6>(argc, argv); case 8: return StartShConversion<8>(argc, argv); case 10: return StartShConversion<10>(argc, argv); case 12: return StartShConversion<12>(argc, argv); } return EXIT_FAILURE; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ImageResampler.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ImageResampler.cpp index 75f2804cd4..1b02efae43 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ImageResampler.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ImageResampler.cpp @@ -1,433 +1,433 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include // ITK #include #include #include "itkLinearInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkIdentityTransform.h" #include "itkResampleImageFilter.h" #include "itkResampleDwiImageFilter.h" using namespace std; typedef itk::Image InputImageType; typedef itk::Image BinaryImageType; static mitk::Image::Pointer TransformToReference(mitk::Image *reference, mitk::Image *moving, bool sincInterpol = false, bool nn = false) { // Convert to itk Images // Identify Transform typedef itk::IdentityTransform T_Transform; T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 3> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); typedef itk::LinearInterpolateImageFunction< InputImageType> LinearInterpolateImageFunctionType; LinearInterpolateImageFunctionType::Pointer lin_interpolator = LinearInterpolateImageFunctionType::New(); typedef itk::NearestNeighborInterpolateImageFunction< BinaryImageType> NearestNeighborInterpolateImageFunctionType; NearestNeighborInterpolateImageFunctionType::Pointer nn_interpolator = NearestNeighborInterpolateImageFunctionType::New(); if (!nn) { InputImageType::Pointer itkReference = InputImageType::New(); InputImageType::Pointer itkMoving = InputImageType::New(); mitk::CastToItkImage(reference,itkReference); mitk::CastToItkImage(moving,itkMoving); typedef itk::ResampleImageFilter ResampleFilterType; ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkMoving); resampler->SetReferenceImage( itkReference ); resampler->UseReferenceImageOn(); resampler->SetTransform(_pTransform); if ( sincInterpol) resampler->SetInterpolator(sinc_interpolator); else resampler->SetInterpolator(lin_interpolator); resampler->Update(); // Convert back to mitk mitk::Image::Pointer result = mitk::Image::New(); result->InitializeByItk(resampler->GetOutput()); GrabItkImageMemory( resampler->GetOutput() , result ); return result; } BinaryImageType::Pointer itkReference = BinaryImageType::New(); BinaryImageType::Pointer itkMoving = BinaryImageType::New(); mitk::CastToItkImage(reference,itkReference); mitk::CastToItkImage(moving,itkMoving); typedef itk::ResampleImageFilter ResampleFilterType; ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkMoving); resampler->SetReferenceImage( itkReference ); resampler->UseReferenceImageOn(); resampler->SetTransform(_pTransform); resampler->SetInterpolator(nn_interpolator); resampler->Update(); // Convert back to mitk mitk::Image::Pointer result = mitk::Image::New(); result->InitializeByItk(resampler->GetOutput()); GrabItkImageMemory( resampler->GetOutput() , result ); return result; } static std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } static std::vector split(const std::string &s, char delim) { std::vector < std::string > elems; return split(s, delim, elems); } static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing, bool useLinInt = true, bool useNN = false) { if (!useNN) { InputImageType::Pointer itkImage = InputImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. InputImageType::SpacingType inputSpacing = itkImage->GetSpacing(); InputImageType::SpacingType outputSpacing; const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); InputImageType::SizeType outputSize; typedef InputImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::LinearInterpolateImageFunction< InputImageType > LinearInterpolatorType; LinearInterpolatorType::Pointer lin_interpolator = LinearInterpolatorType::New(); typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); if (useLinInt) _pResizeFilter->SetInterpolator(lin_interpolator); else _pResizeFilter->SetInterpolator(sinc_interpolator); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } BinaryImageType::Pointer itkImage = BinaryImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. BinaryImageType::SpacingType inputSpacing = itkImage->GetSpacing(); BinaryImageType::SpacingType outputSpacing; const BinaryImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); BinaryImageType::SizeType outputSize; typedef BinaryImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::NearestNeighborInterpolateImageFunction< BinaryImageType> NearestNeighborInterpolateImageType; NearestNeighborInterpolateImageType::Pointer nn_interpolator = NearestNeighborInterpolateImageType::New(); _pResizeFilter->SetInterpolator(nn_interpolator); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } /// Save images according to file type static void SaveImage(std::string fileName, mitk::Image* image, std::string fileType ) { std::cout << "----Save to " << fileName; mitk::IOUtil::Save(image, fileName); } mitk::Image::Pointer ResampleDWIbySpacing(mitk::Image::Pointer input, float* spacing, bool useLinInt = true) { itk::Vector spacingVector; spacingVector[0] = spacing[0]; spacingVector[1] = spacing[1]; spacingVector[2] = spacing[2]; typedef itk::ResampleDwiImageFilter ResampleFilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(input, itkVectorImagePointer); ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput( itkVectorImagePointer ); resampler->SetInterpolation(ResampleFilterType::Interpolate_Linear); resampler->SetNewSpacing(spacingVector); resampler->Update(); mitk::Image::Pointer output = mitk::GrabItkImageMemory( resampler->GetOutput() ); output->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( mitk::DiffusionPropertyHelper::GetGradientContainer(input) ) ); output->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( mitk::DiffusionPropertyHelper::GetReferenceBValue(input) ) ); mitk::DiffusionPropertyHelper propertyHelper( output ); propertyHelper.InitializeImage(); return output; } int main( int argc, char* argv[] ) { mitkCommandLineParser parser; parser.setArgumentPrefix("--","-"); parser.setTitle("Image Resampler"); parser.setCategory("Preprocessing Tools"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setDescription("Resample an image to eigther a specific spacing or to a reference image."); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "Input:", "Input file",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output:", "Output file",us::Any(),false); parser.addArgument("spacing", "s", mitkCommandLineParser::String, "Spacing:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); parser.addArgument("reference", "r", mitkCommandLineParser::InputImage, "Reference:", "Resample using supplied reference image. Also cuts image to same dimensions",us::Any()); parser.addArgument("win-sinc", "w", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); parser.addArgument("nearest-neigh", "n", mitkCommandLineParser::Bool, "Nearest Neighbor:", "Use Nearest Neighbor interpolation instead of linear interpolation ",us::Any()); map parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool useSpacing = false; bool useLinearInterpol = true; bool useNN= false; { if (parsedArgs.size() == 0) { return EXIT_FAILURE; } if (parsedArgs.count("sinc-int")) useLinearInterpol = false; if (parsedArgs.count("nearest-neigh")) useNN = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string outputFile = us::any_cast(parsedArgs["output"]); std::string inputFile = us::any_cast(parsedArgs["input"]); std::vector spacings; float spacing[3]; if (parsedArgs.count("spacing")) { std::string arg = us::any_cast(parsedArgs["spacing"]); if (arg != "") { spacings = split(arg ,','); spacing[0] = atoi(spacings.at(0).c_str()); spacing[1] = atoi(spacings.at(1).c_str()); spacing[2] = atoi(spacings.at(2).c_str()); useSpacing = true; } } std::string refImageFile = ""; if (parsedArgs.count("reference")) { refImageFile = us::any_cast(parsedArgs["reference"]); } if (refImageFile =="" && useSpacing == false) { MITK_ERROR << "No information how to resample is supplied. Use eigther --spacing or --reference !"; return EXIT_FAILURE; } mitk::Image::Pointer refImage; if (!useSpacing) refImage = mitk::IOUtil::LoadImage(refImageFile); mitk::Image::Pointer inputDWI = mitk::IOUtil::LoadImage(inputFile); if ( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(inputDWI.GetPointer())) { mitk::Image::Pointer outputImage; if (useSpacing) outputImage = ResampleDWIbySpacing(inputDWI, spacing); else { MITK_WARN << "Not supported yet, to resample a DWI please set a new spacing."; return EXIT_FAILURE; } mitk::IOUtil::Save(outputImage, outputFile.c_str()); return EXIT_SUCCESS; } mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputFile); mitk::Image::Pointer resultImage; if (useSpacing) resultImage = ResampleBySpacing(inputImage,spacing,useLinearInterpol,useNN); else resultImage = TransformToReference(refImage,inputImage,useLinearInterpol,useNN); mitk::IOUtil::SaveImage(resultImage, outputFile); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/Registration.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/Registration.cpp index 717ec9e125..5133594799 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/Registration.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/Registration.cpp @@ -1,471 +1,471 @@ /*=================================================================== 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. ===================================================================*/ // CTK #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include // ITK #include #include #include "itkLinearInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkIdentityTransform.h" #include "itkResampleImageFilter.h" #include "itkNrrdImageIO.h" using namespace std; typedef std::vector FileListType; typedef itk::Image InputImageType; static mitk::Image::Pointer ExtractFirstTS(mitk::Image* image, std::string fileType) { if (fileType == ".dwi") return image; mitk::ImageTimeSelector::Pointer selector = mitk::ImageTimeSelector::New(); selector->SetInput(image); selector->SetTimeNr(0); selector->UpdateLargestPossibleRegion(); mitk::Image::Pointer img =selector->GetOutput()->Clone(); return img; } static std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } static std::vector split(const std::string &s, char delim) { std::vector < std::string > elems; return split(s, delim, elems); } /// Create list of all files in provided folder ending with same postfix static FileListType CreateFileList(std::string folder , std::string postfix) { itk::Directory::Pointer dir = itk::Directory::New(); FileListType fileList; if( dir->Load(folder.c_str() ) ) { int n = dir->GetNumberOfFiles(); for(int r=0;rGetFile( r ); if (filename == "." || filename == "..") continue; filename = folder + filename; if (!itksys::SystemTools::FileExists( filename.c_str())) continue; if (filename.length() <= postfix.length() ) continue; if (filename.substr(filename.length() -postfix.length() ) == postfix) fileList.push_back(filename); } } return fileList; } static std::string GetSavePath(std::string outputFolder, std::string fileName) { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileName); std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(fileName); std::string savePathAndFileName = outputFolder +fileStem + fileType; return savePathAndFileName; } static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing, bool useLinInt = false) { InputImageType::Pointer itkImage = InputImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. InputImageType::SpacingType inputSpacing = itkImage->GetSpacing(); InputImageType::SpacingType outputSpacing; const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); InputImageType::SizeType outputSize; typedef InputImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::LinearInterpolateImageFunction< InputImageType > LinearInterpolatorType; LinearInterpolatorType::Pointer lin_interpolator = LinearInterpolatorType::New(); typedef itk::Function::WelchWindowFunction<4> WelchWindowFunction; typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4,WelchWindowFunction> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); if (useLinInt) _pResizeFilter->SetInterpolator(lin_interpolator); else _pResizeFilter->SetInterpolator(sinc_interpolator); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } /// Build a derived file name from moving images e.g. xxx_T2.nrrd becomes xxx_GTV.nrrd static FileListType CreateDerivedFileList(std::string baseFN, std::string baseSuffix, std::vector derivedPatterns) { FileListType files; for (unsigned int i=0; i < derivedPatterns.size(); i++) { std::string derResourceSuffix = derivedPatterns.at(i); std::string derivedResourceFilename = baseFN.substr(0,baseFN.length() -baseSuffix.length()) + derResourceSuffix; MITK_INFO <<" Looking for file: " << derivedResourceFilename; if (!itksys::SystemTools::FileExists(derivedResourceFilename.c_str())) { MITK_INFO << "CreateDerivedFileList: File does not exit. Skipping entry."; continue; } files.push_back(derivedResourceFilename); } return files; } /// Save images according to file type static void SaveImage(std::string fileName, mitk::Image* image, std::string fileType ) { MITK_INFO << "----Save to " << fileName; mitk::IOUtil::Save(image, fileName); } /// Copy derived resources from first time step. Append _reg tag, but leave data untouched. static void CopyResources(FileListType fileList, std::string outputPath) { for (unsigned int j=0; j < fileList.size(); j++) { std::string derivedResourceFilename = fileList.at(j); std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(derivedResourceFilename); std::string savePathAndFileName = outputPath +fileStem + "." + fileType; MITK_INFO << "Copy resource " << savePathAndFileName; mitk::Image::Pointer resImage = ExtractFirstTS(mitk::IOUtil::LoadImage(derivedResourceFilename), fileType); mitk::IOUtil::SaveImage(resImage, savePathAndFileName); } } int main( int argc, char* argv[] ) { mitkCommandLineParser parser; parser.setArgumentPrefix("--","-"); parser.setTitle("Folder Registration"); parser.setCategory("Preprocessing Tools"); parser.setDescription("For detail description see http://docs.mitk.org/nightly/DiffusionMiniApps.html"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help", "Show this help text"); //parser.addArgument("usemask", "u", QVariant::Bool, "Use segmentations (derived resources) to exclude areas from registration metrics"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input:", "Input folder",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputDirectory, "Output:", "Output folder (ending with /)",us::Any(),false); parser.addArgument("fixed", "f", mitkCommandLineParser::String, "Fixed images:", "Suffix for fixed image (if none is supplied first file matching moving pattern is chosen)",us::Any(),true); parser.addArgument("moving", "m", mitkCommandLineParser::String, "Moving images:", "Suffix for moving images",us::Any(),false); parser.addArgument("derived", "d", mitkCommandLineParser::String, "Derived resources:", "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true); parser.addArgument("silent", "s", mitkCommandLineParser::Bool, "Silent:", "No xml progress output."); parser.addArgument("resample", "r", mitkCommandLineParser::String, "Resample (x,y,z)mm:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); parser.addArgument("binary", "b", mitkCommandLineParser::Bool, "Binary:", "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any()); parser.addArgument("correct-origin", "c", mitkCommandLineParser::Bool, "Origin correction:", "Correct for large origin displacement. Use switch when you reveive: Joint PDF summed to zero ",us::Any()); parser.addArgument("sinc-int", "s", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); map parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool silent = false; bool isBinary = false; bool alignOrigin = false; bool useLinearInterpol = true; { if (parsedArgs.size() == 0) { return EXIT_FAILURE; } if (parsedArgs.count("sinc-int")) useLinearInterpol = false; if (parsedArgs.count("silent")) silent = true; if (parsedArgs.count("binary")) isBinary = true; if (parsedArgs.count("correct-origin")) alignOrigin = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string refPattern = ""; bool useFirstMoving = false; std::string movingImgPattern = us::any_cast(parsedArgs["moving"]); if (parsedArgs.count("fixed")) { refPattern = us::any_cast(parsedArgs["fixed"]); } else { useFirstMoving = true; refPattern = movingImgPattern; } std::string outputPath = us::any_cast(parsedArgs["output"]); std::string inputPath = us::any_cast(parsedArgs["input"]); //QString resampleReference = parsedArgs["resample"].toString(); //bool maskTumor = parsedArgs["usemask"].toBool(); // if derived sources pattern is provided, populate QStringList with possible filename postfixes std::vector derPatterns; if (parsedArgs.count("derived") || parsedArgs.count("d") ) { std::string arg = us::any_cast(parsedArgs["derived"]); derPatterns = split(arg ,','); } std::vector spacings; float spacing[3]; bool doResampling = false; if (parsedArgs.count("resample") || parsedArgs.count("d") ) { std::string arg = us::any_cast(parsedArgs["resample"]); spacings = split(arg ,','); spacing[0] = atoi(spacings.at(0).c_str()); spacing[1] = atoi(spacings.at(1).c_str()); spacing[2] = atoi(spacings.at(2).c_str()); doResampling = true; } MITK_INFO << "Input Folder : " << inputPath; MITK_INFO << "Looking for reference image ..."; FileListType referenceFileList = CreateFileList(inputPath,refPattern); if ((!useFirstMoving && referenceFileList.size() != 1) || (useFirstMoving && referenceFileList.size() == 0)) { MITK_ERROR << "None or more than one possible reference images (" << refPattern <<") found. Exiting." << referenceFileList.size(); MITK_INFO << "Choose a fixed arguement that is unique in the given folder!"; return EXIT_FAILURE; } std::string referenceFileName = referenceFileList.at(0); MITK_INFO << "Loading Reference (fixed) image: " << referenceFileName; std::string fileType = itksys::SystemTools::GetFilenameExtension(referenceFileName); mitk::Image::Pointer refImage = ExtractFirstTS(mitk::IOUtil::LoadImage(referenceFileName), fileType); mitk::Image::Pointer resampleReference = nullptr; if (doResampling) { refImage = ResampleBySpacing(refImage,spacing); resampleReference = refImage; } if (refImage.IsNull()) MITK_ERROR << "Loaded fixed image is nullptr"; // Copy reference image to destination std::string savePathAndFileName = GetSavePath(outputPath, referenceFileName); mitk::IOUtil::SaveImage(refImage, savePathAndFileName); // Copy all derived resources also to output folder, adding _reg suffix referenceFileList = CreateDerivedFileList(referenceFileName, movingImgPattern,derPatterns); CopyResources(referenceFileList, outputPath); std::string derivedResourceFilename; mitk::Image::Pointer referenceMask = nullptr; // union of all segmentations if (!silent) { // XML Output to report progress std::cout << ""; std::cout << "Batched Registration"; std::cout << "Starting registration ... "; std::cout << ""; } // Now iterate over all files and register them to the reference image, // also register derived resources based on file patterns // ------------------------------------------------------------------------------ // Create File list FileListType movingImagesList = CreateFileList(inputPath, movingImgPattern); // TODO Reactivate Resampling Feature // mitk::Image::Pointer resampleImage = nullptr; // if (QFileInfo(resampleReference).isFile()) // { // resampleImage = mitk::IOUtil::LoadImage(resampleReference.toStdString()); // } for (unsigned int i =0; i < movingImagesList.size(); i++) { std::string fileMorphName = movingImagesList.at(i); if (fileMorphName == referenceFileName) { // do not process reference image again continue; } MITK_INFO << "Processing image " << fileMorphName; // 1 Register morphological file to reference image if (!itksys::SystemTools::FileExists(fileMorphName.c_str())) { MITK_WARN << "File does not exit. Skipping entry."; continue; } // Origin of images is cancelled // TODO make this optional!! double transf[6]; double offset[3]; { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileMorphName); mitk::Image::Pointer movingImage = ExtractFirstTS(mitk::IOUtil::LoadImage(fileMorphName), fileType); if (movingImage.IsNull()) MITK_ERROR << "Loaded moving image is nullptr"; // Store transformation, apply it to morph file MITK_INFO << "----------Registering moving image to reference----------"; mitk::RegistrationWrapper::GetTransformation(refImage, movingImage, transf, offset, alignOrigin, referenceMask); mitk::RegistrationWrapper::ApplyTransformationToImage(movingImage, transf,offset, resampleReference); // , resampleImage savePathAndFileName = GetSavePath(outputPath, fileMorphName); if (fileType == ".dwi") fileType = "dwi"; if (movingImage->GetData() == nullptr) MITK_INFO <<"POST DATA is null"; mitk::IOUtil::Save(movingImage, savePathAndFileName); } if (!silent) { std::cout << "."; } // Now parse all derived resource and apply the above calculated transformation to them // ------------------------------------------------------------------------------------ FileListType fList = CreateDerivedFileList(fileMorphName, movingImgPattern,derPatterns); if (fList.size() > 0) MITK_INFO << "----------DERIVED RESOURCES ---------"; for (unsigned int j=0; j < fList.size(); j++) { derivedResourceFilename = fList.at(j); MITK_INFO << "----Processing derived resorce " << derivedResourceFilename << " ..."; std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); mitk::Image::Pointer derivedMovingResource = ExtractFirstTS(mitk::IOUtil::LoadImage(derivedResourceFilename), fileType); // Apply transformation to derived resource, treat derived resource as binary mitk::RegistrationWrapper::ApplyTransformationToImage(derivedMovingResource, transf,offset, resampleReference,isBinary); savePathAndFileName = GetSavePath(outputPath, derivedResourceFilename); mitk::IOUtil::SaveImage(derivedMovingResource, savePathAndFileName); } } if (!silent) std::cout << ""; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/ResampleGradients.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ResampleGradients.cpp similarity index 96% rename from Modules/DiffusionImaging/cmdapps/ResampleGradients.cpp rename to Modules/DiffusionImaging/DiffusionCore/cmdapps/ResampleGradients.cpp index d3f7795e70..53944ba464 100644 --- a/Modules/DiffusionImaging/cmdapps/ResampleGradients.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ResampleGradients.cpp @@ -1,255 +1,252 @@ /*=================================================================== 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 #include #include #include #include #include #include -#include #include "mitkCommandLineParser.h" #include #include #include -#include -#include #include #include #include // itk includes #include // mitk includes #include #include "itkDWIVoxelFunctor.h" #include typedef short DiffusionPixelType; typedef itk::VectorImage< short, 3 > ItkDwiType; // itk includes #include "itkTimeProbe.h" #include "itkB0ImageExtractionImageFilter.h" #include "itkB0ImageExtractionToSeparateImageFilter.h" #include "itkBrainMaskExtractionImageFilter.h" #include "itkCastImageFilter.h" #include "itkVectorContainer.h" #include #include #include #include #include #include // Multishell includes #include // Multishell Functors #include #include #include #include // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" //#include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include #include #include #include #include //#include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkPreferenceListReaderOptionsFunctor.h" mitk::Image::Pointer DoReduceGradientDirections(mitk::Image::Pointer image, double BValue, unsigned int numOfGradientsToKeep) { bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( !isDiffusionImage ) { std::cout << "Image is not a Diffusion Weighted Image" << std::endl; //return; } typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; typedef mitk::BValueMapProperty::BValueMap BValueMap; BValueMap shellSlectionMap; BValueMap originalShellMap = static_cast (image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() ) ->GetBValueMap(); std::vector newNumGradientDirections; //Keeps 1 b0 gradient double B0Value = 0; shellSlectionMap[B0Value] = originalShellMap[B0Value]; unsigned int num = 1; newNumGradientDirections.push_back(num); //BValue = 1000; shellSlectionMap[BValue] = originalShellMap[BValue]; //numOfGradientsToKeep = 32; newNumGradientDirections.push_back(numOfGradientsToKeep); if (newNumGradientDirections.empty()) { std::cout << "newNumGradientDirections is empty" << std::endl; //return; } itk::DwiGradientLengthCorrectionFilter::GradientDirectionContainerType::Pointer gradientContainer = static_cast ( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() ) ->GetGradientDirectionsContainer(); ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); mitk::CastToItkImage(image, itkVectorImagePointer); std::cout << "1" << std::endl; FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkVectorImagePointer ); filter->SetOriginalGradientDirections(gradientContainer); filter->SetNumGradientDirections(newNumGradientDirections); filter->SetOriginalBValueMap(originalShellMap); filter->SetShellSelectionBValueMap(shellSlectionMap); filter->Update(); std::cout << "2" << std::endl; if( filter->GetOutput() == nullptr) { std::cout << "filter get output is nullptr" << std::endl; } mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( filter->GetOutput() ); newImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetGradientDirections() ) ); newImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast (image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() ) ->GetMeasurementFrame() ) ); newImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast (image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() ) ->GetValue() ) ); mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); //needed? return newImage; } /*! \brief Resample gradients of input DWI image. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Resample Gradients"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Preprocessing Tools"); parser.setDescription("Resample gradients of input DWI image. You can select one b-value shell and the number of gradients within this shell you want to have. It will also keep one b0 image."); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input fiber bundle", us::Any(), false); - parser.addArgument("output", "o", mitkCommandLineParser::String, "Output:", "output fiber bundle", us::Any(), false); + parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false); + parser.addArgument("output", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false); parser.addArgument("bValue", "b", mitkCommandLineParser::Float, "b-value:", "float", 1000, false); parser.addArgument("nrOfGradients", "n", mitkCommandLineParser::Int, "Nr of gradients:", "integer", 32, false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["input"]); std::string outFileName = us::any_cast(parsedArgs["output"]); double bValue = us::any_cast(parsedArgs["bValue"]); unsigned int nrOfGradients = us::any_cast(parsedArgs["nrOfGradients"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({ "Diffusion Weighted Images" }, {}); mitk::Image::Pointer mitkImage = dynamic_cast(mitk::IOUtil::LoadImage(inFileName, &functor).GetPointer()); mitk::Image::Pointer newImage = DoReduceGradientDirections(mitkImage, bValue, nrOfGradients); //mitk::IOUtil::SaveImage(newImage, outFileName); //save as dwi image mitk::IOUtil::Save(newImage, "application/vnd.mitk.nii.gz", outFileName); //save as nifti image } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.cpp index b8ac12b6c0..8279690c85 100644 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.cpp @@ -1,271 +1,276 @@ /*=================================================================== 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 "mitkTrackingHandlerPeaks.h" namespace mitk { TrackingHandlerPeaks::TrackingHandlerPeaks() : m_PeakThreshold(0.1) , m_ApplyDirectionMatrix(false) { } TrackingHandlerPeaks::~TrackingHandlerPeaks() { } void TrackingHandlerPeaks::InitForTracking() { MITK_INFO << "Initializing peak tracker."; itk::Vector spacing4 = m_PeakImage->GetSpacing(); itk::Point origin4 = m_PeakImage->GetOrigin(); itk::Matrix direction4 = m_PeakImage->GetDirection(); itk::ImageRegion<4> imageRegion4 = m_PeakImage->GetLargestPossibleRegion(); spacing3[0] = spacing4[0]; spacing3[1] = spacing4[1]; spacing3[2] = spacing4[2]; origin3[0] = origin4[0]; origin3[1] = origin4[1]; origin3[2] = origin4[2]; for (int r=0; r<3; r++) for (int c=0; c<3; c++) { direction3[r][c] = direction4[r][c]; m_FloatImageRotation[r][c] = direction4[r][c]; } imageRegion3.SetSize(0, imageRegion4.GetSize()[0]); imageRegion3.SetSize(1, imageRegion4.GetSize()[1]); imageRegion3.SetSize(2, imageRegion4.GetSize()[2]); m_DummyImage = ItkUcharImgType::New(); m_DummyImage->SetSpacing( spacing3 ); m_DummyImage->SetOrigin( origin3 ); m_DummyImage->SetDirection( direction3 ); m_DummyImage->SetRegions( imageRegion3 ); m_DummyImage->Allocate(); m_DummyImage->FillBuffer(0.0); m_NumDirs = imageRegion4.GetSize(3)/3; } vnl_vector_fixed TrackingHandlerPeaks::GetMatchingDirection(itk::Index<3> idx3, vnl_vector_fixed& oldDir) { vnl_vector_fixed out_dir; out_dir.fill(0); float angle = 0; float mag = oldDir.magnitude(); if (magmitk::eps) { oldDir[0] = out_dir[0]; oldDir[1] = out_dir[1]; oldDir[2] = out_dir[2]; + found = true; break; } } - // if you didn't find a non-zero random direction, take first non-zero direction you find - for (int i=0; imitk::eps) + // if you didn't find a non-zero random direction, take first non-zero direction you find + for (int i=0; imitk::eps) + { + oldDir[0] = out_dir[0]; + oldDir[1] = out_dir[1]; + oldDir[2] = out_dir[2]; + break; + } } } } else { for (int i=0; i dir = GetDirection(idx3, i); mag = dir.magnitude(); if (mag>mitk::eps) dir.normalize(); float a = dot_product(dir, oldDir); if (fabs(a)>angle) { angle = fabs(a); if (a<0) out_dir = -dir; else out_dir = dir; out_dir *= mag; out_dir *= angle; // shrink contribution of direction if is less parallel to previous direction } } } return out_dir; } vnl_vector_fixed TrackingHandlerPeaks::GetDirection(itk::Index<3> idx3, int dirIdx) { vnl_vector_fixed dir; dir.fill(0.0); if ( !m_DummyImage->GetLargestPossibleRegion().IsInside(idx3) ) return dir; PeakImgType::IndexType idx4; idx4.SetElement(0,idx3[0]); idx4.SetElement(1,idx3[1]); idx4.SetElement(2,idx3[2]); for (int k=0; k<3; k++) { idx4.SetElement(3, dirIdx*3 + k); dir[k] = m_PeakImage->GetPixel(idx4); } if (m_FlipX) dir[0] *= -1; if (m_FlipY) dir[1] *= -1; if (m_FlipZ) dir[2] *= -1; if (m_ApplyDirectionMatrix) dir = m_FloatImageRotation*dir; return dir; } vnl_vector_fixed TrackingHandlerPeaks::GetDirection(itk::Point itkP, bool interpolate, vnl_vector_fixed oldDir){ // transform physical point to index coordinates itk::Index<3> idx3; itk::ContinuousIndex< float, 3> cIdx; m_DummyImage->TransformPhysicalPointToIndex(itkP, idx3); m_DummyImage->TransformPhysicalPointToContinuousIndex(itkP, cIdx); vnl_vector_fixed dir; dir.fill(0.0); if ( !m_DummyImage->GetLargestPossibleRegion().IsInside(idx3) ) return dir; if (interpolate) { float frac_x = cIdx[0] - idx3[0]; float frac_y = cIdx[1] - idx3[1]; float frac_z = cIdx[2] - idx3[2]; if (frac_x<0) { idx3[0] -= 1; frac_x += 1; } if (frac_y<0) { idx3[1] -= 1; frac_y += 1; } if (frac_z<0) { idx3[2] -= 1; frac_z += 1; } frac_x = 1-frac_x; frac_y = 1-frac_y; frac_z = 1-frac_z; // int coordinates inside image? if (idx3[0] >= 0 && idx3[0] < static_cast(m_DummyImage->GetLargestPossibleRegion().GetSize(0) - 1) && idx3[1] >= 0 && idx3[1] < static_cast(m_DummyImage->GetLargestPossibleRegion().GetSize(1) - 1) && idx3[2] >= 0 && idx3[2] < static_cast(m_DummyImage->GetLargestPossibleRegion().GetSize(2) - 1)) { // trilinear interpolation vnl_vector_fixed interpWeights; interpWeights[0] = ( frac_x)*( frac_y)*( frac_z); interpWeights[1] = (1-frac_x)*( frac_y)*( frac_z); interpWeights[2] = ( frac_x)*(1-frac_y)*( frac_z); interpWeights[3] = ( frac_x)*( frac_y)*(1-frac_z); interpWeights[4] = (1-frac_x)*(1-frac_y)*( frac_z); interpWeights[5] = ( frac_x)*(1-frac_y)*(1-frac_z); interpWeights[6] = (1-frac_x)*( frac_y)*(1-frac_z); interpWeights[7] = (1-frac_x)*(1-frac_y)*(1-frac_z); dir = GetMatchingDirection(idx3, oldDir) * interpWeights[0]; itk::Index<3> tmpIdx = idx3; tmpIdx[0]++; dir += GetMatchingDirection(tmpIdx, oldDir) * interpWeights[1]; tmpIdx = idx3; tmpIdx[1]++; dir += GetMatchingDirection(tmpIdx, oldDir) * interpWeights[2]; tmpIdx = idx3; tmpIdx[2]++; dir += GetMatchingDirection(tmpIdx, oldDir) * interpWeights[3]; tmpIdx = idx3; tmpIdx[0]++; tmpIdx[1]++; dir += GetMatchingDirection(tmpIdx, oldDir) * interpWeights[4]; tmpIdx = idx3; tmpIdx[1]++; tmpIdx[2]++; dir += GetMatchingDirection(tmpIdx, oldDir) * interpWeights[5]; tmpIdx = idx3; tmpIdx[2]++; tmpIdx[0]++; dir += GetMatchingDirection(tmpIdx, oldDir) * interpWeights[6]; tmpIdx = idx3; tmpIdx[0]++; tmpIdx[1]++; tmpIdx[2]++; dir += GetMatchingDirection(tmpIdx, oldDir) * interpWeights[7]; } } else - dir = GetMatchingDirection(idx3, oldDir); + dir = GetMatchingDirection(idx3, oldDir); return dir; } vnl_vector_fixed TrackingHandlerPeaks::ProposeDirection(const itk::Point& pos, std::deque >& olddirs, itk::Index<3>& oldIndex) { - // CHECK: wann wird wo normalisiert + // CHECK: wann wird wo normalisiert vnl_vector_fixed output_direction; output_direction.fill(0); itk::Index<3> index; m_DummyImage->TransformPhysicalPointToIndex(pos, index); vnl_vector_fixed oldDir = olddirs.back(); float old_mag = oldDir.magnitude(); if (!m_Interpolate && oldIndex==index) return oldDir; output_direction = GetDirection(pos, m_Interpolate, oldDir); float mag = output_direction.magnitude(); if (mag>=m_PeakThreshold) { output_direction.normalize(); float a = 1; if (old_mag>0.5) - a = dot_product(output_direction, oldDir); + a = dot_product(output_direction, oldDir); if (a>m_AngularThreshold) output_direction *= mag; else output_direction.fill(0); } else output_direction.fill(0); return output_direction; } } diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkStreamlineTrackingFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkStreamlineTrackingFilter.cpp index 3cc79f4a67..ac52889626 100644 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkStreamlineTrackingFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkStreamlineTrackingFilter.cpp @@ -1,993 +1,992 @@ /*=================================================================== 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 "itkStreamlineTrackingFilter.h" #include #include #include #include #include "itkPointShell.h" #define _USE_MATH_DEFINES #include namespace itk { StreamlineTrackingFilter ::StreamlineTrackingFilter() : m_PauseTracking(false) , m_AbortTracking(false) , m_FiberPolyData(nullptr) , m_Points(nullptr) , m_Cells(nullptr) , m_AngularThreshold(-1) , m_StepSize(0) , m_MaxLength(10000) , m_MinTractLength(20.0) , m_MaxTractLength(400.0) , m_SeedsPerVoxel(1) , m_RandomSampling(false) , m_SamplingDistance(-1) , m_DeflectionMod(1.0) , m_OnlyForwardSamples(true) , m_UseStopVotes(true) , m_NumberOfSamples(30) , m_NumPreviousDirections(1) , m_StoppingRegions(nullptr) , m_SeedImage(nullptr) , m_MaskImage(nullptr) , m_AposterioriCurvCheck(false) , m_AvoidStop(true) , m_DemoMode(false) , m_SeedOnlyGm(false) , m_ControlGmEndings(false) , m_WmLabel(3) // mrtrix 5ttseg labels , m_GmLabel(1) // mrtrix 5ttseg labels , m_StepSizeVox(-1) , m_SamplingDistanceVox(-1) , m_AngularThresholdDeg(-1) , m_MaxNumTracts(-1) , m_Random(true) , m_Verbose(true) , m_UseOutputProbabilityMap(false) { this->SetNumberOfRequiredInputs(0); } void StreamlineTrackingFilter::BeforeTracking() { m_TrackingHandler->InitForTracking(); m_FiberPolyData = PolyDataType::New(); m_Points = vtkSmartPointer< vtkPoints >::New(); m_Cells = vtkSmartPointer< vtkCellArray >::New(); itk::Vector< double, 3 > imageSpacing = m_TrackingHandler->GetSpacing(); float minSpacing; if(imageSpacing[0]SetAngularThreshold(m_AngularThreshold); if (m_SamplingDistanceVoxGetNumberOfThreads(); i++) { PolyDataType poly = PolyDataType::New(); m_PolyDataContainer.push_back(poly); } if (m_UseOutputProbabilityMap) { m_OutputProbabilityMap = ItkDoubleImgType::New(); m_OutputProbabilityMap->SetSpacing(imageSpacing); m_OutputProbabilityMap->SetOrigin(m_TrackingHandler->GetOrigin()); m_OutputProbabilityMap->SetDirection(m_TrackingHandler->GetDirection()); m_OutputProbabilityMap->SetRegions(m_TrackingHandler->GetLargestPossibleRegion()); m_OutputProbabilityMap->Allocate(); m_OutputProbabilityMap->FillBuffer(0); } if (m_StoppingRegions.IsNull()) { m_StoppingRegions = ItkUcharImgType::New(); m_StoppingRegions->SetSpacing( imageSpacing ); m_StoppingRegions->SetOrigin( m_TrackingHandler->GetOrigin() ); m_StoppingRegions->SetDirection( m_TrackingHandler->GetDirection() ); m_StoppingRegions->SetRegions( m_TrackingHandler->GetLargestPossibleRegion() ); m_StoppingRegions->Allocate(); m_StoppingRegions->FillBuffer(0); } else std::cout << "StreamlineTracking - Using stopping region image" << std::endl; if (m_SeedImage.IsNull()) { m_SeedImage = ItkUcharImgType::New(); m_SeedImage->SetSpacing( imageSpacing ); m_SeedImage->SetOrigin( m_TrackingHandler->GetOrigin() ); m_SeedImage->SetDirection( m_TrackingHandler->GetDirection() ); m_SeedImage->SetRegions( m_TrackingHandler->GetLargestPossibleRegion() ); m_SeedImage->Allocate(); m_SeedImage->FillBuffer(1); } else std::cout << "StreamlineTracking - Using seed image" << std::endl; if (m_MaskImage.IsNull()) { // initialize mask image m_MaskImage = ItkUcharImgType::New(); m_MaskImage->SetSpacing( imageSpacing ); m_MaskImage->SetOrigin( m_TrackingHandler->GetOrigin() ); m_MaskImage->SetDirection( m_TrackingHandler->GetDirection() ); m_MaskImage->SetRegions( m_TrackingHandler->GetLargestPossibleRegion() ); m_MaskImage->Allocate(); m_MaskImage->FillBuffer(1); } else std::cout << "StreamlineTracking - Using mask image" << std::endl; if (m_SeedPoints.empty()) GetSeedPointsFromSeedImage(); else m_SeedOnlyGm = false; if (m_TissueImage.IsNull()) { if (m_SeedOnlyGm) { MITK_WARN << "StreamlineTracking - Cannot seed in gray matter. No tissue type image set."; m_SeedOnlyGm = false; } if (m_ControlGmEndings) { MITK_WARN << "StreamlineTracking - Cannot control gray matter endings. No tissue type image set."; m_ControlGmEndings = false; } } else { if (m_ControlGmEndings) m_SeedOnlyGm = true; if (m_ControlGmEndings || m_SeedOnlyGm) std::cout << "StreamlineTracking - Using tissue image" << std::endl; else MITK_WARN << "StreamlineTracking - Tissue image set but no gray matter seeding or fiber endpoint-control enabled" << std::endl; } m_BuildFibersReady = 0; m_BuildFibersFinished = false; m_Tractogram.clear(); m_SamplingPointset = mitk::PointSet::New(); m_AlternativePointset = mitk::PointSet::New(); m_StopVotePointset = mitk::PointSet::New(); m_StartTime = std::chrono::system_clock::now(); if (m_SeedOnlyGm && m_ControlGmEndings) InitGrayMatterEndings(); if (m_DemoMode) omp_set_num_threads(1); - omp_set_num_threads(1); if (m_TrackingHandler->GetMode()==mitk::TrackingDataHandler::MODE::DETERMINISTIC) std::cout << "StreamlineTracking - Mode: deterministic" << std::endl; else if(m_TrackingHandler->GetMode()==mitk::TrackingDataHandler::MODE::PROBABILISTIC) std::cout << "StreamlineTracking - Mode: probabilistic" << std::endl; else std::cout << "StreamlineTracking - Mode: ???" << std::endl; std::cout << "StreamlineTracking - Angular threshold: " << m_AngularThreshold << " (" << 180*std::acos( m_AngularThreshold )/M_PI << "°)" << std::endl; std::cout << "StreamlineTracking - Stepsize: " << m_StepSize << "mm (" << m_StepSize/minSpacing << "*vox)" << std::endl; std::cout << "StreamlineTracking - Seeds per voxel: " << m_SeedsPerVoxel << std::endl; std::cout << "StreamlineTracking - Max. tract length: " << m_MaxTractLength << "mm" << std::endl; std::cout << "StreamlineTracking - Min. tract length: " << m_MinTractLength << "mm" << std::endl; std::cout << "StreamlineTracking - Max. num. tracts: " << m_MaxNumTracts << std::endl; std::cout << "StreamlineTracking - Num. neighborhood samples: " << m_NumberOfSamples << std::endl; std::cout << "StreamlineTracking - Max. sampling distance: " << m_SamplingDistance << "mm (" << m_SamplingDistance/minSpacing << "*vox)" << std::endl; std::cout << "StreamlineTracking - Deflection modifier: " << m_DeflectionMod << std::endl; std::cout << "StreamlineTracking - Use stop votes: " << m_UseStopVotes << std::endl; std::cout << "StreamlineTracking - Only frontal samples: " << m_OnlyForwardSamples << std::endl; if (m_DemoMode) { std::cout << "StreamlineTracking - Running in demo mode"; std::cout << "StreamlineTracking - Starting streamline tracking using 1 thread" << std::endl; } else std::cout << "StreamlineTracking - Starting streamline tracking using " << omp_get_max_threads() << " threads" << std::endl; } void StreamlineTrackingFilter::InitGrayMatterEndings() { m_TrackingHandler->SetAngularThreshold(0); m_GmStubs.clear(); if (m_TissueImage.IsNotNull()) { std::cout << "StreamlineTracking - initializing GM endings" << std::endl; ImageRegionConstIterator< ItkUcharImgType > it(m_TissueImage, m_TissueImage->GetLargestPossibleRegion() ); it.GoToBegin(); vnl_vector_fixed d1; d1.fill(0.0); std::deque< vnl_vector_fixed > olddirs; while (olddirs.size() start; m_TissueImage->TransformIndexToPhysicalPoint(s_idx, start); itk::Point wm_p; float max = -1; FiberType fib; for (int x : {-1,0,1}) for (int y : {-1,0,1}) for (int z : {-1,0,1}) { if (x==y && y==z) continue; ItkUcharImgType::IndexType e_idx; e_idx[0] = s_idx[0] + x; e_idx[1] = s_idx[1] + y; e_idx[2] = s_idx[2] + z; if ( !m_TissueImage->GetLargestPossibleRegion().IsInside(e_idx) || m_TissueImage->GetPixel(e_idx)!=m_WmLabel ) continue; itk::ContinuousIndex end; m_TissueImage->TransformIndexToPhysicalPoint(e_idx, end); d1 = m_TrackingHandler->ProposeDirection(end, olddirs, s_idx); if (d1.magnitude()<0.0001) continue; d1.normalize(); vnl_vector_fixed< float, 3 > d2; d2[0] = end[0] - start[0]; d2[1] = end[1] - start[1]; d2[2] = end[2] - start[2]; d2.normalize(); float a = fabs(dot_product(d1,d2)); if (a>max) { max = a; wm_p = end; } } if (max>=0) { fib.push_back(start); fib.push_back(wm_p); m_GmStubs.push_back(fib); } } ++it; } } m_TrackingHandler->SetAngularThreshold(m_AngularThreshold); } void StreamlineTrackingFilter::CalculateNewPosition(itk::Point& pos, vnl_vector_fixed& dir) { pos[0] += dir[0]*m_StepSize; pos[1] += dir[1]*m_StepSize; pos[2] += dir[2]*m_StepSize; } bool StreamlineTrackingFilter ::IsValidPosition(const itk::Point &pos) { ItkUcharImgType::IndexType idx; m_MaskImage->TransformPhysicalPointToIndex(pos, idx); if (!m_MaskImage->GetLargestPossibleRegion().IsInside(idx) || m_MaskImage->GetPixel(idx)==0) return false; return true; } bool StreamlineTrackingFilter ::IsInGm(const itk::Point &pos) { if (m_TissueImage.IsNull()) return true; ItkUcharImgType::IndexType idx; m_TissueImage->TransformPhysicalPointToIndex(pos, idx); if (m_TissueImage->GetLargestPossibleRegion().IsInside(idx) && m_TissueImage->GetPixel(idx) == m_GmLabel) return true; return false; } float StreamlineTrackingFilter::GetRandDouble(float min, float max) { return (float)(rand()%((int)(10000*(max-min))) + 10000*min)/10000; } std::vector< vnl_vector_fixed > StreamlineTrackingFilter::CreateDirections(int NPoints) { std::vector< vnl_vector_fixed > pointshell; if (NPoints<2) return pointshell; std::vector< float > theta; theta.resize(NPoints); std::vector< float > phi; phi.resize(NPoints); float C = sqrt(4*M_PI); phi[0] = 0.0; phi[NPoints-1] = 0.0; for(int i=0; i0 && i d; d[0] = cos(theta[i]) * cos(phi[i]); d[1] = cos(theta[i]) * sin(phi[i]); d[2] = sin(theta[i]); pointshell.push_back(d); } return pointshell; } vnl_vector_fixed StreamlineTrackingFilter::GetNewDirection(itk::Point &pos, std::deque >& olddirs, itk::Index<3> &oldIndex) { if (m_DemoMode) { m_SamplingPointset->Clear(); m_AlternativePointset->Clear(); m_StopVotePointset->Clear(); } vnl_vector_fixed direction; direction.fill(0); ItkUcharImgType::IndexType idx; m_MaskImage->TransformPhysicalPointToIndex(pos, idx); if (IsValidPosition(pos)) { if (m_StoppingRegions->GetPixel(idx)>0) return direction; direction = m_TrackingHandler->ProposeDirection(pos, olddirs, oldIndex); // get direction proposal at current streamline position } else return direction; vnl_vector_fixed olddir = olddirs.back(); std::vector< vnl_vector_fixed > probeVecs = CreateDirections(m_NumberOfSamples); itk::Point sample_pos; int alternatives = 1; int stop_votes = 0; int possible_stop_votes = 0; for (int i=0; i d; bool is_stop_voter = false; if (m_RandomSampling) { d[0] = GetRandDouble(); d[1] = GetRandDouble(); d[2] = GetRandDouble(); d.normalize(); d *= GetRandDouble(0,m_SamplingDistance); } else { d = probeVecs.at(i); float dot = dot_product(d, olddir); if (m_UseStopVotes && dot>0.7) { is_stop_voter = true; possible_stop_votes++; } else if (m_OnlyForwardSamples && dot<0) continue; d *= m_SamplingDistance; } sample_pos[0] = pos[0] + d[0]; sample_pos[1] = pos[1] + d[1]; sample_pos[2] = pos[2] + d[2]; vnl_vector_fixed tempDir; tempDir.fill(0.0); if (IsValidPosition(sample_pos)) tempDir = m_TrackingHandler->ProposeDirection(sample_pos, olddirs, oldIndex); // sample neighborhood if (tempDir.magnitude()>mitk::eps) { direction += tempDir; if(m_DemoMode) m_SamplingPointset->InsertPoint(i, sample_pos); } else if (m_AvoidStop && olddir.magnitude()>0.5) // out of white matter { if (is_stop_voter) stop_votes++; if (m_DemoMode) m_StopVotePointset->InsertPoint(i, sample_pos); float dot = dot_product(d, olddir); if (dot >= 0.0) // in front of plane defined by pos and olddir d = -d + 2*dot*olddir; // reflect else d = -d; // invert // look a bit further into the other direction sample_pos[0] = pos[0] + d[0]; sample_pos[1] = pos[1] + d[1]; sample_pos[2] = pos[2] + d[2]; alternatives++; vnl_vector_fixed tempDir; tempDir.fill(0.0); if (IsValidPosition(sample_pos)) tempDir = m_TrackingHandler->ProposeDirection(sample_pos, olddirs, oldIndex); // sample neighborhood if (tempDir.magnitude()>mitk::eps) // are we back in the white matter? { direction += d * m_DeflectionMod; // go into the direction of the white matter direction += tempDir; // go into the direction of the white matter direction at this location if(m_DemoMode) m_AlternativePointset->InsertPoint(alternatives, sample_pos); } else { if (m_DemoMode) m_StopVotePointset->InsertPoint(i, sample_pos); } } else { if (m_DemoMode) m_StopVotePointset->InsertPoint(i, sample_pos); if (is_stop_voter) stop_votes++; } } if (direction.magnitude()>0.001 && (possible_stop_votes==0 || (float)stop_votes/possible_stop_votes<0.5) ) direction.normalize(); else direction.fill(0); return direction; } float StreamlineTrackingFilter::FollowStreamline(itk::Point pos, vnl_vector_fixed dir, FiberType* fib, float tractLength, bool front) { vnl_vector_fixed zero_dir; zero_dir.fill(0.0); std::deque< vnl_vector_fixed > last_dirs; for (unsigned int i=0; iTransformPhysicalPointToIndex(pos, oldIndex); // get new position CalculateNewPosition(pos, dir); // is new position inside of image and mask if (m_AbortTracking) // if not end streamline { return tractLength; } else // if yes, add new point to streamline { tractLength += m_StepSize; if (front) fib->push_front(pos); else fib->push_back(pos); if (m_AposterioriCurvCheck) { int curv = CheckCurvature(fib, front); if (curv>0) { tractLength -= m_StepSize*curv; while (curv>0) { if (front) fib->pop_front(); else fib->pop_back(); curv--; } return tractLength; } } if (tractLength>m_MaxTractLength) return tractLength; } #pragma omp critical if (m_DemoMode && !m_UseOutputProbabilityMap) // CHECK: warum sind die samplingpunkte der streamline in der visualisierung immer einen schritt voras? { m_BuildFibersReady++; m_Tractogram.push_back(*fib); BuildFibers(true); m_Stop = true; while (m_Stop){ } } dir.normalize(); last_dirs.push_back(dir); if (last_dirs.size()>m_NumPreviousDirections) last_dirs.pop_front(); dir = GetNewDirection(pos, last_dirs, oldIndex); while (m_PauseTracking){} if (dir.magnitude()<0.0001) return tractLength; } return tractLength; } int StreamlineTrackingFilter::CheckCurvature(FiberType* fib, bool front) { float m_Distance = 5; if (fib->size()<3) return 0; float dist = 0; std::vector< vnl_vector_fixed< float, 3 > > vectors; vnl_vector_fixed< float, 3 > meanV; meanV.fill(0); float dev = 0; if (front) { int c=0; while(distsize()-1) { itk::Point p1 = fib->at(c); itk::Point p2 = fib->at(c+1); vnl_vector_fixed< float, 3 > v; v[0] = p2[0]-p1[0]; v[1] = p2[1]-p1[1]; v[2] = p2[2]-p1[2]; dist += v.magnitude(); v.normalize(); vectors.push_back(v); if (c==0) meanV += v; c++; } } else { int c=fib->size()-1; while(dist0) { itk::Point p1 = fib->at(c); itk::Point p2 = fib->at(c-1); vnl_vector_fixed< float, 3 > v; v[0] = p2[0]-p1[0]; v[1] = p2[1]-p1[1]; v[2] = p2[2]-p1[2]; dist += v.magnitude(); v.normalize(); vectors.push_back(v); if (c==fib->size()-1) meanV += v; c--; } } meanV.normalize(); for (int c=0; c1.0) angle = 1.0; if (angle<-1.0) angle = -1.0; dev += acos(angle)*180/M_PI; } if (vectors.size()>0) dev /= vectors.size(); if (dev<30) return 0; else return vectors.size(); } void StreamlineTrackingFilter::GetSeedPointsFromSeedImage() { MITK_INFO << "Calculating seed points."; m_SeedPoints.clear(); if (!m_ControlGmEndings) { typedef ImageRegionConstIterator< ItkUcharImgType > MaskIteratorType; MaskIteratorType sit(m_SeedImage, m_SeedImage->GetLargestPossibleRegion()); sit.GoToBegin(); while (!sit.IsAtEnd()) { if (sit.Value()>0) { ItkUcharImgType::IndexType index = sit.GetIndex(); itk::ContinuousIndex start; start[0] = index[0]; start[1] = index[1]; start[2] = index[2]; itk::Point worldPos; m_SeedImage->TransformContinuousIndexToPhysicalPoint(start, worldPos); if (IsValidPosition(worldPos) && (!m_SeedOnlyGm || IsInGm(worldPos))) { m_SeedPoints.push_back(worldPos); for (int s = 1; s < m_SeedsPerVoxel; s++) { start[0] = index[0] + GetRandDouble(-0.5, 0.5); start[1] = index[1] + GetRandDouble(-0.5, 0.5); start[2] = index[2] + GetRandDouble(-0.5, 0.5); itk::Point worldPos; m_SeedImage->TransformContinuousIndexToPhysicalPoint(start, worldPos); m_SeedPoints.push_back(worldPos); } } } ++sit; } } else { for (auto s : m_GmStubs) m_SeedPoints.push_back(s[1]); } } void StreamlineTrackingFilter::GenerateData() { this->BeforeTracking(); if (m_Random) { std::srand(std::time(0)); std::random_shuffle(m_SeedPoints.begin(), m_SeedPoints.end()); } bool stop = false; unsigned int current_tracts = 0; int num_seeds = m_SeedPoints.size(); itk::Index<3> zeroIndex; zeroIndex.Fill(0); int progress = 0; int i = 0; int print_interval = num_seeds/100; if (print_interval<100) m_Verbose=false; #pragma omp parallel while (i=num_seeds || stop) continue; else if (m_Verbose && i%print_interval==0) #pragma omp critical { progress += print_interval; std::cout << " \r"; if (m_MaxNumTracts>0) std::cout << "Tried: " << progress << "/" << num_seeds << " | Accepted: " << current_tracts << "/" << m_MaxNumTracts << '\r'; else std::cout << "Tried: " << progress << "/" << num_seeds << " | Accepted: " << current_tracts << '\r'; cout.flush(); } const itk::Point worldPos = m_SeedPoints.at(temp_i); FiberType fib; float tractLength = 0; unsigned int counter = 0; // get starting direction vnl_vector_fixed dir; dir.fill(0.0); std::deque< vnl_vector_fixed > olddirs; while (olddirs.size() gm_start_dir; if (m_ControlGmEndings) { gm_start_dir[0] = m_GmStubs[temp_i][1][0] - m_GmStubs[temp_i][0][0]; gm_start_dir[1] = m_GmStubs[temp_i][1][1] - m_GmStubs[temp_i][0][1]; gm_start_dir[2] = m_GmStubs[temp_i][1][2] - m_GmStubs[temp_i][0][2]; gm_start_dir.normalize(); olddirs.pop_back(); olddirs.push_back(gm_start_dir); } if (IsValidPosition(worldPos)) dir = m_TrackingHandler->ProposeDirection(worldPos, olddirs, zeroIndex); if (dir.magnitude()>0.0001) { if (m_ControlGmEndings) { float a = dot_product(gm_start_dir, dir); if (a<0) dir = -dir; } // forward tracking tractLength = FollowStreamline(worldPos, dir, &fib, 0, false); fib.push_front(worldPos); if (m_ControlGmEndings) { fib.push_front(m_GmStubs[temp_i][0]); CheckFiberForGmEnding(&fib); } else { // backward tracking (only if we don't explicitely start in the GM) tractLength = FollowStreamline(worldPos, -dir, &fib, tractLength, true); if (m_ControlGmEndings) { CheckFiberForGmEnding(&fib); std::reverse(fib.begin(),fib.end()); CheckFiberForGmEnding(&fib); } } counter = fib.size(); #pragma omp critical if (tractLength>=m_MinTractLength && counter>=2) { if (!stop) { if (!m_UseOutputProbabilityMap) m_Tractogram.push_back(fib); else FiberToProbmap(&fib); current_tracts++; } if (m_MaxNumTracts > 0 && current_tracts>=static_cast(m_MaxNumTracts)) { if (!stop) { std::cout << " \r"; MITK_INFO << "Reconstructed maximum number of tracts (" << current_tracts << "). Stopping tractography."; } stop = true; } } } } this->AfterTracking(); } void StreamlineTrackingFilter::CheckFiberForGmEnding(FiberType* fib) { if (m_TissueImage.IsNull()) return; // first check if the current fibe rendpoint is located inside of the white matter // if not, remove last fiber point and repeat bool in_wm = false; while (!in_wm && fib->size()>2) { ItkUcharImgType::IndexType idx; m_TissueImage->TransformPhysicalPointToIndex(fib->back(), idx); if (m_TissueImage->GetPixel(idx)==m_WmLabel) in_wm = true; else fib->pop_back(); } if (fib->size()<3 || !in_wm) { fib->clear(); return; } // get fiber direction at end point vnl_vector_fixed< float, 3 > d1; d1[0] = fib->back()[0] - fib->at(fib->size()-2)[0]; d1[1] = fib->back()[1] - fib->at(fib->size()-2)[1]; d1[2] = fib->back()[2] - fib->at(fib->size()-2)[2]; d1.normalize(); // find closest gray matter voxel ItkUcharImgType::IndexType s_idx; m_TissueImage->TransformPhysicalPointToIndex(fib->back(), s_idx); itk::Point gm_endp; float max = -1; for (int x : {-1,0,1}) for (int y : {-1,0,1}) for (int z : {-1,0,1}) { if (x==y && y==z) continue; ItkUcharImgType::IndexType e_idx; e_idx[0] = s_idx[0] + x; e_idx[1] = s_idx[1] + y; e_idx[2] = s_idx[2] + z; if ( !m_TissueImage->GetLargestPossibleRegion().IsInside(e_idx) || m_TissueImage->GetPixel(e_idx)!=m_GmLabel ) continue; itk::ContinuousIndex end; m_TissueImage->TransformIndexToPhysicalPoint(e_idx, end); vnl_vector_fixed< float, 3 > d2; d2[0] = end[0] - fib->back()[0]; d2[1] = end[1] - fib->back()[1]; d2[2] = end[2] - fib->back()[2]; d2.normalize(); float a = dot_product(d1,d2); if (a>max) { max = a; gm_endp = end; } } if (max>=0) fib->push_back(gm_endp); else // no gray matter enpoint found -> delete fiber fib->clear(); } void StreamlineTrackingFilter::FiberToProbmap(FiberType* fib) { ItkDoubleImgType::IndexType last_idx; last_idx.Fill(0); for (auto p : *fib) { ItkDoubleImgType::IndexType idx; m_OutputProbabilityMap->TransformPhysicalPointToIndex(p, idx); if (idx != last_idx) { if (m_OutputProbabilityMap->GetLargestPossibleRegion().IsInside(idx)) m_OutputProbabilityMap->SetPixel(idx, m_OutputProbabilityMap->GetPixel(idx)+1); last_idx = idx; } } } void StreamlineTrackingFilter::BuildFibers(bool check) { if (m_BuildFibersReady::New(); vtkSmartPointer vNewLines = vtkSmartPointer::New(); vtkSmartPointer vNewPoints = vtkSmartPointer::New(); for (int i=0; i container = vtkSmartPointer::New(); FiberType fib = m_Tractogram.at(i); for (FiberType::iterator it = fib.begin(); it!=fib.end(); ++it) { vtkIdType id = vNewPoints->InsertNextPoint((*it).GetDataPointer()); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); } if (check) for (int i=0; iSetPoints(vNewPoints); m_FiberPolyData->SetLines(vNewLines); m_BuildFibersFinished = true; } void StreamlineTrackingFilter::AfterTracking() { if (m_Verbose) std::cout << " \r"; if (!m_UseOutputProbabilityMap) { MITK_INFO << "Reconstructed " << m_Tractogram.size() << " fibers."; MITK_INFO << "Generating polydata "; BuildFibers(false); } MITK_INFO << "done"; m_EndTime = std::chrono::system_clock::now(); std::chrono::hours hh = std::chrono::duration_cast(m_EndTime - m_StartTime); std::chrono::minutes mm = std::chrono::duration_cast(m_EndTime - m_StartTime); std::chrono::seconds ss = std::chrono::duration_cast(m_EndTime - m_StartTime); mm %= 60; ss %= 60; MITK_INFO << "Tracking took " << hh.count() << "h, " << mm.count() << "m and " << ss.count() << "s"; m_SeedPoints.clear(); } } diff --git a/Modules/DiffusionImaging/FiberTracking/CMakeLists.txt b/Modules/DiffusionImaging/FiberTracking/CMakeLists.txt index 311976e551..20b4331ec9 100644 --- a/Modules/DiffusionImaging/FiberTracking/CMakeLists.txt +++ b/Modules/DiffusionImaging/FiberTracking/CMakeLists.txt @@ -1,50 +1,55 @@ set(_module_deps MitkDiffusionCore MitkGraphAlgorithms MitkCLVigraRandomForest) mitk_check_module_dependencies( MODULES ${_module_deps} MISSING_DEPENDENCIES_VAR _missing_deps ) if(NOT _missing_deps) set(lut_url http://mitk.org/download/data/FibertrackingLUT.tar.gz) set(lut_tarball ${CMAKE_CURRENT_BINARY_DIR}/FibertrackingLUT.tar.gz) #message("Downloading FiberTracking LUT ${lut_url}...") file(DOWNLOAD ${lut_url} ${lut_tarball} EXPECTED_MD5 38ecb6d4a826c9ebb0f4965eb9aeee44 TIMEOUT 60 STATUS status SHOW_PROGRESS ) list(GET status 0 status_code) list(GET status 1 status_msg) if(NOT status_code EQUAL 0) message(SEND_ERROR "${status_msg} (error code ${status_code})") endif() file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Resources) #message("Unpacking FiberTracking LUT tarball...") execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf ../FibertrackingLUT.tar.gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Resources RESULT_VARIABLE result ERROR_VARIABLE err_msg) if(result) message(SEND_ERROR "Unpacking FibertrackingLUT.tar.gz failed: ${err_msg}") endif() endif() MITK_CREATE_MODULE( SUBPROJECTS MITK-DTI INCLUDE_DIRS Fiberfox Fiberfox/SignalModels Fiberfox/Sequences Algorithms Algorithms/TrackingHandlers Algorithms/GibbsTracking Algorithms/StochasticTracking IODataStructures IODataStructures/FiberBundle IODataStructures/PlanarFigureComposite Rendering ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${_module_deps} PACKAGE_DEPENDS PUBLIC ITK|ITKFFT ITK|ITKDiffusionTensorImage Vigra HDF5 #WARNINGS_AS_ERRORS ) if(MODULE_IS_ENABLED) + add_subdirectory(cmdapps/Fiberfox) + add_subdirectory(cmdapps/FiberProcessing) + add_subdirectory(cmdapps/Tractography) + add_subdirectory(cmdapps/TractographyEvaluation) + add_subdirectory(cmdapps/Misc) add_subdirectory(Testing) endif() diff --git a/Modules/DiffusionImaging/cmdapps/CMakeLists.txt b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/CMakeLists.txt similarity index 53% rename from Modules/DiffusionImaging/cmdapps/CMakeLists.txt rename to Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/CMakeLists.txt index 8e2417bd78..cf4af5cca2 100755 --- a/Modules/DiffusionImaging/cmdapps/CMakeLists.txt +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/CMakeLists.txt @@ -1,60 +1,43 @@ -if(BUILD_DiffusionCmdApps OR MITK_BUILD_ALL_APPS) +option(BUILD_DiffusionFiberProcessingCmdApps "Build commandline tools for diffusion fiber processing" OFF) + +if(BUILD_DiffusionFiberProcessingCmdApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # list of diffusion cmdapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" - set( diffusioncmdapps - NetworkCreation^^MitkFiberTracking_MitkConnectomics - NetworkStatistics^^MitkConnectomics - - Fiberfox^^MitkFiberTracking - MultishellMethods^^MitkFiberTracking - PeaksAngularError^^MitkFiberTracking - PeakExtraction^^MitkFiberTracking + set( diffusionFiberProcessingcmdapps + TractDensity^^MitkFiberTracking + Sift2WeightCopy^^MitkFiberTracking FiberExtraction^^MitkFiberTracking FiberProcessing^^MitkFiberTracking FiberDirectionExtraction^^MitkFiberTracking - # LocalDirectionalFiberPlausibility^^MitkFiberTracking # HAS TO USE NEW PEAK IMAGE FORMAT - StreamlineTracking^^MitkFiberTracking - GibbsTracking^^MitkFiberTracking - TractometerMetrics^^MitkFiberTracking - FileFormatConverter^^MitkFiberTracking - RfTraining^^MitkFiberTracking - TractDensity^^MitkFiberTracking - Sift2WeightCopy^^MitkFiberTracking - ResampleGradients^^MitkFiberTracking + FiberJoin^^MitkFiberTracking ) - foreach(diffusioncmdapp ${diffusioncmdapps}) + foreach(diffusionFiberProcessingcmdapp ${diffusiontractographycmdapps}) # extract cmd app name and dependencies - string(REPLACE "^^" "\\;" cmdapp_info ${diffusioncmdapp}) + string(REPLACE "^^" "\\;" cmdapp_info ${diffusionFiberProcessingcmdapp}) set(cmdapp_info_list ${cmdapp_info}) list(GET cmdapp_info_list 0 appname) list(GET cmdapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitkFunctionCreateCommandLineApp( NAME ${appname} DEPENDS MitkCore MitkDiffusionCore ${dependencies_list} PACKAGE_DEPENDS ITK ) endforeach() - # This cmd app does not depend on mitkDiffusionImaging at all - mitkFunctionCreateCommandLineApp( - NAME Dicom2Nrrd - DEPENDS MitkCore ${dependencies_list} - ) - if(EXECUTABLE_IS_ENABLED) MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET}) endif() endif() diff --git a/Modules/DiffusionImaging/cmdapps/FiberDirectionExtraction.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberDirectionExtraction.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/FiberDirectionExtraction.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberDirectionExtraction.cpp index 83cb43f0ef..d419846ca1 100755 --- a/Modules/DiffusionImaging/cmdapps/FiberDirectionExtraction.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberDirectionExtraction.cpp @@ -1,180 +1,180 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include using namespace std; /*! \brief Extract principal fiber directions from a tractogram */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiber Direction Extraction"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Extract principal fiber directions from a tractogram"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib/.trk)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image"); parser.addArgument("athresh", "a", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); parser.addArgument("peakthresh", "t", mitkCommandLineParser::Float, "Peak size threshold:", "peak size threshold relative to largest peak in voxel", 0.2, true); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results"); parser.addArgument("numdirs", "d", mitkCommandLineParser::Int, "Max. num. directions:", "maximum number of fibers per voxel", 3, true); parser.addArgument("normalize", "n", mitkCommandLineParser::Bool, "Normalize:", "normalize vectors"); parser.addArgument("file_ending", "f", mitkCommandLineParser::String, "Image type:", ".nrrd, .nii, .nii.gz"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string fibFile = us::any_cast(parsedArgs["input"]); string maskImage(""); if (parsedArgs.count("mask")) maskImage = us::any_cast(parsedArgs["mask"]); float peakThreshold = 0.2; if (parsedArgs.count("peakthresh")) peakThreshold = us::any_cast(parsedArgs["peakthresh"]); float angularThreshold = 25; if (parsedArgs.count("athresh")) angularThreshold = us::any_cast(parsedArgs["athresh"]); string outRoot = us::any_cast(parsedArgs["out"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); int maxNumDirs = 3; if (parsedArgs.count("numdirs")) maxNumDirs = us::any_cast(parsedArgs["numdirs"]); bool normalize = false; if (parsedArgs.count("normalize")) normalize = us::any_cast(parsedArgs["normalize"]); std::string file_ending = ".nrrd"; if (parsedArgs.count("file_ending")) file_ending = us::any_cast(parsedArgs["file_ending"]); try { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; // load fiber bundle mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::LoadDataNode(fibFile)->GetData()); // load/create mask image ItkUcharImgType::Pointer itkMaskImage = nullptr; if (maskImage.compare("")!=0) { std::cout << "Using mask image"; itkMaskImage = ItkUcharImgType::New(); mitk::Image::Pointer mitkMaskImage = dynamic_cast(mitk::IOUtil::LoadDataNode(maskImage)->GetData()); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); } // extract directions from fiber bundle itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetMaskImage(itkMaskImage); fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180)); fOdfFilter->SetNormalizeVectors(normalize); fOdfFilter->SetUseWorkingCopy(false); fOdfFilter->SetSizeThreshold(peakThreshold); fOdfFilter->SetMaxNumDirections(maxNumDirs); fOdfFilter->Update(); { itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer itkImg = fOdfFilter->GetDirectionImage(); typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter::ItkDirectionImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_DIRECTIONS"); outfilename.append(file_ending); writer->SetFileName(outfilename.c_str()); writer->SetInput(itkImg); writer->Update(); } if (verbose) { // write vector field mitk::FiberBundle::Pointer directions = fOdfFilter->GetOutputFiberBundle(); string outfilename = outRoot; outfilename.append("_VECTOR_FIELD.fib"); mitk::IOUtil::SaveBaseData(directions.GetPointer(), outfilename ); // write num direction image { ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage(); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_NUM_DIRECTIONS"); outfilename.append(file_ending); writer->SetFileName(outfilename.c_str()); writer->SetInput(numDirImage); writer->Update(); } } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/FiberExtraction.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtraction.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/FiberExtraction.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtraction.cpp index d87bd97921..5f55a18858 100755 --- a/Modules/DiffusionImaging/cmdapps/FiberExtraction.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtraction.cpp @@ -1,163 +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 #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include using namespace std; /*! \brief Extract fibers from a tractogram using planar figure ROIs */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiber Extraction"); parser.setCategory("Fiber Tracking and Processing Methods"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setDescription("Extract fibers from a tractogram using planar figure ROIs"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); parser.addArgument("planfirgure1", "pf1", mitkCommandLineParser::String, "Figure 1:", "first ROI", us::Any(), false); parser.addArgument("planfirgure2", "pf2", mitkCommandLineParser::String, "Figure 2:", "second ROI", us::Any()); parser.addArgument("operation", "op", mitkCommandLineParser::String, "Operation:", "logical operation (AND, OR, NOT)", us::Any()); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFib = us::any_cast(parsedArgs["input"]); string outFib = us::any_cast(parsedArgs["out"]); string pf1_path = us::any_cast(parsedArgs["planfirgure1"]); string operation(""); string pf2_path(""); if (parsedArgs.count("operation")) { operation = us::any_cast(parsedArgs["operation"]); if (parsedArgs.count("planfirgure2") && (operation=="AND" || operation=="OR")) pf2_path = us::any_cast(parsedArgs["planfirgure2"]); } try { typedef itk::Image ItkUcharImgType; // load fiber bundle mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::LoadDataNode(inFib)->GetData()); mitk::FiberBundle::Pointer result; mitk::StandaloneDataStorage::Pointer storage = mitk::StandaloneDataStorage::New(); mitk::DataNode::Pointer input1 = mitk::IOUtil::LoadDataNode(pf1_path); if (input1.IsNotNull()) { mitk::PlanarFigureComposite::Pointer pfc = mitk::PlanarFigureComposite::New(); mitk::DataNode::Pointer pfcNode = mitk::DataNode::New(); pfcNode->SetData(pfc); mitk::DataStorage::SetOfObjects::Pointer set1 = mitk::DataStorage::SetOfObjects::New(); set1->push_back(pfcNode); storage->Add(pfcNode); mitk::DataNode::Pointer input2; if (!pf2_path.empty()) { input2 = mitk::IOUtil::LoadDataNode(pf2_path); } if (operation.empty()) { result = inputTractogram->ExtractFiberSubset(input1, nullptr); } else if (operation=="NOT") { pfc->setOperationType(mitk::PlanarFigureComposite::NOT); storage->Add(input1, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else if (operation=="AND" && input2.IsNotNull()) { pfc->setOperationType(mitk::PlanarFigureComposite::AND); storage->Add(input1, set1); storage->Add(input2, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else if (operation=="OR" && input2.IsNotNull()) { pfc->setOperationType(mitk::PlanarFigureComposite::OR); storage->Add(input1, set1); storage->Add(input2, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else { std::cout << "Could not process input:"; std::cout << pf1_path; std::cout << pf2_path; std::cout << operation; } } else { ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New(); mitk::Image::Pointer mitkMaskImage = dynamic_cast(mitk::IOUtil::LoadDataNode(pf1_path)->GetData()); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); if (operation=="NOT") result = inputTractogram->ExtractFiberSubset(itkMaskImage, true, true); else result = inputTractogram->ExtractFiberSubset(itkMaskImage, true, false); } if (result.IsNotNull()) mitk::IOUtil::SaveBaseData(result, outFib); else std::cout << "No valid fiber bundle extracted."; } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/FiberJoin.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberJoin.cpp similarity index 98% rename from Modules/DiffusionImaging/cmdapps/FiberJoin.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberJoin.cpp index beeef7ec51..8240fe7cff 100755 --- a/Modules/DiffusionImaging/cmdapps/FiberJoin.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberJoin.cpp @@ -1,92 +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 "MiniAppManager.h" #include #include #include "ctkCommandLineParser.h" #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include /*! \brief Join multiple tractograms */ int FiberJoin(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiber Join"); parser.setCategory("Fiber Tracking and Processing Methods"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setDescription("Join multiple tractograms"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::StringList, "Input:", "input tractograms (.fib, vtk file format)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType inFibs = us::any_cast(parsedArgs["input"]); string outFib = us::any_cast(parsedArgs["out"]); if (inFibs.size()<=1) { std::cout << "More than one input tractogram required!"; return EXIT_FAILURE; } try { mitk::FiberBundle::Pointer result = dynamic_cast(mitk::IOUtil::LoadDataNode(inFibs.at(0))->GetData()); for (int i=1; i(mitk::IOUtil::LoadDataNode(inFibs.at(i))->GetData()); result = result->AddBundle(inputTractogram); } catch(...){ std::cout << "could not load: " << inFibs.at(i); } } mitk::IOUtil::SaveBaseData(result, outFib); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } RegisterDiffusionMiniApp(FiberJoin); diff --git a/Modules/DiffusionImaging/cmdapps/FiberProcessing.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberProcessing.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/FiberProcessing.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberProcessing.cpp index c3cb37b2c6..63d1bfb3e0 100644 --- a/Modules/DiffusionImaging/cmdapps/FiberProcessing.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberProcessing.cpp @@ -1,220 +1,220 @@ /*=================================================================== 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 #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include mitk::FiberBundle::Pointer LoadFib(std::string filename) { std::vector fibInfile = mitk::IOUtil::Load(filename); if( fibInfile.empty() ) std::cout << "File " << filename << " could not be read!"; mitk::BaseData::Pointer baseData = fibInfile.at(0); return dynamic_cast(baseData.GetPointer()); } /*! \brief Modify input tractogram: fiber resampling, compression, pruning and transformation. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiber Processing"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Modify input tractogram: fiber resampling, compression, pruning and transformation."); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input fiber bundle (.fib, .trk, .tck)", us::Any(), false); parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib, .trk)", us::Any(), false); parser.addArgument("smooth", "s", mitkCommandLineParser::Float, "Spline resampling:", "Resample fiber using splines with the given point distance (in mm)"); parser.addArgument("compress", "c", mitkCommandLineParser::Float, "Compress:", "Compress fiber using the given error threshold (in mm)"); parser.addArgument("minLength", "l", mitkCommandLineParser::Float, "Minimum length:", "Minimum fiber length (in mm)"); parser.addArgument("maxLength", "m", mitkCommandLineParser::Float, "Maximum length:", "Maximum fiber length (in mm)"); parser.addArgument("maxAngle", "a", mitkCommandLineParser::Float, "Maximum angle:", "Maximum angular STDEV over 1cm (in degree)"); parser.addArgument("remove", "rm", mitkCommandLineParser::Bool, "Remove fibers exceeding curvature threshold:", "if false, only the high curvature parts are removed"); parser.addArgument("mirror", "p", mitkCommandLineParser::Int, "Invert coordinates:", "Invert fiber coordinates XYZ (e.g. 010 to invert y-coordinate of each fiber point)"); parser.addArgument("rotate-x", "rx", mitkCommandLineParser::Float, "Rotate x-axis:", "Rotate around x-axis (in deg)"); parser.addArgument("rotate-y", "ry", mitkCommandLineParser::Float, "Rotate y-axis:", "Rotate around y-axis (in deg)"); parser.addArgument("rotate-z", "rz", mitkCommandLineParser::Float, "Rotate z-axis:", "Rotate around z-axis (in deg)"); parser.addArgument("scale-x", "sx", mitkCommandLineParser::Float, "Scale x-axis:", "Scale in direction of x-axis"); parser.addArgument("scale-y", "sy", mitkCommandLineParser::Float, "Scale y-axis:", "Scale in direction of y-axis"); parser.addArgument("scale-z", "sz", mitkCommandLineParser::Float, "Scale z-axis", "Scale in direction of z-axis"); parser.addArgument("translate-x", "tx", mitkCommandLineParser::Float, "Translate x-axis:", "Translate in direction of x-axis (in mm)"); parser.addArgument("translate-y", "ty", mitkCommandLineParser::Float, "Translate y-axis:", "Translate in direction of y-axis (in mm)"); parser.addArgument("translate-z", "tz", mitkCommandLineParser::Float, "Translate z-axis:", "Translate in direction of z-axis (in mm)"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; bool remove = false; if (parsedArgs.count("remove")) remove = us::any_cast(parsedArgs["remove"]); float smoothDist = -1; if (parsedArgs.count("smooth")) smoothDist = us::any_cast(parsedArgs["smooth"]); float compress = -1; if (parsedArgs.count("compress")) compress = us::any_cast(parsedArgs["compress"]); float minFiberLength = -1; if (parsedArgs.count("minLength")) minFiberLength = us::any_cast(parsedArgs["minLength"]); float maxFiberLength = -1; if (parsedArgs.count("maxLength")) maxFiberLength = us::any_cast(parsedArgs["maxLength"]); float maxAngularDev = -1; if (parsedArgs.count("maxAngle")) maxAngularDev = us::any_cast(parsedArgs["maxAngle"]); int axis = 0; if (parsedArgs.count("mirror")) axis = us::any_cast(parsedArgs["mirror"]); float rotateX = 0; if (parsedArgs.count("rotate-x")) rotateX = us::any_cast(parsedArgs["rotate-x"]); float rotateY = 0; if (parsedArgs.count("rotate-y")) rotateY = us::any_cast(parsedArgs["rotate-y"]); float rotateZ = 0; if (parsedArgs.count("rotate-z")) rotateZ = us::any_cast(parsedArgs["rotate-z"]); float scaleX = 0; if (parsedArgs.count("scale-x")) scaleX = us::any_cast(parsedArgs["scale-x"]); float scaleY = 0; if (parsedArgs.count("scale-y")) scaleY = us::any_cast(parsedArgs["scale-y"]); float scaleZ = 0; if (parsedArgs.count("scale-z")) scaleZ = us::any_cast(parsedArgs["scale-z"]); float translateX = 0; if (parsedArgs.count("translate-x")) translateX = us::any_cast(parsedArgs["translate-x"]); float translateY = 0; if (parsedArgs.count("translate-y")) translateY = us::any_cast(parsedArgs["translate-y"]); float translateZ = 0; if (parsedArgs.count("translate-z")) translateZ = us::any_cast(parsedArgs["translate-z"]); string inFileName = us::any_cast(parsedArgs["input"]); string outFileName = us::any_cast(parsedArgs["outFile"]); try { mitk::FiberBundle::Pointer fib = LoadFib(inFileName); if (maxAngularDev>0) { auto filter = itk::FiberCurvatureFilter::New(); filter->SetInputFiberBundle(fib); filter->SetAngularDeviation(maxAngularDev); filter->SetDistance(10); filter->SetRemoveFibers(remove); filter->Update(); fib = filter->GetOutputFiberBundle(); } if (minFiberLength>0) fib->RemoveShortFibers(minFiberLength); if (maxFiberLength>0) fib->RemoveLongFibers(maxFiberLength); if (smoothDist>0) fib->ResampleSpline(smoothDist); if (compress>0) fib->Compress(compress); if (axis/100==1) fib->MirrorFibers(0); if ((axis%100)/10==1) fib->MirrorFibers(1); if (axis%10==1) fib->MirrorFibers(2); if (rotateX > 0 || rotateY > 0 || rotateZ > 0){ std::cout << "Rotate " << rotateX << " " << rotateY << " " << rotateZ; fib->RotateAroundAxis(rotateX, rotateY, rotateZ); } if (translateX > 0 || translateY > 0 || translateZ > 0){ fib->TranslateFibers(translateX, translateY, translateZ); } if (scaleX > 0 || scaleY > 0 || scaleZ > 0) fib->ScaleFibers(scaleX, scaleY, scaleZ); mitk::IOUtil::SaveBaseData(fib.GetPointer(), outFileName ); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/Sift2WeightCopy.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/Sift2WeightCopy.cpp similarity index 97% rename from Modules/DiffusionImaging/cmdapps/Sift2WeightCopy.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/Sift2WeightCopy.cpp index caeda36330..266285afae 100644 --- a/Modules/DiffusionImaging/cmdapps/Sift2WeightCopy.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/Sift2WeightCopy.cpp @@ -1,108 +1,108 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include mitk::FiberBundle::Pointer LoadFib(std::string filename) { std::vector fibInfile = mitk::IOUtil::Load(filename); if( fibInfile.empty() ) std::cout << "File " << filename << " could not be read!"; mitk::BaseData::Pointer baseData = fibInfile.at(0); return dynamic_cast(baseData.GetPointer()); } /*! \brief Import Sift2 Fiber Weights txt file. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Sift2 Fiber Weight Import"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Import sift2 fiber weights."); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input fiber bundle", us::Any(), false); parser.addArgument("weights", "w", mitkCommandLineParser::String, "Weights:", "input weights file (.txt)", us::Any(), false); - parser.addArgument("output", "o", mitkCommandLineParser::String, "Output:", "output fiber bundle", us::Any(), false); + parser.addArgument("output", "o", mitkCommandLineParser::String, "Output:", "output fiber bundle (.fib)", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["input"]); std::string weightsFileName = us::any_cast(parsedArgs["weights"]); std::string outFileName = us::any_cast(parsedArgs["output"]); try { mitk::FiberBundle::Pointer fib = LoadFib(inFileName); std::ifstream fin; fin.open(weightsFileName); if (!fin.good()) return 1; // exit if file not found std::vector weights; for (float d; fin >> d; ) { weights.push_back(d); } for(int i = 0; i != weights.size(); i++) { fib->SetFiberWeight(i, weights[i]); } mitk::IOUtil::SaveBaseData(fib.GetPointer(), outFileName ); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/TractDensity.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensity.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/TractDensity.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensity.cpp index 87e4eced52..87da49883c 100644 --- a/Modules/DiffusionImaging/cmdapps/TractDensity.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensity.cpp @@ -1,201 +1,201 @@ /*=================================================================== 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 #include #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include mitk::FiberBundle::Pointer LoadFib(std::string filename) { std::vector fibInfile = mitk::IOUtil::Load(filename); if( fibInfile.empty() ) std::cout << "File " << filename << " could not be read!"; mitk::BaseData::Pointer baseData = fibInfile.at(0); return dynamic_cast(baseData.GetPointer()); } /*! \brief Modify input tractogram: fiber resampling, compression, pruning and transformation. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Tract Density"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Generate tract density image, fiber envelope or fiber endpoints image."); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input fiber bundle (.fib)", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false); parser.addArgument("binary", "", mitkCommandLineParser::Bool, "Binary output:", "calculate binary tract envelope", us::Any()); parser.addArgument("endpoints", "", mitkCommandLineParser::Bool, "Output endpoints image:", "calculate image of fiber endpoints instead of mask", us::Any()); parser.addArgument("reference_image", "", mitkCommandLineParser::String, "Reference image:", "output image will have geometry of this reference image", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; bool binary = false; if (parsedArgs.count("binary")) binary = us::any_cast(parsedArgs["binary"]); bool endpoints = false; if (parsedArgs.count("endpoints")) endpoints = us::any_cast(parsedArgs["endpoints"]); std::string reference_image = ""; if (parsedArgs.count("reference_image")) reference_image = us::any_cast(parsedArgs["reference_image"]); std::string inFileName = us::any_cast(parsedArgs["input"]); std::string outFileName = us::any_cast(parsedArgs["output"]); try { mitk::FiberBundle::Pointer fib = LoadFib(inFileName); mitk::Image::Pointer ref_img; MITK_INFO << reference_image; if (!reference_image.empty()) ref_img = dynamic_cast(mitk::IOUtil::LoadImage(reference_image).GetPointer()); if (endpoints) { typedef unsigned int OutPixType; typedef itk::Image OutImageType; typedef itk::TractsToFiberEndingsImageFilter< OutImageType > ImageGeneratorType; ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); generator->SetFiberBundle(fib); if (ref_img.IsNotNull()) { OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(ref_img, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::IOUtil::SaveBaseData(img, outFileName ); } else if (binary) { typedef unsigned char OutPixType; typedef itk::Image OutImageType; itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); generator->SetFiberBundle(fib); generator->SetBinaryOutput(binary); generator->SetOutputAbsoluteValues(false); generator->SetWorkOnFiberCopy(false); if (ref_img.IsNotNull()) { OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(ref_img, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::IOUtil::SaveBaseData(img, outFileName ); } else { typedef float OutPixType; typedef itk::Image OutImageType; itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); generator->SetFiberBundle(fib); generator->SetBinaryOutput(binary); generator->SetOutputAbsoluteValues(false); generator->SetWorkOnFiberCopy(false); if (ref_img.IsNotNull()) { OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(ref_img, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::IOUtil::SaveBaseData(img, outFileName ); } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt b/Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/CMakeLists.txt old mode 100644 new mode 100755 similarity index 57% copy from Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt copy to Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/CMakeLists.txt index 1fe5feb7d2..e5aa410786 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/CMakeLists.txt @@ -1,44 +1,38 @@ -option(BUILD_DiffusionCoreCmdApps "Build commandline tools for diffusion" OFF) +option(BUILD_DiffusionFiberfoxCmdApps "Build commandline tools for diffusion data simulation (Fiberfox)" OFF) -if(BUILD_DiffusionCoreCmdApps OR MITK_BUILD_ALL_APPS) +if(BUILD_DiffusionFiberfoxCmdApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # list of diffusion cmdapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" - set( diffusioncorecmdapps - DwiDenoising^^ - ImageResampler^^ - ExportShImage^^ - CopyGeometry^^ - DiffusionIndices^^ - QballReconstruction^^ - Registration^^ - TensorReconstruction^^ - TensorDerivedMapsExtraction^^ - DiffusionDICOMLoader^^ - DiffusionKurtosisFit^^ + set( diffusionFiberfoxcmdapps + Fiberfox^^MitkFiberTracking ) - foreach(diffusioncorecmdapp ${diffusioncorecmdapps}) + foreach(diffusionFiberfoxcmdapp ${diffusiontractographycmdapps}) # extract cmd app name and dependencies - string(REPLACE "^^" "\\;" cmdapp_info ${diffusioncorecmdapp}) + string(REPLACE "^^" "\\;" cmdapp_info ${diffusionFiberfoxcmdapp}) set(cmdapp_info_list ${cmdapp_info}) list(GET cmdapp_info_list 0 appname) list(GET cmdapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitkFunctionCreateCommandLineApp( NAME ${appname} DEPENDS MitkCore MitkDiffusionCore ${dependencies_list} PACKAGE_DEPENDS ITK ) endforeach() + if(EXECUTABLE_IS_ENABLED) + MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET}) + endif() + endif() diff --git a/Modules/DiffusionImaging/cmdapps/Fiberfox.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/Fiberfox.cpp similarity index 98% rename from Modules/DiffusionImaging/cmdapps/Fiberfox.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/Fiberfox.cpp index e6e3880ae4..644de8bf95 100755 --- a/Modules/DiffusionImaging/cmdapps/Fiberfox.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/Fiberfox.cpp @@ -1,214 +1,214 @@ /*=================================================================== 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 #include #include #include "mitkCommandLineParser.h" #include #include #include #include using namespace mitk; /*! * \brief Command line interface to Fiberfox. * Simulate a diffusion-weighted image from a tractogram using the specified parameter file. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiberfox"); - parser.setCategory("Fiber Tracking and Processing Methods"); - parser.setContributor("MBI"); + parser.setCategory("Diffusion Simulation Tools"); + parser.setContributor("MIC"); parser.setDescription("Command line interface to Fiberfox." " Simulate a diffusion-weighted image from a tractogram using the specified parameter file."); parser.setArgumentPrefix("--", "-"); parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output root:", "output root", us::Any(), false); parser.addArgument("parameters", "p", mitkCommandLineParser::InputFile, "Parameter file:", "fiberfox parameter file (.ffp)", us::Any(), false); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "Input tractogram or diffusion-weighted image.", us::Any(), false); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Output additional images:", "output volume fraction images etc.", us::Any()); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } string outName = us::any_cast(parsedArgs["out"]); string paramName = us::any_cast(parsedArgs["parameters"]); string input=""; if (parsedArgs.count("input")) { input = us::any_cast(parsedArgs["input"]); } bool verbose = false; if (parsedArgs.count("verbose")) { verbose = us::any_cast(parsedArgs["verbose"]); } FiberfoxParameters parameters; parameters.LoadParameters(paramName); // Test if /path/dir is an existing directory: string file_extension = ""; if( itksys::SystemTools::FileIsDirectory( outName ) ) { while( *(--(outName.cend())) == '/') { outName.pop_back(); } outName = outName + '/'; parameters.m_Misc.m_OutputPath = outName; outName = outName + parameters.m_Misc.m_OutputPrefix; // using default m_OutputPrefix as initialized. } else { // outName is NOT an existing directory, so we need to remove all trailing slashes: while( *(--(outName.cend())) == '/') { outName.pop_back(); } // now split up the given outName into directory and (prefix of) filename: if( ! itksys::SystemTools::GetFilenamePath( outName ).empty() && itksys::SystemTools::FileIsDirectory(itksys::SystemTools::GetFilenamePath( outName ) ) ) { parameters.m_Misc.m_OutputPath = itksys::SystemTools::GetFilenamePath( outName ) + '/'; } else { parameters.m_Misc.m_OutputPath = itksys::SystemTools::GetCurrentWorkingDirectory() + '/'; } file_extension = itksys::SystemTools::GetFilenameExtension(outName); if( ! itksys::SystemTools::GetFilenameWithoutExtension( outName ).empty() ) { parameters.m_Misc.m_OutputPrefix = itksys::SystemTools::GetFilenameWithoutExtension( outName ); } else { parameters.m_Misc.m_OutputPrefix = "fiberfox"; } outName = parameters.m_Misc.m_OutputPath + parameters.m_Misc.m_OutputPrefix; } // check if log file already exists and avoid overwriting existing files: std::string NameTest = outName; int c = 0; while( itksys::SystemTools::FileExists( outName + ".log" ) && c <= std::numeric_limits::max() ) { outName = NameTest + "_" + boost::lexical_cast(c); ++c; } if (verbose) { MITK_DEBUG << outName << ".ffp"; parameters.SaveParameters(outName+".ffp"); } mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images", "Fiberbundles"}, {}); mitk::BaseData::Pointer inputData = mitk::IOUtil::Load(input, &functor)[0]; itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New(); if ( dynamic_cast(inputData.GetPointer()) ) // simulate dataset from fibers { tractsToDwiFilter->SetFiberBundle(dynamic_cast(inputData.GetPointer())); } else if ( dynamic_cast(inputData.GetPointer()) ) // add artifacts to existing image { typedef itk::VectorImage< short, 3 > ItkDwiType; mitk::Image::Pointer diffImg = dynamic_cast(inputData.GetPointer()); ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); mitk::CastToItkImage(diffImg, itkVectorImagePointer); parameters.m_SignalGen.m_SignalScale = 1; parameters.m_SignalGen.m_ImageRegion = itkVectorImagePointer->GetLargestPossibleRegion(); parameters.m_SignalGen.m_ImageSpacing = itkVectorImagePointer->GetSpacing(); parameters.m_SignalGen.m_ImageOrigin = itkVectorImagePointer->GetOrigin(); parameters.m_SignalGen.m_ImageDirection = itkVectorImagePointer->GetDirection(); parameters.m_SignalGen.m_Bvalue = static_cast (diffImg->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() ) ->GetValue(); parameters.m_SignalGen.SetGradienDirections( static_cast ( diffImg->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() ) ->GetGradientDirectionsContainer() ); tractsToDwiFilter->SetInputImage(itkVectorImagePointer); } tractsToDwiFilter->SetParameters(parameters); tractsToDwiFilter->Update(); mitk::Image::Pointer image = mitk::GrabItkImageMemory( tractsToDwiFilter->GetOutput() ); image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( parameters.m_SignalGen.GetGradientDirections() ) ); image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( parameters.m_SignalGen.m_Bvalue ) ); mitk::DiffusionPropertyHelper propertyHelper( image ); propertyHelper.InitializeImage(); if (file_extension=="") mitk::IOUtil::Save(image, "application/vnd.mitk.nii.gz", outName+".nii.gz"); else if (file_extension==".nii" || file_extension==".nii.gz") mitk::IOUtil::Save(image, "application/vnd.mitk.nii.gz", outName+file_extension); else mitk::IOUtil::Save(image, outName+file_extension); if (verbose) { std::vector< itk::TractsToDWIImageFilter< short >::ItkDoubleImgType::Pointer > volumeFractions = tractsToDwiFilter->GetVolumeFractions(); for (unsigned int k=0; kInitializeByItk(volumeFractions.at(k).GetPointer()); image->SetVolume(volumeFractions.at(k)->GetBufferPointer()); mitk::IOUtil::Save(image, outName+"_Compartment"+boost::lexical_cast(k+1)+".nrrd"); } if (tractsToDwiFilter->GetPhaseImage().IsNotNull()) { mitk::Image::Pointer image = mitk::Image::New(); itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer itkPhase = tractsToDwiFilter->GetPhaseImage(); image = mitk::GrabItkImageMemory( itkPhase.GetPointer() ); mitk::IOUtil::Save(image, outName+"_Phase.nrrd"); } if (tractsToDwiFilter->GetKspaceImage().IsNotNull()) { mitk::Image::Pointer image = mitk::Image::New(); itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer itkImage = tractsToDwiFilter->GetKspaceImage(); image = mitk::GrabItkImageMemory( itkImage.GetPointer() ); mitk::IOUtil::Save(image, outName+"_kSpace.nrrd"); } } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/CMakeLists.txt similarity index 57% copy from Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt copy to Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/CMakeLists.txt index 1fe5feb7d2..e759910e7f 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/CMakeLists.txt @@ -1,44 +1,36 @@ -option(BUILD_DiffusionCoreCmdApps "Build commandline tools for diffusion" OFF) +option(BUILD_DiffusionMiscCmdApps "Build miscellaneous commandline tools for diffusion" OFF) -if(BUILD_DiffusionCoreCmdApps OR MITK_BUILD_ALL_APPS) +if(BUILD_DiffusionMiscCmdApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # list of diffusion cmdapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" - set( diffusioncorecmdapps - DwiDenoising^^ - ImageResampler^^ - ExportShImage^^ - CopyGeometry^^ - DiffusionIndices^^ - QballReconstruction^^ - Registration^^ - TensorReconstruction^^ - TensorDerivedMapsExtraction^^ - DiffusionDICOMLoader^^ - DiffusionKurtosisFit^^ + set( diffusionMisccmdapps + PeakExtraction^^MitkFiberTracking + FileFormatConverter^^MitkFiberTracking ) - foreach(diffusioncorecmdapp ${diffusioncorecmdapps}) + foreach(diffusionMisccmdapp ${diffusionMisccmdapps}) # extract cmd app name and dependencies - string(REPLACE "^^" "\\;" cmdapp_info ${diffusioncorecmdapp}) + string(REPLACE "^^" "\\;" cmdapp_info ${diffusionMisccmdapp}) set(cmdapp_info_list ${cmdapp_info}) list(GET cmdapp_info_list 0 appname) list(GET cmdapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitkFunctionCreateCommandLineApp( NAME ${appname} DEPENDS MitkCore MitkDiffusionCore ${dependencies_list} PACKAGE_DEPENDS ITK ) endforeach() + +endif() - endif() diff --git a/Modules/DiffusionImaging/cmdapps/FileFormatConverter.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/FileFormatConverter.cpp similarity index 96% rename from Modules/DiffusionImaging/cmdapps/FileFormatConverter.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/FileFormatConverter.cpp index 4ca767c50c..d5a405a5d2 100644 --- a/Modules/DiffusionImaging/cmdapps/FileFormatConverter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/FileFormatConverter.cpp @@ -1,83 +1,83 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include +#include using namespace mitk; using namespace std; /*! \brief Load image and save as specified file type. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Format Converter"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Preprocessing Tools"); parser.setDescription("Load image and save as specified file type."); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input file", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments string inName = us::any_cast(parsedArgs["in"]); string outName = us::any_cast(parsedArgs["out"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); std::vector baseData = mitk::IOUtil::Load(inName, &functor); if ( baseData.size()>0 && dynamic_cast(baseData[0].GetPointer()) ) { mitk::IOUtil::Save(dynamic_cast(baseData[0].GetPointer()), outName.c_str()); } else if ( baseData.size()>0 && dynamic_cast(baseData[0].GetPointer()) ) { mitk::IOUtil::Save(dynamic_cast(baseData[0].GetPointer()) ,outName.c_str()); } else std::cout << "File type currently not supported!"; } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/PeakExtraction.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PeakExtraction.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/PeakExtraction.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PeakExtraction.cpp index ed869ccb7c..bd582e2439 100755 --- a/Modules/DiffusionImaging/cmdapps/PeakExtraction.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PeakExtraction.cpp @@ -1,371 +1,371 @@ /*=================================================================== 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 #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include using namespace std; template int StartPeakExtraction(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("image", "i", mitkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false); parser.addArgument("outroot", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image"); parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true); parser.addArgument("numpeaks", "p", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true); parser.addArgument("peakthres", "r", mitkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true); parser.addArgument("abspeakthres", "a", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true); parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", string("MITK"), true); parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention"); parser.addArgument("clusterThres", "c", mitkCommandLineParser::Float, "Clustering threshold", "directions closer together than the specified angular threshold will be clustered (in rad)", 0.9); parser.addArgument("flipX", "fx", mitkCommandLineParser::Bool, "Flip X", "Flip peaks in x direction"); parser.addArgument("flipY", "fy", mitkCommandLineParser::Bool, "Flip Y", "Flip peaks in y direction"); parser.addArgument("flipZ", "fz", mitkCommandLineParser::Bool, "Flip Z", "Flip peaks in z direction"); parser.setCategory("Preprocessing Tools"); parser.setTitle("Peak Extraction"); parser.setDescription(""); - parser.setContributor("MBI"); + parser.setContributor("MIC"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments string imageName = us::any_cast(parsedArgs["image"]); string outRoot = us::any_cast(parsedArgs["outroot"]); // optional arguments string maskImageName(""); if (parsedArgs.count("mask")) maskImageName = us::any_cast(parsedArgs["mask"]); int normalization = 1; if (parsedArgs.count("normalization")) normalization = us::any_cast(parsedArgs["normalization"]); int numPeaks = 2; if (parsedArgs.count("numpeaks")) numPeaks = us::any_cast(parsedArgs["numpeaks"]); float peakThres = 0.4; if (parsedArgs.count("peakthres")) peakThres = us::any_cast(parsedArgs["peakthres"]); float absPeakThres = 0.06; if (parsedArgs.count("abspeakthres")) absPeakThres = us::any_cast(parsedArgs["abspeakthres"]); float clusterThres = 0.9; if (parsedArgs.count("clusterThres")) clusterThres = us::any_cast(parsedArgs["clusterThres"]); bool noFlip = false; if (parsedArgs.count("noFlip")) noFlip = us::any_cast(parsedArgs["noFlip"]); bool flipX = false; if (parsedArgs.count("flipX")) flipX = us::any_cast(parsedArgs["flipX"]); bool flipY = false; if (parsedArgs.count("flipY")) flipY = us::any_cast(parsedArgs["flipY"]); bool flipZ = false; if (parsedArgs.count("flipZ")) flipZ = us::any_cast(parsedArgs["flipZ"]); std::cout << "image: " << imageName; std::cout << "outroot: " << outRoot; if (!maskImageName.empty()) std::cout << "mask: " << maskImageName; else std::cout << "no mask image selected"; std::cout << "numpeaks: " << numPeaks; std::cout << "peakthres: " << peakThres; std::cout << "abspeakthres: " << absPeakThres; std::cout << "shOrder: " << shOrder; try { mitk::Image::Pointer image = mitk::IOUtil::LoadImage(imageName); mitk::Image::Pointer mask = mitk::IOUtil::LoadImage(maskImageName); typedef itk::Image ItkUcharImgType; typedef itk::FiniteDiffOdfMaximaExtractionFilter< float, shOrder, 20242 > MaximaExtractionFilterType; typename MaximaExtractionFilterType::Pointer filter = MaximaExtractionFilterType::New(); int toolkitConvention = 0; if (parsedArgs.count("shConvention")) { string convention = us::any_cast(parsedArgs["shConvention"]).c_str(); if ( boost::algorithm::equals(convention, "FSL") ) { toolkitConvention = 1; std::cout << "Using FSL SH-basis"; } else if ( boost::algorithm::equals(convention, "MRtrix") ) { toolkitConvention = 2; std::cout << "Using MRtrix SH-basis"; } else std::cout << "Using MITK SH-basis"; } else std::cout << "Using MITK SH-basis"; ItkUcharImgType::Pointer itkMaskImage = nullptr; if (mask.IsNotNull()) { try{ itkMaskImage = ItkUcharImgType::New(); mitk::CastToItkImage(mask, itkMaskImage); filter->SetMaskImage(itkMaskImage); } catch(...) { } } if (toolkitConvention>0) { std::cout << "Converting coefficient image to MITK format"; typedef itk::ShCoefficientImageImporter< float, shOrder > ConverterType; typedef mitk::ImageToItk< itk::Image< float, 4 > > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); itk::Image< float, 4 >::Pointer itkImage = caster->GetOutput(); typename ConverterType::Pointer converter = ConverterType::New(); if (noFlip) { converter->SetInputImage(itkImage); } else { std::cout << "Flipping image"; itk::FixedArray flipAxes; flipAxes[0] = true; flipAxes[1] = true; flipAxes[2] = false; flipAxes[3] = false; itk::FlipImageFilter< itk::Image< float, 4 > >::Pointer flipper = itk::FlipImageFilter< itk::Image< float, 4 > >::New(); flipper->SetInput(itkImage); flipper->SetFlipAxes(flipAxes); flipper->Update(); itk::Image< float, 4 >::Pointer flipped = flipper->GetOutput(); itk::Matrix< double,4,4 > m = itkImage->GetDirection(); m[0][0] *= -1; m[1][1] *= -1; flipped->SetDirection(m); itk::Point< float, 4 > o = itkImage->GetOrigin(); o[0] -= (flipped->GetLargestPossibleRegion().GetSize(0)-1); o[1] -= (flipped->GetLargestPossibleRegion().GetSize(1)-1); flipped->SetOrigin(o); converter->SetInputImage(flipped); } std::cout << "Starting conversion"; switch (toolkitConvention) { case 1: converter->SetToolkit(ConverterType::FSL); filter->SetToolkit(MaximaExtractionFilterType::FSL); break; case 2: converter->SetToolkit(ConverterType::MRTRIX); filter->SetToolkit(MaximaExtractionFilterType::MRTRIX); break; default: converter->SetToolkit(ConverterType::FSL); filter->SetToolkit(MaximaExtractionFilterType::FSL); break; } converter->GenerateData(); filter->SetInput(converter->GetCoefficientImage()); } else { try{ typedef mitk::ImageToItk< typename MaximaExtractionFilterType::CoefficientImageType > CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); filter->SetInput(caster->GetOutput()); } catch(...) { std::cout << "wrong image type"; return EXIT_FAILURE; } } filter->SetMaxNumPeaks(numPeaks); filter->SetPeakThreshold(peakThres); filter->SetAbsolutePeakThreshold(absPeakThres); filter->SetAngularThreshold(1); filter->SetClusteringThreshold(clusterThres); filter->SetFlipX(flipX); filter->SetFlipY(flipY); filter->SetFlipZ(flipZ); switch (normalization) { case 0: filter->SetNormalizationMethod(MaximaExtractionFilterType::NO_NORM); break; case 1: filter->SetNormalizationMethod(MaximaExtractionFilterType::MAX_VEC_NORM); break; case 2: filter->SetNormalizationMethod(MaximaExtractionFilterType::SINGLE_VEC_NORM); break; } std::cout << "Starting extraction"; filter->Update(); // write direction image { typename MaximaExtractionFilterType::PeakImageType::Pointer itkImg = filter->GetPeakImage(); string outfilename = outRoot; outfilename.append("_PEAKS.nrrd"); typedef itk::ImageFileWriter< typename MaximaExtractionFilterType::PeakImageType > WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outfilename); writer->SetInput(itkImg); writer->Update(); } // write num directions image { ItkUcharImgType::Pointer numDirImage = filter->GetNumDirectionsImage(); if (itkMaskImage.IsNotNull()) { numDirImage->SetDirection(itkMaskImage->GetDirection()); numDirImage->SetOrigin(itkMaskImage->GetOrigin()); } string outfilename = outRoot.c_str(); outfilename.append("_NUM_PEAKS.nrrd"); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outfilename); writer->SetInput(numDirImage); writer->Update(); } // write vector field { mitk::FiberBundle::Pointer directions = filter->GetOutputFiberBundle(); string outfilename = outRoot.c_str(); outfilename.append("_VECTOR_FIELD.fib"); mitk::IOUtil::Save(directions.GetPointer(),outfilename.c_str()); } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } /*! \brief Extract maxima in the input spherical harmonics image. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("image", "i", mitkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false); parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order"); parser.addArgument("outroot", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image"); parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true); parser.addArgument("numpeaks", "p", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true); parser.addArgument("peakthres", "r", mitkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true); parser.addArgument("abspeakthres", "a", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true); parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", string("MITK"), true); parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention"); parser.setCategory("Preprocessing Tools"); parser.setTitle("Peak Extraction"); parser.setDescription("Extract maxima in the input spherical harmonics image."); - parser.setContributor("MBI"); + parser.setContributor("MIC"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; int shOrder = -1; if (parsedArgs.count("shOrder")) shOrder = us::any_cast(parsedArgs["shOrder"]); switch (shOrder) { case 4: return StartPeakExtraction<4>(argc, argv); case 6: return StartPeakExtraction<6>(argc, argv); case 8: return StartPeakExtraction<8>(argc, argv); case 10: return StartPeakExtraction<10>(argc, argv); case 12: return StartPeakExtraction<12>(argc, argv); } return EXIT_FAILURE; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/CMakeLists.txt old mode 100644 new mode 100755 similarity index 57% copy from Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt copy to Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/CMakeLists.txt index 1fe5feb7d2..e509b3958c --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/CMakeLists.txt @@ -1,44 +1,40 @@ -option(BUILD_DiffusionCoreCmdApps "Build commandline tools for diffusion" OFF) +option(BUILD_DiffusionTractographyCmdApps "Build commandline tools for diffusion fiber tractography" OFF) -if(BUILD_DiffusionCoreCmdApps OR MITK_BUILD_ALL_APPS) +if(BUILD_DiffusionTractographyCmdApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # list of diffusion cmdapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" - set( diffusioncorecmdapps - DwiDenoising^^ - ImageResampler^^ - ExportShImage^^ - CopyGeometry^^ - DiffusionIndices^^ - QballReconstruction^^ - Registration^^ - TensorReconstruction^^ - TensorDerivedMapsExtraction^^ - DiffusionDICOMLoader^^ - DiffusionKurtosisFit^^ + set( diffusiontractographycmdapps + StreamlineTracking^^MitkFiberTracking + GibbsTracking^^MitkFiberTracking + RfTraining^^MitkFiberTracking ) - foreach(diffusioncorecmdapp ${diffusioncorecmdapps}) + foreach(diffusiontractographycmdapp ${diffusiontractographycmdapps}) # extract cmd app name and dependencies - string(REPLACE "^^" "\\;" cmdapp_info ${diffusioncorecmdapp}) + string(REPLACE "^^" "\\;" cmdapp_info ${diffusiontractographycmdapp}) set(cmdapp_info_list ${cmdapp_info}) list(GET cmdapp_info_list 0 appname) list(GET cmdapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitkFunctionCreateCommandLineApp( NAME ${appname} DEPENDS MitkCore MitkDiffusionCore ${dependencies_list} PACKAGE_DEPENDS ITK ) endforeach() + if(EXECUTABLE_IS_ENABLED) + MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET}) + endif() + endif() diff --git a/Modules/DiffusionImaging/cmdapps/GibbsTracking.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/GibbsTracking.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/GibbsTracking.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/GibbsTracking.cpp index 997a769f27..e46669e925 100755 --- a/Modules/DiffusionImaging/cmdapps/GibbsTracking.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/GibbsTracking.cpp @@ -1,240 +1,240 @@ /*=================================================================== 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 #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include template typename itk::ShCoefficientImageImporter< float, shOrder >::QballImageType::Pointer TemplatedConvertShCoeffs(mitk::Image* mitkImg, int toolkit, bool noFlip = false) { typedef itk::ShCoefficientImageImporter< float, shOrder > FilterType; typedef mitk::ImageToItk< itk::Image< float, 4 > > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(mitkImg); caster->Update(); itk::Image< float, 4 >::Pointer itkImage = caster->GetOutput(); typename FilterType::Pointer filter = FilterType::New(); if (noFlip) { filter->SetInputImage(itkImage); } else { std::cout << "Flipping image"; itk::FixedArray flipAxes; flipAxes[0] = true; flipAxes[1] = true; flipAxes[2] = false; flipAxes[3] = false; itk::FlipImageFilter< itk::Image< float, 4 > >::Pointer flipper = itk::FlipImageFilter< itk::Image< float, 4 > >::New(); flipper->SetInput(itkImage); flipper->SetFlipAxes(flipAxes); flipper->Update(); itk::Image< float, 4 >::Pointer flipped = flipper->GetOutput(); itk::Matrix< double,4,4 > m = itkImage->GetDirection(); m[0][0] *= -1; m[1][1] *= -1; flipped->SetDirection(m); itk::Point< float, 4 > o = itkImage->GetOrigin(); o[0] -= (flipped->GetLargestPossibleRegion().GetSize(0)-1); o[1] -= (flipped->GetLargestPossibleRegion().GetSize(1)-1); flipped->SetOrigin(o); filter->SetInputImage(flipped); } switch (toolkit) { case 0: filter->SetToolkit(FilterType::FSL); break; case 1: filter->SetToolkit(FilterType::MRTRIX); break; default: filter->SetToolkit(FilterType::FSL); } filter->GenerateData(); return filter->GetQballImage(); } /*! \brief Perform global fiber tractography (Gibbs tractography) */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Gibbs Tracking"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Perform global fiber tractography (Gibbs tractography)"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false); parser.addArgument("parameters", "p", mitkCommandLineParser::InputFile, "Parameters:", "parameter file (.gtp)", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "binary mask image"); parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "SH coefficient:", "sh coefficient convention (FSL, MRtrix)", string("FSL"), true); parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib)", us::Any(), false); parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip:", "do not flip input image to match MITK coordinate convention"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFileName = us::any_cast(parsedArgs["input"]); string paramFileName = us::any_cast(parsedArgs["parameters"]); string outFileName = us::any_cast(parsedArgs["outFile"]); bool noFlip = false; if (parsedArgs.count("noFlip")) noFlip = us::any_cast(parsedArgs["noFlip"]); try { // instantiate gibbs tracker typedef itk::Vector OdfVectorType; typedef itk::Image ItkQballImageType; typedef itk::GibbsTrackingFilter GibbsTrackingFilterType; GibbsTrackingFilterType::Pointer gibbsTracker = GibbsTrackingFilterType::New(); // load input image mitk::Image::Pointer mitkImage = mitk::IOUtil::LoadImage(inFileName); // try to cast to qball image if( boost::algorithm::ends_with(inFileName, ".qbi") ) { std::cout << "Loading qball image ..."; mitk::QBallImage::Pointer mitkQballImage = dynamic_cast(mitkImage.GetPointer()); ItkQballImageType::Pointer itk_qbi = ItkQballImageType::New(); mitk::CastToItkImage(mitkQballImage, itk_qbi); gibbsTracker->SetQBallImage(itk_qbi.GetPointer()); } else if( boost::algorithm::ends_with(inFileName, ".dti") ) { std::cout << "Loading tensor image ..."; typedef itk::Image< itk::DiffusionTensor3D, 3 > ItkTensorImage; mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast(mitkImage.GetPointer()); ItkTensorImage::Pointer itk_dti = ItkTensorImage::New(); mitk::CastToItkImage(mitkTensorImage, itk_dti); gibbsTracker->SetTensorImage(itk_dti); } else if ( boost::algorithm::ends_with(inFileName, ".nii") ) { std::cout << "Loading sh-coefficient image ..."; int nrCoeffs = mitkImage->GetLargestPossibleRegion().GetSize()[3]; int c=3, d=2-2*nrCoeffs; double D = c*c-4*d; int shOrder; if (D>0) { shOrder = (-c+sqrt(D))/2.0; if (shOrder<0) shOrder = (-c-sqrt(D))/2.0; } else if (D==0) shOrder = -c/2.0; std::cout << "using SH-order " << shOrder; int toolkitConvention = 0; if (parsedArgs.count("shConvention")) { string convention = us::any_cast(parsedArgs["shConvention"]).c_str(); if ( boost::algorithm::equals(convention, "MRtrix") ) { toolkitConvention = 1; std::cout << "Using MRtrix style sh-coefficient convention"; } else std::cout << "Using FSL style sh-coefficient convention"; } else std::cout << "Using FSL style sh-coefficient convention"; switch (shOrder) { case 4: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<4>(mitkImage, toolkitConvention, noFlip)); break; case 6: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<6>(mitkImage, toolkitConvention, noFlip)); break; case 8: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<8>(mitkImage, toolkitConvention, noFlip)); break; case 10: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<10>(mitkImage, toolkitConvention, noFlip)); break; case 12: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<12>(mitkImage, toolkitConvention, noFlip)); break; default: std::cout << "SH-order " << shOrder << " not supported"; } } else return EXIT_FAILURE; // global tracking if (parsedArgs.count("mask")) { typedef itk::Image MaskImgType; mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::LoadImage(us::any_cast(parsedArgs["mask"])); MaskImgType::Pointer itk_mask = MaskImgType::New(); mitk::CastToItkImage(mitkMaskImage, itk_mask); gibbsTracker->SetMaskImage(itk_mask); } gibbsTracker->SetDuplicateImage(false); gibbsTracker->SetLoadParameterFile( paramFileName ); // gibbsTracker->SetLutPath( "" ); gibbsTracker->Update(); mitk::FiberBundle::Pointer mitkFiberBundle = mitk::FiberBundle::New(gibbsTracker->GetFiberBundle()); mitkFiberBundle->SetReferenceGeometry(mitkImage->GetGeometry()); mitk::IOUtil::SaveBaseData(mitkFiberBundle.GetPointer(), outFileName ); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/RfTraining.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/RfTraining.cpp similarity index 98% rename from Modules/DiffusionImaging/cmdapps/RfTraining.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/RfTraining.cpp index ebda300334..faee2c35c8 100755 --- a/Modules/DiffusionImaging/cmdapps/RfTraining.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/RfTraining.cpp @@ -1,228 +1,228 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include using namespace std; /*! \brief Train random forest classifier for machine learning based streamline tractography */ int main(int argc, char* argv[]) { MITK_INFO << "RfTraining"; mitkCommandLineParser parser; - parser.setTitle("Training for Machine Learning Based Streamline Tractography"); + parser.setTitle("Trains Random Forests for Machine Learning Based Tractography"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Train random forest classifier for machine learning based streamline tractography"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("images", "i", mitkCommandLineParser::StringList, "DWIs:", "input diffusion-weighted images", us::Any(), false); parser.addArgument("tractograms", "t", mitkCommandLineParser::StringList, "Tractograms:", "input training tractograms (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("forest", "f", mitkCommandLineParser::OutputFile, "Forest:", "output random forest (HDF5)", us::Any(), false); parser.addArgument("masks", "", mitkCommandLineParser::StringList, "Masks:", "restrict training using a binary mask image", us::Any()); parser.addArgument("wm_masks", "", mitkCommandLineParser::StringList, "WM-Masks:", "if no binary white matter mask is specified, the envelope of the input tractogram is used", us::Any()); parser.addArgument("volume_modification_images", "", mitkCommandLineParser::StringList, "Volume modification images:", "specify a list of float images that modify the fiber density", us::Any()); parser.addArgument("additional_feature_images", "", mitkCommandLineParser::StringList, "Additional feature images:", "specify a list of float images that hold additional features (float)", us::Any()); parser.addArgument("sampling_distance", "", mitkCommandLineParser::Float, "Sampling distance:", "resampling parameter for the input tractogram in mm (determines number of white-matter samples)", us::Any()); parser.addArgument("num_gm_samples", "", mitkCommandLineParser::Int, "Number of gray matter samples per voxel:", "Number of gray matter samples per voxel", us::Any()); parser.addArgument("num_trees", "", mitkCommandLineParser::Int, "Number of trees:", "number of trees", 30); parser.addArgument("max_tree_depth", "", mitkCommandLineParser::Int, "Max. tree depth:", "maximum tree depth", 25); parser.addArgument("sample_fraction", "", mitkCommandLineParser::Float, "Sample fraction:", "fraction of samples used per tree", 0.7); parser.addArgument("use_sh_features", "", mitkCommandLineParser::Bool, "Use SH features:", "use SH features", false); parser.addArgument("max_wm_samples", "", mitkCommandLineParser::Int, "Max. num. WM samples:", "upper limit for the number of WM samples"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; bool shfeatures = false; if (parsedArgs.count("use_sh_features")) shfeatures = us::any_cast(parsedArgs["use_sh_features"]); mitkCommandLineParser::StringContainerType imageFiles = us::any_cast(parsedArgs["images"]); mitkCommandLineParser::StringContainerType wmMaskFiles; if (parsedArgs.count("wm_masks")) wmMaskFiles = us::any_cast(parsedArgs["wm_masks"]); mitkCommandLineParser::StringContainerType volModFiles; if (parsedArgs.count("volume_modification_images")) volModFiles = us::any_cast(parsedArgs["volume_modification_images"]); mitkCommandLineParser::StringContainerType addFeatFiles; if (parsedArgs.count("additional_feature_images")) addFeatFiles = us::any_cast(parsedArgs["additional_feature_images"]); mitkCommandLineParser::StringContainerType maskFiles; if (parsedArgs.count("masks")) maskFiles = us::any_cast(parsedArgs["masks"]); string forestFile = us::any_cast(parsedArgs["forest"]); mitkCommandLineParser::StringContainerType tractogramFiles; if (parsedArgs.count("tractograms")) tractogramFiles = us::any_cast(parsedArgs["tractograms"]); int num_trees = 30; if (parsedArgs.count("num_trees")) num_trees = us::any_cast(parsedArgs["num_trees"]); int gm_samples = -1; if (parsedArgs.count("num_gm_samples")) gm_samples = us::any_cast(parsedArgs["num_gm_samples"]); float sampling_distance = -1; if (parsedArgs.count("sampling_distance")) sampling_distance = us::any_cast(parsedArgs["sampling_distance"]); int max_tree_depth = 25; if (parsedArgs.count("max_tree_depth")) max_tree_depth = us::any_cast(parsedArgs["max_tree_depth"]); double sample_fraction = 0.7; if (parsedArgs.count("sample_fraction")) sample_fraction = us::any_cast(parsedArgs["sample_fraction"]); int maxWmSamples = -1; if (parsedArgs.count("max_wm_samples")) maxWmSamples = us::any_cast(parsedArgs["max_wm_samples"]); MITK_INFO << "loading diffusion-weighted images"; std::vector< mitk::Image::Pointer > rawData; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); for (auto imgFile : imageFiles) { mitk::Image::Pointer dwi = dynamic_cast(mitk::IOUtil::LoadImage(imgFile, &functor).GetPointer()); rawData.push_back(dwi); } typedef itk::Image ItkFloatImgType; typedef itk::Image ItkUcharImgType; MITK_INFO << "loading mask images"; std::vector< ItkUcharImgType::Pointer > maskImageVector; for (auto maskFile : maskFiles) { mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::LoadImage(maskFile).GetPointer()); ItkUcharImgType::Pointer mask = ItkUcharImgType::New(); mitk::CastToItkImage(img, mask); maskImageVector.push_back(mask); } MITK_INFO << "loading white matter mask images"; std::vector< ItkUcharImgType::Pointer > wmMaskImageVector; for (auto wmFile : wmMaskFiles) { mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::LoadImage(wmFile).GetPointer()); ItkUcharImgType::Pointer wmmask = ItkUcharImgType::New(); mitk::CastToItkImage(img, wmmask); wmMaskImageVector.push_back(wmmask); } MITK_INFO << "loading tractograms"; std::vector< mitk::FiberBundle::Pointer > tractograms; for (auto tractFile : tractogramFiles) { mitk::FiberBundle::Pointer fib = dynamic_cast(mitk::IOUtil::Load(tractFile).at(0).GetPointer()); tractograms.push_back(fib); } MITK_INFO << "loading white volume modification images"; std::vector< ItkFloatImgType::Pointer > volumeModImages; for (auto file : volModFiles) { mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::LoadImage(file).GetPointer()); ItkFloatImgType::Pointer itkimg = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkimg); volumeModImages.push_back(itkimg); } MITK_INFO << "loading additional feature images"; std::vector< std::vector< ItkFloatImgType::Pointer > > addFeatImages; for (int i=0; i()); int c = 0; for (auto file : addFeatFiles) { mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::LoadImage(file).GetPointer()); ItkFloatImgType::Pointer itkimg = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkimg); addFeatImages.at(c%addFeatImages.size()).push_back(itkimg); c++; } if (shfeatures) { mitk::TrackingHandlerRandomForest<6,28> forestHandler; forestHandler.SetDwis(rawData); forestHandler.SetMaskImages(maskImageVector); forestHandler.SetWhiteMatterImages(wmMaskImageVector); forestHandler.SetFiberVolumeModImages(volumeModImages); forestHandler.SetAdditionalFeatureImages(addFeatImages); forestHandler.SetTractograms(tractograms); forestHandler.SetNumTrees(num_trees); forestHandler.SetMaxTreeDepth(max_tree_depth); forestHandler.SetGrayMatterSamplesPerVoxel(gm_samples); forestHandler.SetSampleFraction(sample_fraction); forestHandler.SetStepSize(sampling_distance); forestHandler.SetMaxNumWmSamples(maxWmSamples); forestHandler.StartTraining(); forestHandler.SaveForest(forestFile); } else { mitk::TrackingHandlerRandomForest<6,100> forestHandler; forestHandler.SetDwis(rawData); forestHandler.SetMaskImages(maskImageVector); forestHandler.SetWhiteMatterImages(wmMaskImageVector); forestHandler.SetFiberVolumeModImages(volumeModImages); forestHandler.SetAdditionalFeatureImages(addFeatImages); forestHandler.SetTractograms(tractograms); forestHandler.SetNumTrees(num_trees); forestHandler.SetMaxTreeDepth(max_tree_depth); forestHandler.SetGrayMatterSamplesPerVoxel(gm_samples); forestHandler.SetSampleFraction(sample_fraction); forestHandler.SetStepSize(sampling_distance); forestHandler.SetMaxNumWmSamples(maxWmSamples); forestHandler.StartTraining(); forestHandler.SaveForest(forestFile); } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/StreamlineTracking.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/StreamlineTracking.cpp similarity index 100% rename from Modules/DiffusionImaging/cmdapps/StreamlineTracking.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/StreamlineTracking.cpp diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/CMakeLists.txt old mode 100644 new mode 100755 similarity index 52% copy from Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt copy to Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/CMakeLists.txt index 1fe5feb7d2..9692f7b2ae --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/CMakeLists.txt @@ -1,44 +1,40 @@ -option(BUILD_DiffusionCoreCmdApps "Build commandline tools for diffusion" OFF) +option(BUILD_DiffusionTractographyEvaluationCmdApps "Build commandline tools for diffusion fiber tractography evaluation" OFF) -if(BUILD_DiffusionCoreCmdApps OR MITK_BUILD_ALL_APPS) +if(BUILD_DiffusionTractographyEvaluationCmdApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # list of diffusion cmdapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" - set( diffusioncorecmdapps - DwiDenoising^^ - ImageResampler^^ - ExportShImage^^ - CopyGeometry^^ - DiffusionIndices^^ - QballReconstruction^^ - Registration^^ - TensorReconstruction^^ - TensorDerivedMapsExtraction^^ - DiffusionDICOMLoader^^ - DiffusionKurtosisFit^^ + set( diffusionTractographyEvaluationcmdapps + PeaksAngularError^^MitkFiberTracking + TractometerMetrics^^MitkFiberTracking + # LocalDirectionalFiberPlausibility^^MitkFiberTracking # HAS TO USE NEW PEAK IMAGE FORMAT ) - foreach(diffusioncorecmdapp ${diffusioncorecmdapps}) + foreach(diffusionTractographyEvaluationcmdapp ${diffusiontractographycmdapps}) # extract cmd app name and dependencies - string(REPLACE "^^" "\\;" cmdapp_info ${diffusioncorecmdapp}) + string(REPLACE "^^" "\\;" cmdapp_info ${diffusionTractographyEvaluationcmdapp}) set(cmdapp_info_list ${cmdapp_info}) list(GET cmdapp_info_list 0 appname) list(GET cmdapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitkFunctionCreateCommandLineApp( NAME ${appname} DEPENDS MitkCore MitkDiffusionCore ${dependencies_list} PACKAGE_DEPENDS ITK ) endforeach() + if(EXECUTABLE_IS_ENABLED) + MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET}) + endif() + endif() diff --git a/Modules/DiffusionImaging/cmdapps/LocalDirectionalFiberPlausibility.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/LocalDirectionalFiberPlausibility.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/LocalDirectionalFiberPlausibility.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/LocalDirectionalFiberPlausibility.cpp index 02e86bfd57..a659842e8b 100755 --- a/Modules/DiffusionImaging/cmdapps/LocalDirectionalFiberPlausibility.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/LocalDirectionalFiberPlausibility.cpp @@ -1,320 +1,320 @@ /*=================================================================== 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 #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include using namespace std; /*! \brief Calculate angular error of a tractogram with respect to the input reference directions. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Local Directional Fiber Plausibility"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription("Calculate angular error of a tractogram with respect to the input reference directions."); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("reference", "r", mitkCommandLineParser::StringList, "Reference images:", "reference direction images", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::StringList, "Masks:", "mask images"); parser.addArgument("athresh", "a", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); parser.addArgument("sthresh", "s", mitkCommandLineParser::Float, "Size threshold:", "Relative peak size threshold per voxel.", 0.0, true); parser.addArgument("maxdirs", "md", mitkCommandLineParser::Int, "Max. Clusters:", "Maximum number of fiber clusters.", 0, true); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results"); parser.addArgument("ignore", "n", mitkCommandLineParser::Bool, "Ignore:", "don't increase error for missing or too many directions"); parser.addArgument("empty", "e", mitkCommandLineParser::Bool, "Empty Voxels:", "don't increase error for empty voxels"); parser.addArgument("fileID", "id", mitkCommandLineParser::String, "ID:", "optional ID field"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType referenceImages = us::any_cast(parsedArgs["reference"]); mitkCommandLineParser::StringContainerType maskImages; if (parsedArgs.count("mask")) maskImages = us::any_cast(parsedArgs["mask"]); string fibFile = us::any_cast(parsedArgs["input"]); float angularThreshold = 25; if (parsedArgs.count("athresh")) angularThreshold = us::any_cast(parsedArgs["athresh"]); float sizeThreshold = 0; if (parsedArgs.count("sthresh")) sizeThreshold = us::any_cast(parsedArgs["sthresh"]); int maxDirs = 0; if (parsedArgs.count("maxdirs")) maxDirs = us::any_cast(parsedArgs["maxdirs"]); string outRoot = us::any_cast(parsedArgs["out"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); bool ignoreMissing = false; if (parsedArgs.count("ignore")) ignoreMissing = us::any_cast(parsedArgs["ignore"]); bool ignoreEmpty = false; if (parsedArgs.count("empty")) ignoreEmpty = us::any_cast(parsedArgs["empty"]); string fileID = ""; if (parsedArgs.count("fileID")) fileID = us::any_cast(parsedArgs["fileID"]); try { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType; // load fiber bundle mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::LoadDataNode(fibFile)->GetData()); // load reference directions ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New(); for (unsigned int i=0; i(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData()); typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput(); referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg); } catch(...){ std::cout << "could not load: " << referenceImages.at(i); } } ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New(); ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0); itkMaskImage->SetSpacing( dirImg->GetSpacing() ); itkMaskImage->SetOrigin( dirImg->GetOrigin() ); itkMaskImage->SetDirection( dirImg->GetDirection() ); itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->Allocate(); itkMaskImage->FillBuffer(1); // extract directions from fiber bundle itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetMaskImage(itkMaskImage); fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180)); fOdfFilter->SetNormalizeVectors(true); fOdfFilter->SetUseWorkingCopy(false); fOdfFilter->SetSizeThreshold(sizeThreshold); fOdfFilter->SetMaxNumDirections(maxDirs); fOdfFilter->Update(); if (verbose) { // write vector field mitk::FiberBundle::Pointer directions = fOdfFilter->GetOutputFiberBundle(); string outfilename = outRoot; outfilename.append("_VECTOR_FIELD.fib"); mitk::IOUtil::SaveBaseData(directions.GetPointer(), outfilename ); // write direction images { itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer itkImg = fOdfFilter->GetDirectionImage(); typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter::ItkDirectionImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_DIRECTIONS.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(itkImg); writer->Update(); } // write num direction image { ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage(); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_NUM_DIRECTIONS.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(numDirImage); writer->Update(); } } string logFile = outRoot; logFile.append("_ANGULAR_ERROR.csv"); ofstream file; file.open (logFile.c_str()); if (maskImages.size()>0) { for (unsigned int i=0; i(mitk::IOUtil::LoadDataNode(maskImages.at(i))->GetData()); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); // evaluate directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); //evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(ignoreMissing); evaluationFilter->SetIgnoreEmptyVoxels(ignoreEmpty); evaluationFilter->Update(); if (verbose) { EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_ERROR_IMAGE.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } string maskFileName = itksys::SystemTools::GetFilenameWithoutExtension(maskImages.at(i)); unsigned found = maskFileName.find_last_of("_"); string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile); if (!fileID.empty()) sens = fileID; sens.append(","); sens.append(maskFileName.substr(found+1)); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append(";\n"); file << sens; } } else { // evaluate directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); //evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(ignoreMissing); evaluationFilter->SetIgnoreEmptyVoxels(ignoreEmpty); evaluationFilter->Update(); if (verbose) { EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_ERROR_IMAGE.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile); if (!fileID.empty()) sens = fileID; sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append(";\n"); file << sens; } file.close(); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/PeaksAngularError.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/PeaksAngularError.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/PeaksAngularError.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/PeaksAngularError.cpp index 276179d121..14d1bb6fa7 100755 --- a/Modules/DiffusionImaging/cmdapps/PeaksAngularError.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/PeaksAngularError.cpp @@ -1,209 +1,209 @@ /*=================================================================== 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 #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include using namespace std; /*! \brief Calculate angular error between two sets of directions stored in multiple 3D vector images where each pixel corresponds to a vector (itk::Image< itk::Vector< float, 3>, 3 >) */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("test", "t", mitkCommandLineParser::StringList, "Test images", "test direction images", us::Any(), false); parser.addArgument("reference", "r", mitkCommandLineParser::StringList, "Reference images", "reference direction images", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image"); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose", "output optional and intermediate calculation results"); parser.addArgument("ignore", "i", mitkCommandLineParser::Bool, "Ignore", "don't increase error for missing or too many directions"); - parser.setCategory("Preprocessing Tools"); + parser.setCategory("Fiber Tracking Evaluation"); parser.setTitle("Peaks Angular Error"); parser.setDescription("Calculate angular error between two sets of directions stored in multiple 3D vector images where each pixel corresponds to a vector (itk::Image< itk::Vector< float, 3>, 3 >)"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType testImages = us::any_cast(parsedArgs["test"]); mitkCommandLineParser::StringContainerType referenceImages = us::any_cast(parsedArgs["reference"]); string maskImage(""); if (parsedArgs.count("mask")) maskImage = us::any_cast(parsedArgs["mask"]); string outRoot = us::any_cast(parsedArgs["out"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); bool ignore = false; if (parsedArgs.count("ignore")) ignore = us::any_cast(parsedArgs["ignore"]); try { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType; ItkDirectionImageContainerType::Pointer directionImageContainer = ItkDirectionImageContainerType::New(); for (unsigned int i=0; i(mitk::IOUtil::LoadDataNode(testImages.at(i))->GetData()); typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput(); directionImageContainer->InsertElement(directionImageContainer->Size(),itkImg); } catch(...){ std::cout << "could not load: " << referenceImages.at(i); } } // load reference directions ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New(); for (unsigned int i=0; i(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData()); typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput(); referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg); } catch(...){ std::cout << "could not load: " << referenceImages.at(i); } } // load/create mask image ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New(); if (maskImage.compare("")==0) { ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0); itkMaskImage->SetSpacing( dirImg->GetSpacing() ); itkMaskImage->SetOrigin( dirImg->GetOrigin() ); itkMaskImage->SetDirection( dirImg->GetDirection() ); itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->Allocate(); itkMaskImage->FillBuffer(1); } else { mitk::Image::Pointer mitkMaskImage = dynamic_cast(mitk::IOUtil::LoadDataNode(maskImage)->GetData()); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); } // evaluate directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(ignore); evaluationFilter->Update(); if (verbose) { EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_ERROR_IMAGE.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } string logFile = outRoot; logFile.append("_ANGULAR_ERROR.csv"); ofstream file; file.open (logFile.c_str()); string sens = "Mean:"; sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(";\n"); sens.append("Median:"); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(";\n"); sens.append("Maximum:"); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(";\n"); sens.append("Minimum:"); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(";\n"); sens.append("STDEV:"); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append(";\n"); file << sens; file.close(); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/TractometerMetrics.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/TractometerMetrics.cpp similarity index 99% rename from Modules/DiffusionImaging/cmdapps/TractometerMetrics.cpp rename to Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/TractometerMetrics.cpp index 72d5dbb8d0..303a218b5f 100755 --- a/Modules/DiffusionImaging/cmdapps/TractometerMetrics.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/TractometerMetrics.cpp @@ -1,418 +1,418 @@ /*=================================================================== 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 #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include using namespace std; /*! \brief Calculates the Tractometer evaluation metrics for tractograms (http://www.tractometer.org/) */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Tractometer Metrics"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription("Calculates the Tractometer evaluation metrics for tractograms (http://www.tractometer.org/)"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("labels", "l", mitkCommandLineParser::StringList, "Label pairs:", "label pairs", false); parser.addArgument("labelimage", "li", mitkCommandLineParser::String, "Label image:", "label image", false); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output valid, invalid and no connections as fiber bundles"); parser.addArgument("fileID", "id", mitkCommandLineParser::String, "ID:", "optional ID field"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType labelpairs = us::any_cast(parsedArgs["labels"]); string fibFile = us::any_cast(parsedArgs["input"]); string labelImageFile = us::any_cast(parsedArgs["labelimage"]); string outRoot = us::any_cast(parsedArgs["out"]); string fileID = ""; if (parsedArgs.count("fileID")) fileID = us::any_cast(parsedArgs["fileID"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); try { typedef itk::Image ItkShortImgType; typedef itk::Image ItkUcharImgType; // load fiber bundle mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::LoadDataNode(fibFile)->GetData()); mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::LoadDataNode(labelImageFile)->GetData()); typedef mitk::ImageToItk< ItkShortImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkShortImgType::Pointer labelImage = caster->GetOutput(); string path = itksys::SystemTools::GetFilenamePath(labelImageFile); std::vector< bool > detected; std::vector< std::pair< int, int > > labelsvector; std::vector< ItkUcharImgType::Pointer > bundleMasks; std::vector< ItkUcharImgType::Pointer > bundleMasksCoverage; short max = 0; for (unsigned int i=0; i l; l.first = boost::lexical_cast(labelpairs.at(i)); l.second = boost::lexical_cast(labelpairs.at(i+1)); std::cout << labelpairs.at(i); std::cout << labelpairs.at(i+1); if (l.first>max) max=l.first; if (l.second>max) max=l.second; labelsvector.push_back(l); detected.push_back(false); { mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::LoadDataNode(path+"/Bundle"+boost::lexical_cast(labelsvector.size())+"_MASK.nrrd")->GetData()); typedef mitk::ImageToItk< ItkUcharImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkUcharImgType::Pointer bundle = caster->GetOutput(); bundleMasks.push_back(bundle); } { mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::LoadDataNode(path+"/Bundle"+boost::lexical_cast(labelsvector.size())+"_MASK_COVERAGE.nrrd")->GetData()); typedef mitk::ImageToItk< ItkUcharImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkUcharImgType::Pointer bundle = caster->GetOutput(); bundleMasksCoverage.push_back(bundle); } } vnl_matrix< unsigned char > matrix; matrix.set_size(max, max); matrix.fill(0); vtkSmartPointer polyData = inputTractogram->GetFiberPolyData(); int validConnections = 0; int noConnection = 0; int validBundles = 0; int invalidBundles = 0; int invalidConnections = 0; ItkUcharImgType::Pointer coverage = ItkUcharImgType::New(); coverage->SetSpacing(labelImage->GetSpacing()); coverage->SetOrigin(labelImage->GetOrigin()); coverage->SetDirection(labelImage->GetDirection()); coverage->SetLargestPossibleRegion(labelImage->GetLargestPossibleRegion()); coverage->SetBufferedRegion( labelImage->GetLargestPossibleRegion() ); coverage->SetRequestedRegion( labelImage->GetLargestPossibleRegion() ); coverage->Allocate(); coverage->FillBuffer(0); vtkSmartPointer noConnPoints = vtkSmartPointer::New(); vtkSmartPointer noConnCells = vtkSmartPointer::New(); vtkSmartPointer invalidPoints = vtkSmartPointer::New(); vtkSmartPointer invalidCells = vtkSmartPointer::New(); vtkSmartPointer validPoints = vtkSmartPointer::New(); vtkSmartPointer validCells = vtkSmartPointer::New(); boost::progress_display disp(inputTractogram->GetNumFibers()); for (int i=0; iGetNumFibers(); i++) { ++disp; vtkCell* cell = polyData->GetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (numPoints>1) { double* start = points->GetPoint(0); itk::Point itkStart; itkStart[0] = start[0]; itkStart[1] = start[1]; itkStart[2] = start[2]; itk::Index<3> idxStart; labelImage->TransformPhysicalPointToIndex(itkStart, idxStart); double* end = points->GetPoint(numPoints-1); itk::Point itkEnd; itkEnd[0] = end[0]; itkEnd[1] = end[1]; itkEnd[2] = end[2]; itk::Index<3> idxEnd; labelImage->TransformPhysicalPointToIndex(itkEnd, idxEnd); if ( labelImage->GetPixel(idxStart)==0 || labelImage->GetPixel(idxEnd)==0 ) { noConnection++; if (verbose) { vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = noConnPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } noConnCells->InsertNextCell(container); } } else { bool invalid = true; for (unsigned int i=0; i l = labelsvector.at(i); if ( (labelImage->GetPixel(idxStart)==l.first && labelImage->GetPixel(idxEnd)==l.second) || (labelImage->GetPixel(idxStart)==l.second && labelImage->GetPixel(idxEnd)==l.first) ) { for (int j=0; jGetPoint(j); itk::Point itkP; itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2]; itk::Index<3> idx; bundle->TransformPhysicalPointToIndex(itkP, idx); if ( !bundle->GetPixel(idx)>0 && bundle->GetLargestPossibleRegion().IsInside(idx) ) { outside=true; } } if (!outside) { validConnections++; if (detected.at(i)==false) validBundles++; detected.at(i) = true; invalid = false; vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = validPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); itk::Point itkP; itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2]; itk::Index<3> idx; coverage->TransformPhysicalPointToIndex(itkP, idx); if ( coverage->GetLargestPossibleRegion().IsInside(idx) ) coverage->SetPixel(idx, 1); } validCells->InsertNextCell(container); } break; } } if (invalid==true) { invalidConnections++; int x = labelImage->GetPixel(idxStart)-1; int y = labelImage->GetPixel(idxEnd)-1; if (x>=0 && y>0 && x container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = invalidPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } invalidCells->InsertNextCell(container); } } } } } if (verbose) { mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); vtkSmartPointer noConnPolyData = vtkSmartPointer::New(); noConnPolyData->SetPoints(noConnPoints); noConnPolyData->SetLines(noConnCells); mitk::FiberBundle::Pointer noConnFib = mitk::FiberBundle::New(noConnPolyData); string ncfilename = outRoot; ncfilename.append("_NC.fib"); mitk::IOUtil::SaveBaseData(noConnFib.GetPointer(), ncfilename ); vtkSmartPointer invalidPolyData = vtkSmartPointer::New(); invalidPolyData->SetPoints(invalidPoints); invalidPolyData->SetLines(invalidCells); mitk::FiberBundle::Pointer invalidFib = mitk::FiberBundle::New(invalidPolyData); string icfilename = outRoot; icfilename.append("_IC.fib"); mitk::IOUtil::SaveBaseData(invalidFib.GetPointer(), icfilename ); vtkSmartPointer validPolyData = vtkSmartPointer::New(); validPolyData->SetPoints(validPoints); validPolyData->SetLines(validCells); mitk::FiberBundle::Pointer validFib = mitk::FiberBundle::New(validPolyData); string vcfilename = outRoot; vcfilename.append("_VC.fib"); mitk::IOUtil::SaveBaseData(validFib.GetPointer(), vcfilename ); { typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outRoot+"_ABC.nrrd"); writer->SetInput(coverage); writer->Update(); } } // calculate coverage int wmVoxels = 0; int coveredVoxels = 0; itk::ImageRegionIterator it (coverage, coverage->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { bool wm = false; for (unsigned int i=0; iGetPixel(it.GetIndex())>0) { wm = true; wmVoxels++; break; } } if (wm && it.Get()>0) coveredVoxels++; ++it; } int numFibers = inputTractogram->GetNumFibers(); double nc = (double)noConnection/numFibers; double vc = (double)validConnections/numFibers; double ic = (double)invalidConnections/numFibers; if (numFibers==0) { nc = 0.0; vc = 0.0; ic = 0.0; } int vb = validBundles; int ib = invalidBundles; double abc = (double)coveredVoxels/wmVoxels; std::cout << "NC: " << nc; std::cout << "VC: " << vc; std::cout << "IC: " << ic; std::cout << "VB: " << vb; std::cout << "IB: " << ib; std::cout << "ABC: " << abc; string logFile = outRoot; logFile.append("_TRACTOMETER.csv"); ofstream file; file.open (logFile.c_str()); { string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile); if (!fileID.empty()) sens = fileID; sens.append(","); sens.append(boost::lexical_cast(nc)); sens.append(","); sens.append(boost::lexical_cast(vc)); sens.append(","); sens.append(boost::lexical_cast(ic)); sens.append(","); sens.append(boost::lexical_cast(validBundles)); sens.append(","); sens.append(boost::lexical_cast(invalidBundles)); sens.append(","); sens.append(boost::lexical_cast(abc)); sens.append(";\n"); file << sens; } file.close(); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/Quantification/CMakeLists.txt b/Modules/DiffusionImaging/Quantification/CMakeLists.txt index 3308f19cfa..3c93b1eb41 100644 --- a/Modules/DiffusionImaging/Quantification/CMakeLists.txt +++ b/Modules/DiffusionImaging/Quantification/CMakeLists.txt @@ -1,15 +1,16 @@ # With apple gcc 4.2.1 the following waring leads to an build error if boost is enabled if(APPLE) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=empty-body" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() #DiffusionImaging/Quantification MITK_CREATE_MODULE( SUBPROJECTS MITK-DTI INCLUDE_DIRS Algorithms IODataStructures IODataStructures/TbssImages Rendering ${CMAKE_CURRENT_BINARY_DIR} DEPENDS MitkDiffusionCore MitkFiberTracking MitkGraphAlgorithms PACKAGE_DEPENDS ITK|ITKThresholding WARNINGS_AS_ERRORS ) add_subdirectory(Testing) +add_subdirectory(cmdapps) diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt b/Modules/DiffusionImaging/Quantification/cmdapps/CMakeLists.txt similarity index 67% copy from Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt copy to Modules/DiffusionImaging/Quantification/cmdapps/CMakeLists.txt index 1fe5feb7d2..bd65206b21 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CMakeLists.txt +++ b/Modules/DiffusionImaging/Quantification/cmdapps/CMakeLists.txt @@ -1,44 +1,39 @@ -option(BUILD_DiffusionCoreCmdApps "Build commandline tools for diffusion" OFF) +option(BUILD_DiffusionQuantificationCmdApps "Build commandline tools for diffusion quantification (IVIM, ADC, ...)" OFF) -if(BUILD_DiffusionCoreCmdApps OR MITK_BUILD_ALL_APPS) +if(BUILD_DiffusionQuantificationCmdApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # list of diffusion cmdapps # if an app requires additional dependencies # they are added after a "^^" and separated by "_" - set( diffusioncorecmdapps - DwiDenoising^^ - ImageResampler^^ - ExportShImage^^ - CopyGeometry^^ + set( diffusionQuantificationcmdapps DiffusionIndices^^ QballReconstruction^^ - Registration^^ TensorReconstruction^^ TensorDerivedMapsExtraction^^ - DiffusionDICOMLoader^^ DiffusionKurtosisFit^^ + MultishellMethods^^ ) - foreach(diffusioncorecmdapp ${diffusioncorecmdapps}) + foreach(diffusionQuantificationcmdapp ${diffusionQuantificationcmdapps}) # extract cmd app name and dependencies - string(REPLACE "^^" "\\;" cmdapp_info ${diffusioncorecmdapp}) + string(REPLACE "^^" "\\;" cmdapp_info ${diffusionQuantificationcmdapp}) set(cmdapp_info_list ${cmdapp_info}) list(GET cmdapp_info_list 0 appname) list(GET cmdapp_info_list 1 raw_dependencies) string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") set(dependencies_list ${dependencies}) mitkFunctionCreateCommandLineApp( NAME ${appname} DEPENDS MitkCore MitkDiffusionCore ${dependencies_list} PACKAGE_DEPENDS ITK ) endforeach() - - endif() + +endif() diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionIndices.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/DiffusionIndices.cpp similarity index 99% rename from Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionIndices.cpp rename to Modules/DiffusionImaging/Quantification/cmdapps/DiffusionIndices.cpp index 984e4ac5d1..67b06afc5a 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionIndices.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/DiffusionIndices.cpp @@ -1,145 +1,145 @@ /*=================================================================== 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 #include #include #include "mitkCommandLineParser.h" #include #include #include #include using namespace std; /** * Calculate indices derived from Qball or tensor images */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Diffusion Indices"); parser.setCategory("Diffusion Related Measures"); parser.setDescription("Computes requested diffusion related measures"); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false); parser.addArgument("index", "idx", mitkCommandLineParser::String, "Index:", "index (fa, gfa, ra, ad, rd, ca, l2, l3, md)", us::Any(), false); parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFileName = us::any_cast(parsedArgs["input"]); string index = us::any_cast(parsedArgs["index"]); string outFileName = us::any_cast(parsedArgs["outFile"]); string ext = itksys::SystemTools::GetFilenameLastExtension(outFileName); if (ext.empty()) outFileName += ".nrrd"; try { // load input image std::vector infile = mitk::IOUtil::Load( inFileName ); if( boost::algorithm::ends_with(inFileName, ".qbi") && index=="gfa" ) { typedef itk::Vector OdfVectorType; typedef itk::Image ItkQballImageType; mitk::QBallImage::Pointer mitkQballImage = dynamic_cast(infile[0].GetPointer()); ItkQballImageType::Pointer itk_qbi = ItkQballImageType::New(); mitk::CastToItkImage(mitkQballImage, itk_qbi); typedef itk::DiffusionQballGeneralizedFaImageFilter GfaFilterType; GfaFilterType::Pointer gfaFilter = GfaFilterType::New(); gfaFilter->SetInput(itk_qbi); gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD); gfaFilter->Update(); itk::ImageFileWriter< itk::Image >::Pointer fileWriter = itk::ImageFileWriter< itk::Image >::New(); fileWriter->SetInput(gfaFilter->GetOutput()); fileWriter->SetFileName(outFileName); fileWriter->Update(); } else if( boost::algorithm::ends_with(inFileName, ".dti") ) { typedef itk::Image< itk::DiffusionTensor3D, 3 > ItkTensorImage; mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast(infile[0].GetPointer()); ItkTensorImage::Pointer itk_dti = ItkTensorImage::New(); mitk::CastToItkImage(mitkTensorImage, itk_dti); typedef itk::TensorDerivedMeasurementsFilter MeasurementsType; MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itk_dti.GetPointer() ); if(index=="fa") measurementsCalculator->SetMeasure(MeasurementsType::FA); else if(index=="ra") measurementsCalculator->SetMeasure(MeasurementsType::RA); else if(index=="ad") measurementsCalculator->SetMeasure(MeasurementsType::AD); else if(index=="rd") measurementsCalculator->SetMeasure(MeasurementsType::RD); else if(index=="ca") measurementsCalculator->SetMeasure(MeasurementsType::CA); else if(index=="l2") measurementsCalculator->SetMeasure(MeasurementsType::L2); else if(index=="l3") measurementsCalculator->SetMeasure(MeasurementsType::L3); else if(index=="md") measurementsCalculator->SetMeasure(MeasurementsType::MD); else { MITK_WARN << "No valid diffusion index for input image (tensor image) defined"; return EXIT_FAILURE; } measurementsCalculator->Update(); itk::ImageFileWriter< itk::Image >::Pointer fileWriter = itk::ImageFileWriter< itk::Image >::New(); fileWriter->SetInput(measurementsCalculator->GetOutput()); fileWriter->SetFileName(outFileName); fileWriter->Update(); } else std::cout << "Diffusion index " << index << " not supported for supplied file type."; } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionKurtosisFit.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/DiffusionKurtosisFit.cpp similarity index 99% rename from Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionKurtosisFit.cpp rename to Modules/DiffusionImaging/Quantification/cmdapps/DiffusionKurtosisFit.cpp index 363498ee22..9850df25b7 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DiffusionKurtosisFit.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/DiffusionKurtosisFit.cpp @@ -1,254 +1,254 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include "mitkImage.h" #include #include #include #include "mitkIOUtil.h" #include #include //vnl_includes #include "vnl/vnl_math.h" #include "vnl/vnl_cost_function.h" #include "vnl/vnl_least_squares_function.h" #include "vnl/algo/vnl_lbfgsb.h" #include "vnl/algo/vnl_lbfgs.h" #include "vnl/algo/vnl_levenberg_marquardt.h" typedef mitk::DiffusionPropertyHelper DPH; #include #include #include #include #include #include #include DPH::ImageType::Pointer GetBlurredVectorImage( DPH::ImageType::Pointer vectorImage, double sigma) { typedef itk::DiscreteGaussianImageFilter< itk::Image, itk::Image > GaussianFilterType; typedef itk::VectorIndexSelectionCastImageFilter< DPH::ImageType, itk::Image > IndexSelectionType; IndexSelectionType::Pointer indexSelectionFilter = IndexSelectionType::New(); indexSelectionFilter->SetInput( vectorImage ); typedef itk::ComposeImageFilter< itk::Image, DPH::ImageType > ComposeFilterType; ComposeFilterType::Pointer vec_composer = ComposeFilterType::New(); for( unsigned int i=0; iGetVectorLength(); ++i) { GaussianFilterType::Pointer gaussian_filter = GaussianFilterType::New(); indexSelectionFilter->SetIndex( i ); gaussian_filter->SetInput( indexSelectionFilter->GetOutput() ); gaussian_filter->SetVariance( sigma ); vec_composer->SetInput(i, gaussian_filter->GetOutput() ); gaussian_filter->Update(); } try { vec_composer->Update(); } catch(const itk::ExceptionObject &e) { mitkThrow() << "[VectorImage.GaussianSmoothing] !! Failed with ITK Exception: " << e.what(); } DPH::ImageType::Pointer smoothed_vector = vec_composer->GetOutput(); /* itk::ImageFileWriter< DPH::ImageType >::Pointer writer = itk::ImageFileWriter< DPH::ImageType >::New(); writer->SetInput( smoothed_vector ); writer->SetFileName( "/tmp/itk_smoothed_vector.nrrd"); writer->Update();*/ return smoothed_vector; } void KurtosisMapComputation( mitk::Image::Pointer input, std::string output_prefix , std::string output_type, std::string maskPath, bool omitBZero, double lower, double upper ) { DPH::ImageType::Pointer vectorImage = DPH::ImageType::New(); mitk::CastToItkImage( input, vectorImage ); typedef itk::DiffusionKurtosisReconstructionImageFilter< short, double > KurtosisFilterType; KurtosisFilterType::Pointer kurtosis_filter = KurtosisFilterType::New(); kurtosis_filter->SetInput( GetBlurredVectorImage( vectorImage, 1.5 ) ); kurtosis_filter->SetReferenceBValue( DPH::GetReferenceBValue( input.GetPointer() ) ); kurtosis_filter->SetGradientDirections( DPH::GetGradientContainer( input.GetPointer() ) ); // kurtosis_filter->SetNumberOfThreads(1); kurtosis_filter->SetOmitUnweightedValue(omitBZero); kurtosis_filter->SetBoundariesForKurtosis(-lower,upper); // kurtosis_filter->SetInitialSolution(const vnl_vector& x0 ); if(maskPath != "") { mitk::Image::Pointer segmentation; segmentation = mitk::IOUtil::LoadImage(maskPath); typedef itk::Image< short , 3> MaskImageType; MaskImageType::Pointer vectorSeg = MaskImageType::New() ; mitk::CastToItkImage( segmentation, vectorSeg ); kurtosis_filter->SetImageMask(vectorSeg) ; } try { kurtosis_filter->Update(); } catch( const itk::ExceptionObject& e) { mitkThrow() << "Kurtosis fit failed with an ITK Exception: " << e.what(); } mitk::Image::Pointer d_image = mitk::Image::New(); d_image->InitializeByItk( kurtosis_filter->GetOutput(0) ); d_image->SetVolume( kurtosis_filter->GetOutput(0)->GetBufferPointer() ); mitk::Image::Pointer k_image = mitk::Image::New(); k_image->InitializeByItk( kurtosis_filter->GetOutput(1) ); k_image->SetVolume( kurtosis_filter->GetOutput(1)->GetBufferPointer() ); std::string outputD_FileName = output_prefix + "_ADC_map." + output_type; std::string outputK_FileName = output_prefix + "_AKC_map." + output_type; try { mitk::IOUtil::Save( d_image, outputD_FileName ); mitk::IOUtil::Save( k_image, outputK_FileName ); } catch( const itk::ExceptionObject& e) { mitkThrow() << "Failed to save the KurtosisFit Results due to exception: " << e.what(); } } int main( int argc, char* argv[] ) { mitkCommandLineParser parser; parser.setTitle("Diffusion Kurtosis Fit"); - parser.setCategory("Signal Reconstruction"); + parser.setCategory("Diffusion Related Measures"); parser.setContributor("MIC"); parser.setDescription("Fitting Kurtosis"); parser.setArgumentPrefix("--","-"); // mandatory arguments parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input: ", "input image (DWI)", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::String, "Output Preifx: ", "Prefix for the output images, will append _f, _K, _D accordingly ", us::Any(), false); parser.addArgument("output_type", "ot", mitkCommandLineParser::String, "Output Type: ", "choose data type of output image, e.g. '.nii' or '.nrrd' ", us::Any(), false); // optional arguments parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Masking Image: ", "ROI (segmentation)", us::Any()); parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help", "Show this help text"); parser.addArgument("omitbzero", "om", mitkCommandLineParser::Bool, "Omit b0:", "Omit b0 value during fit (default = false)", us::Any()); parser.addArgument("lowerkbound", "kl", mitkCommandLineParser::Float, "lower Kbound:", "Set (unsigned) lower boundary for Kurtosis parameter (default = -1000)", us::Any()); parser.addArgument("upperkbound", "ku", mitkCommandLineParser::Float, "upper Kbound:", "Set upper boundary for Kurtosis parameter (default = 1000)", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")){ std::cout << parser.helpText(); return EXIT_SUCCESS; } // mandatory arguments std::string inFileName = us::any_cast(parsedArgs["input"]); std::string out_prefix = us::any_cast(parsedArgs["output"]); std::string maskPath = ""; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inFileName, &functor); bool omitBZero = false; double lower = -1000; double upper = 1000; std::string out_type = "nrrd"; if (parsedArgs.count("mask") || parsedArgs.count("m")) { maskPath = us::any_cast(parsedArgs["mask"]); } if (parsedArgs.count("output_type") || parsedArgs.count("ot")) { out_type = us::any_cast(parsedArgs["output_type"]); } if (parsedArgs.count("omitbzero") || parsedArgs.count("om")) { omitBZero = us::any_cast(parsedArgs["omitbzero"]); } if (parsedArgs.count("lowerkbound") || parsedArgs.count("kl")) { lower = us::any_cast(parsedArgs["lowerkbound"]); } if (parsedArgs.count("upperkbound") || parsedArgs.count("ku")) { upper = us::any_cast(parsedArgs["upperkbound"]); } if( !DPH::IsDiffusionWeightedImage( inputImage ) ) { MITK_ERROR("DiffusionIVIMFit.Input") << "No valid diffusion-weighted image provided, failed to load " << inFileName << " as DW Image. Aborting..."; return EXIT_FAILURE; } KurtosisMapComputation( inputImage, out_prefix , out_type, maskPath, omitBZero, lower, upper); } diff --git a/Modules/DiffusionImaging/cmdapps/MultishellMethods.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/MultishellMethods.cpp similarity index 98% rename from Modules/DiffusionImaging/cmdapps/MultishellMethods.cpp rename to Modules/DiffusionImaging/Quantification/cmdapps/MultishellMethods.cpp index 86112381a6..b23d1d10c0 100644 --- a/Modules/DiffusionImaging/cmdapps/MultishellMethods.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/MultishellMethods.cpp @@ -1,220 +1,219 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include -#include #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Multishell Methods"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Preprocessing Tools"); parser.setDescription(""); - parser.setContributor("MBI"); + parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input file", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false); parser.addArgument("adc", "D", mitkCommandLineParser::Bool, "ADC:", "ADC Average", us::Any(), false); parser.addArgument("akc", "K", mitkCommandLineParser::Bool, "Kurtosis fit:", "Kurtosis Fit", us::Any(), false); parser.addArgument("biexp", "B", mitkCommandLineParser::Bool, "BiExp fit:", "BiExp fit", us::Any(), false); parser.addArgument("targetbvalue", "b", mitkCommandLineParser::String, "b Value:", "target bValue (mean, min, max)", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments string inName = us::any_cast(parsedArgs["in"]); string outName = us::any_cast(parsedArgs["out"]); bool applyADC = us::any_cast(parsedArgs["adc"]); bool applyAKC = us::any_cast(parsedArgs["akc"]); bool applyBiExp = us::any_cast(parsedArgs["biexp"]); string targetType = us::any_cast(parsedArgs["targetbvalue"]); try { std::cout << "Loading " << inName; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer dwi = mitk::IOUtil::LoadImage(inName, &functor); if ( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dwi ) ) { typedef itk::RadialMultishellToSingleshellImageFilter FilterType; typedef itk::DwiGradientLengthCorrectionFilter CorrectionFilterType; CorrectionFilterType::Pointer roundfilter = CorrectionFilterType::New(); roundfilter->SetRoundingValue( 1000 ); roundfilter->SetReferenceBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi )); roundfilter->SetReferenceGradientDirectionContainer(mitk::DiffusionPropertyHelper::GetGradientContainer(dwi)); roundfilter->Update(); dwi->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( roundfilter->GetNewBValue() ) ); dwi->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( roundfilter->GetOutputGradientDirectionContainer() ) ); // filter input parameter const mitk::DiffusionPropertyHelper::BValueMapType &originalShellMap = mitk::DiffusionPropertyHelper::GetBValueMap(dwi); mitk::DiffusionPropertyHelper::ImageType::Pointer vectorImage = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, vectorImage); const mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradientContainer = mitk::DiffusionPropertyHelper::GetGradientContainer(dwi); const unsigned int &bValue = mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi ); // filter call vnl_vector bValueList(originalShellMap.size()-1); double targetBValue = bValueList.mean(); mitk::DiffusionPropertyHelper::BValueMapType::const_iterator it = originalShellMap.begin(); ++it; int i = 0 ; for(; it != originalShellMap.end(); ++it) bValueList.put(i++,it->first); if( targetType == "mean" ) targetBValue = bValueList.mean(); else if( targetType == "min" ) targetBValue = bValueList.min_value(); else if( targetType == "max" ) targetBValue = bValueList.max_value(); if(applyADC) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); outImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( targetBValue ) ); outImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetTargetGradientDirections() ) ); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, (outName + "_ADC.dwi").c_str()); } if(applyAKC) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); outImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( targetBValue ) ); outImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetTargetGradientDirections() ) ); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, (string(outName) + "_AKC.dwi").c_str()); } if(applyBiExp) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); outImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( targetBValue ) ); outImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetTargetGradientDirections() ) ); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, (string(outName) + "_BiExp.dwi").c_str()); } } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/QballReconstruction.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/QballReconstruction.cpp similarity index 99% rename from Modules/DiffusionImaging/DiffusionCore/cmdapps/QballReconstruction.cpp rename to Modules/DiffusionImaging/Quantification/cmdapps/QballReconstruction.cpp index 93390ff3d0..942573a283 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/QballReconstruction.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/QballReconstruction.cpp @@ -1,263 +1,263 @@ /*=================================================================== 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 "mitkImage.h" #include "itkAnalyticalDiffusionQballReconstructionImageFilter.h" #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include using namespace mitk; using namespace std; /** * Perform Q-ball reconstruction using a spherical harmonics basis */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false); parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false); parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order", 4, true); parser.addArgument("b0Threshold", "t", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true); parser.addArgument("lambda", "r", mitkCommandLineParser::Float, "Lambda", "ragularization factor lambda", 0.006, true); parser.addArgument("csa", "csa", mitkCommandLineParser::Bool, "Constant solid angle consideration", "use constant solid angle consideration"); parser.addArgument("outputCoeffs", "shc", mitkCommandLineParser::Bool, "Output coefficients", "output file containing the SH coefficients"); parser.addArgument("mrtrix", "mb", mitkCommandLineParser::Bool, "MRtrix", "use MRtrix compatible spherical harmonics definition"); - parser.setCategory("Preprocessing Tools"); + parser.setCategory("Signal Modelling"); parser.setTitle("Qball Reconstruction"); parser.setDescription(""); - parser.setContributor("MBI"); + parser.setContributor("MIC"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["input"]); std::string outfilename = us::any_cast(parsedArgs["outFile"]); outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename); int threshold = 0; if (parsedArgs.count("b0Threshold")) threshold = us::any_cast(parsedArgs["b0Threshold"]); int shOrder = 4; if (parsedArgs.count("shOrder")) shOrder = us::any_cast(parsedArgs["shOrder"]); float lambda = 0.006; if (parsedArgs.count("lambda")) lambda = us::any_cast(parsedArgs["lambda"]); int normalization = 0; if (parsedArgs.count("csa") && us::any_cast(parsedArgs["csa"])) normalization = 6; bool outCoeffs = false; if (parsedArgs.count("outputCoeffs")) outCoeffs = us::any_cast(parsedArgs["outputCoeffs"]); bool mrTrix = false; if (parsedArgs.count("mrtrix")) mrTrix = us::any_cast(parsedArgs["mrtrix"]); try { std::vector infile = mitk::IOUtil::Load(inFileName); Image::Pointer dwi = dynamic_cast(infile.at(0).GetPointer()); mitk::DiffusionPropertyHelper propertyHelper(dwi); propertyHelper.AverageRedundantGradients(0.001); propertyHelper.InitializeImage(); mitk::QBallImage::Pointer image = mitk::QBallImage::New(); mitk::Image::Pointer coeffsImage = mitk::Image::New(); std::cout << "SH order: " << shOrder; std::cout << "lambda: " << lambda; std::cout << "B0 threshold: " << threshold; switch ( shOrder ) { case 4: { typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetThreshold( threshold ); filter->SetLambda(lambda); filter->SetUseMrtrixBasis(mrTrix); if (normalization==0) filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); else filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); break; } case 6: { typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetThreshold( threshold ); filter->SetLambda(lambda); filter->SetUseMrtrixBasis(mrTrix); if (normalization==0) filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); else filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); break; } case 8: { typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetThreshold( threshold ); filter->SetLambda(lambda); filter->SetUseMrtrixBasis(mrTrix); if (normalization==0) filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); else filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); break; } case 10: { typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetThreshold( threshold ); filter->SetLambda(lambda); filter->SetUseMrtrixBasis(mrTrix); if (normalization==0) filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); else filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); break; } case 12: { typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetThreshold( threshold ); filter->SetLambda(lambda); if (normalization==0) filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); else filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); break; } default: { std::cout << "Supplied SH order not supported. Using default order of 4."; typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetThreshold( threshold ); filter->SetLambda(lambda); filter->SetUseMrtrixBasis(mrTrix); if (normalization==0) filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); else filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); } } std::string coeffout = outfilename; coeffout += "_shcoeffs.nrrd"; outfilename += ".qbi"; mitk::IOUtil::SaveBaseData(image, outfilename); if (outCoeffs) mitk::IOUtil::SaveImage(coeffsImage, coeffout); } catch ( itk::ExceptionObject &err) { std::cout << "Exception: " << err; } catch ( std::exception err) { std::cout << "Exception: " << err.what(); } catch ( ... ) { std::cout << "Exception!"; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/TensorDerivedMapsExtraction.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/TensorDerivedMapsExtraction.cpp similarity index 99% rename from Modules/DiffusionImaging/DiffusionCore/cmdapps/TensorDerivedMapsExtraction.cpp rename to Modules/DiffusionImaging/Quantification/cmdapps/TensorDerivedMapsExtraction.cpp index 1634e36e95..d2f4f0bd2b 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/TensorDerivedMapsExtraction.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/TensorDerivedMapsExtraction.cpp @@ -1,181 +1,181 @@ /*=================================================================== 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 "mitkImage.h" #include #include "mitkITKImageImport.h" #include #include #include #include #include #include "itkTensorDerivedMeasurementsFilter.h" #include "itkDiffusionTensor3DReconstructionImageFilter.h" #include "mitkCommandLineParser.h" #include #include #include using namespace std; typedef short DiffusionPixelType; typedef double TTensorPixelType; static void ExtractMapsAndSave(mitk::TensorImage::Pointer tensorImage, std::string filename, std::string postfix = "") { mitk::Image* image = dynamic_cast (tensorImage.GetPointer()); typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType; typedef itk::Image< TensorPixelType, 3 > TensorImageType; TensorImageType::Pointer itkvol = TensorImageType::New(); mitk::CastToItkImage(image, itkvol); typedef itk::TensorDerivedMeasurementsFilter MeasurementsType; MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); mitk::Image::Pointer map = mitk::Image::New(); // FA measurementsCalculator->SetMeasure(MeasurementsType::FA); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_FA" + postfix + ".nrrd"); // MD measurementsCalculator->SetMeasure(MeasurementsType::MD); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_MD" + postfix + ".nrrd"); // AD measurementsCalculator->SetMeasure(MeasurementsType::AD); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_AD" + postfix + ".nrrd"); // CA measurementsCalculator->SetMeasure(MeasurementsType::CA); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_CA" + postfix + ".nrrd"); // RA measurementsCalculator->SetMeasure(MeasurementsType::RA); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_RA" + postfix + ".nrrd"); // RD measurementsCalculator->SetMeasure(MeasurementsType::RD); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_RD" + postfix + ".nrrd"); } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("help", "h", mitkCommandLineParser::String, "Help", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input dwi file", us::Any(),false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output folder", "output folder and base name, e.g. /tmp/outPatient1 ", us::Any(),false); parser.setTitle("Tensor Derived Maps Extraction"); parser.setCategory("Diffusion Related Measures"); parser.setDescription(""); - parser.setContributor("MBI"); + parser.setContributor("MIC"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputFile = us::any_cast(parsedArgs["input"]); std::string baseFileName = us::any_cast(parsedArgs["out"]); std::string dtiFileName = "_dti.dti"; mitk::Image::Pointer diffusionImage = mitk::IOUtil::LoadImage(inputFile); if (diffusionImage.IsNull() || !mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(diffusionImage)) // does nullptr pointer check make sense after static cast ? { MITK_ERROR << "Invalid Input Image. Must be DWI. Aborting."; return -1; } typedef itk::DiffusionTensor3DReconstructionImageFilter< DiffusionPixelType, DiffusionPixelType, TTensorPixelType > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter = TensorReconstructionImageFilterType::New(); mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradientContainerCopy = mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::New(); for( mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::ConstIterator it = mitk::DiffusionPropertyHelper::GetGradientContainer(diffusionImage)->Begin(); it != mitk::DiffusionPropertyHelper::GetGradientContainer(diffusionImage)->End(); it++) { gradientContainerCopy->push_back(it.Value()); } mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(diffusionImage, itkVectorImagePointer); tensorReconstructionFilter->SetGradientImage( gradientContainerCopy, itkVectorImagePointer ); tensorReconstructionFilter->SetBValue( mitk::DiffusionPropertyHelper::GetReferenceBValue( diffusionImage ) ); tensorReconstructionFilter->SetThreshold(50); tensorReconstructionFilter->Update(); typedef itk::Image, 3> TensorImageType; TensorImageType::Pointer tensorImage = tensorReconstructionFilter->GetOutput(); tensorImage->SetDirection( itkVectorImagePointer->GetDirection() ); mitk::TensorImage::Pointer tensorImageMitk = mitk::TensorImage::New(); tensorImageMitk->InitializeByItk(tensorImage.GetPointer()); tensorImageMitk->SetVolume( tensorImage->GetBufferPointer() ); itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileType( itk::ImageIOBase::Binary ); io->UseCompressionOn(); itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< double >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< double >, 3 > >::New(); writer->SetInput(tensorReconstructionFilter->GetOutput()); writer->SetFileName(baseFileName + dtiFileName); writer->SetImageIO(io); writer->UseCompressionOn(); writer->Update(); ExtractMapsAndSave(tensorImageMitk,baseFileName); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/TensorReconstruction.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/TensorReconstruction.cpp similarity index 97% rename from Modules/DiffusionImaging/DiffusionCore/cmdapps/TensorReconstruction.cpp rename to Modules/DiffusionImaging/Quantification/cmdapps/TensorReconstruction.cpp index 63e0173f16..e30f0aa811 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/TensorReconstruction.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/TensorReconstruction.cpp @@ -1,101 +1,101 @@ /*=================================================================== 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 "mitkImage.h" #include #include "mitkBaseData.h" #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include using namespace mitk; using namespace std; /** * Convert files from one ending to the other */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false); parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false); parser.addArgument("b0Threshold", "t", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true); - parser.setCategory("Preprocessing Tools"); + parser.setCategory("Signal Modelling"); parser.setTitle("Tensor Reconstruction"); parser.setDescription(""); - parser.setContributor("MBI"); + parser.setContributor("MIC"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["input"]); std::string outfilename = us::any_cast(parsedArgs["outFile"]); outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename); outfilename += ".dti"; int threshold = 0; if (parsedArgs.count("b0Threshold")) threshold = us::any_cast(parsedArgs["b0Threshold"]); try { Image::Pointer dwi = IOUtil::LoadImage(inFileName); mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue( mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi )); filter->SetThreshold(threshold); filter->Update(); // Save tensor image itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileType( itk::ImageIOBase::Binary ); io->UseCompressionOn(); itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New(); writer->SetInput(filter->GetOutput()); writer->SetFileName(outfilename); writer->SetImageIO(io); writer->UseCompressionOn(); writer->Update(); } catch ( itk::ExceptionObject &err) { std::cout << "Exception: " << err; } catch ( std::exception err) { std::cout << "Exception: " << err.what(); } catch ( ... ) { std::cout << "Exception!"; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/cmdapps/Documentation/DiffusionMiniApps.dox b/Modules/DiffusionImaging/cmdapps/Documentation/DiffusionMiniApps.dox deleted file mode 100644 index a102a9a7e1..0000000000 --- a/Modules/DiffusionImaging/cmdapps/Documentation/DiffusionMiniApps.dox +++ /dev/null @@ -1,226 +0,0 @@ -/** -\page DiffusionMiniApps MITK Diffusion MiniApps - -\tableofcontents - -This page intends to provide an overview of all tools that are included with the current MITK Diffusion Installer and refer to the respective Plugin in the MITK Diffusion application (if one exists). -For a detailed list of parameters call the according tool without any arguments (see \ref MiniAppExplainPage for details on this) or refer its Plugin equivalent. - -\section Preprocessing Preprocessing Tools - - -\subsection DiffDicomLoad Diffusion Dicom Loader - -Loads Diffusion DICOM Files and creates NRRD or Nifty file. - - -\code - $./MitkDiffusionDICOMLoader -i /home/dcmFolder/ -o /home/outputfile.nrrd - $./MitkDiffusionDICOMLoader -i /home/dcmFolder/ -o /home/outputfile.nii -\endcode - - -\subsection RegDicomLoad Regular Dicom Loader - -Loads DICOM Files and creates NRRD or Nifty file. - -\code - $./MitkDicom2Nrrd -i /home/dcmFolder/ -o /home/outputfile.nrrd - $./MitkDicom2Nrrd -i /home/dcmFolder/ -o /home/outputfile.nii -\endcode - - - - -\subsection SecFolderRegistration Folder Registration - -Allows to register a series of images (of different modalities, including diffusion weighted) to one reference image. It allows to register derived resources (e.g. a segmentation on -a T2 image) using the transformation of the original (T2) image. - -For the following examples assume a folder containing a longitudinal study with T1,T2, DWI images and segmentations (ROI) : - -\code -Patien01_2010-1.dwi -Patien01_2010-1_T1.nrrd -Patien01_2010-1_T2.nrrd -Patien01_2010-1_ROI.nrrd -Patien01_2010-2.dwi -Patien01_2010-2_T1.nrrd -Patien01_2010-2_T2.nrrd -Patien01_2010-2_ROI.nrrd -Patien01_2010-3.dwi -Patien01_2010-3_T1.nrrd -Patien01_2010-3_T2.nrrd -Patien01_2010-3_ROI.nrrd -Patien01_2010-4.dwi -Patien01_2010-4_T1.nrrd -Patien01_2010-4_T2.nrrd -Patien01_2010-4_ROI.nrrd -\endcode - -All T2 and DWI images are to be co-registered to the first T2 image, this can be achieved by the following two calls: - -\code - $./MitkRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m T2.nrrd - $./MitkRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m .dwi -\endcode - -The segmentations where performed on the T1 image and are therefore related to the image space of the respective T1 image, -so they can be bound to these images by marking them as derived resources. To register them both you would call - -\code - $./MitkFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m _T1.nrrd -d _ROI.nrrd -b -\endcode - -\note the suffixes of '_T1.nrrd' and '_ROI.nrrd' must have the same length! - -The parameter -b designates the derived resource as binary such that a nearest neighbor interpolation is used. - -All images (execpt for DWI files) are resample to the reference image, to resample to a specific spacing append the desired -spacing like this (e.g. 1 x 1 x 2 mm) - -\code - $./MitkFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m .dwi -r 1,1,2 -\endcode - -\note Registration methods assume that both images occupy roughly the same space. It may happend that this is not the case, -and therefore registration fails. In this case you can try the -c option which uses the same origin for both images. - - -\subsection CopyGeometry Copy Geometry - -Copies the geometry (origin) of the source image to the target image. -This is useful in cases where rounding errors in geometries cause the following itk error: -itk::ERROR: ImageToImageFilter(): Inputs do not occupy the same physical space! - -For images with differing extent the --alignCentroid option will adapt the origin of the input image such that the centroids of both images align, -this can be as a preprocessing steo for registratering images that do not overlap at all -(e.g. error : Joint PDF summed to zero ) - - -\subsection ImageResampler Resampling of Images - -This tool can be used to resample images in different ways. One way is by specifying the spacing. -Transforming an image test.nrrd to have a spacing of 1x1x3 mm can be done using this command: - -\code - $./MitkImageResampler -i test.nrrd -s 1,1,3 -o resampledImage.nrrd -\endcode - -Alternatively this program can be used to resample by reference. This will resample the input image to the grid provided by the reference image -and also ensure they occupy the same physical space (that is the input image will have the same origin and voxel dimensions) - -\code - $./MitkImageResampler -i test.nrrd -r referenceImage.nrrd -o resampledImage.nrrd -\endcode - -\note Resampling by reference image can also be applied to MR Diffusion data (.dwi files). - - - -\subsection TensorRecon Tensor Reconstruction -See \ref QmitkDiffusionImagingUserManualTensorReconstruction for the GUI equivalent of this tool. - -Takes a .dwi, .fsl/.fslgz file as input and saves the computed reconstructed tensor to the specified file. -It also allows for a threshold to be set, to exclude low b values from the reconstruction process. - -\code -$./MitkTensorReconstruction -i /home/user/sample.dwi -o /home/user/tensors.dti -t 50 -\endcode - -\subsection QballRecon Qball Reconstruction - -See \ref QmitkDiffusionImagingUserManualQBallReconstruction for the GUI equivalent of this tool. - -\code -./MitkQballReconstruction -i /home/user/sample.dwi -o /home/user/tensors.qbi -t 50 -r .006 -shc /home/user/coeffs.csv -\endcode - -\subsection PeakExtraction Peak Extraction - -Extracts ODF peaks from the given spherical harmonics coefficient image. Input image type is an image that contains a vector with the spherical harmonics coefficients as pixel type: Image< Vector< float, (ShOrder*ShOrder + ShOrder + 2)/2 + ShOrder >, 3 > - -\subsection PeakAngularErr Peak Angular Error - -Calculates the angular error between two sets of input directions. The directions are stored as images. Each image voxel contains one direction vector. Such images are for example the output of the fiber direction extraction miniapp. - -\section DiffusionMeasures Diffusion Related Measures - -\subsection DiffusionIndices Diffusion Indices - -See \ref QmitkDiffusionImagingUserManualQuantification for the GUI equivalent of this tool. - -Computes a selected tensor derived indices (fa, gfa, ra, ad, rd, ca, l2, l3, md) given a -Tensor, Q-ball or FSL/MRTrix SH-coefficient image. E.g. to compute the fraction anisotropy call - -\code -./MitkDiffusionIndices -i /home/user/input.dti -idx fa -o /home/user/fa_image.nrrd -\endcode - -\subsection AllDiffusionIndices Tensor Derived Maps Extraction - -Similar to \ref DiffusionIndices . But computes all of the following indices FA, RA, MD, CA, RD, AD at once. -Also the input is a regular .dwi file, the tensor reconstruction is done implicitly (using a b0 threshold of 50). - -\section FibTracking Fiber Tracking and Processing Methods - -\subsection FibDirection Fiber Direction Extraction - -Extracts the voxel-wise main fiber directions from a tractogram. - -\subsection Streamline Streamline Tracking - -See \ref org_mitk_views_streamlinetracking for the GUI equivalent of this tool. - -Performs streamline tractography on a tensor image. - -\subsection GibbsTracking Gibbs Fiber Tracking - -See \ref org_mitk_views_gibbstracking for the GUI equivalent of this tool. - -Performs global Gibbs tractography on a tensor/Q-ball/SH-coefficient image. - -\subsection FibProcessing Fiber Processing - -Post-process a fiber bundle. Provides the possibility to - -\li remove short/long fiber tracks -\li apply curvature threshold -\li resample a fiber bundle (linear and spline based) -\li compress a fiber bundle (lossy) -\li transform fiber bundle (scale, translate, rotate) -\li mirror fiber bundle - - -\subsection FibFoxProcessing Fiberfox - -See \ref QmitkFiberfoxViewUserManualSignalGeneration for the GUI equivalent of this tool. - -Generates a signal from a fiber bundle provided a reference DWI and a parameter file. The parameter file can be generated -using the Fiberfox plugin (sub-tab) Signal Generation. - -\subsection FormatConv File Format Converter - -Determines the data type and converts the input file (if possible) to .NRRD (regular image), -.DWI (diffusion image) or .FIB (fiber bundle). - -\subsection MultiShell Multishell Methods - -Computes several fits on an images (Kurtosis,Bi-Exponential, ADC). - -These fits are part of the Preprocessing Plugin \ref QmitkDiffusionImagingUserManualPreprocessing . - -\section NetworkTools Connectomics - -\subsection NetworkCreation Network Creation - -See \ref org_mitk_views_connectomicsdata for the GUI equivalent of this tool. - -Creates a network based on a brain parcellation and a fiber image. - -\subsection NetworkStatistics Network Statistics - -See \ref org_mitk_views_connectomicsstatistics for the GUI equivalent of this tool. - -Calculates several network statistics for a given connectome. -*/ diff --git a/Modules/DiffusionImaging/cmdapps/ExtractImageStatistics.cpp b/Modules/DiffusionImaging/cmdapps/ExtractImageStatistics.cpp deleted file mode 100644 index 91e5549533..0000000000 --- a/Modules/DiffusionImaging/cmdapps/ExtractImageStatistics.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/*=================================================================== - - 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 "MiniAppManager.h" - -//#include "ctkCommandLineParser.h" -#include "mitkCommandLineParser.cpp" -#include "mitkImage.h" -#include "mitkImageStatisticsCalculator.h" -#include "mitkIOUtil.h" -#include -#include -#include - -int ExtractImageStatistics(int argc, char* argv[]) -{ - mitkCommandLineParser parser; - - parser.setTitle("Extract Image Statistics"); - parser.setCategory("Preprocessing Tools"); - parser.setDescription(""); - parser.setContributor("MBI"); - - parser.setArgumentPrefix("--", "-"); - parser.addArgument("help", "h", mitkCommandLineParser::String, "Help:", "Show this help text"); - parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(),false); - parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image / roi image denotin area on which statistics are calculated", us::Any(),false); - parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output", "output file (default: filenameOfRoi.nrrd_statistics.txt)", us::Any()); - - map parsedArgs = parser.parseArguments(argc, argv); - if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")) - { - std::cout << "\n\n MiniApp Description: \nCalculates statistics on the supplied image using given mask." << endl; - std::cout << "Output is written to the designated output file in this order:" << endl; - std::cout << "Mean, Standard Deviation, RMS, Max, Min, Number of Voxels, Volume [mm3]" << endl; - std::cout << "\n\n Parameters:"<< endl; - std::cout << parser.helpText(); - return EXIT_SUCCESS; - } - - - // Parameters: - bool ignoreZeroValues = false; - unsigned int timeStep = 0; - - std::string inputImageFile = us::any_cast(parsedArgs["input"]); - std::string maskImageFile = us::any_cast(parsedArgs["mask"]); - - std::string outFile; - if (parsedArgs.count("out") || parsedArgs.count("o") ) - outFile = us::any_cast(parsedArgs["out"]); - else - outFile = inputImageFile + "_statistics.txt"; - - // Load image and mask - mitk::Image::Pointer maskImage = mitk::IOUtil::LoadImage(maskImageFile); - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile); - - // Calculate statistics - mitk::ImageStatisticsCalculator::Statistics statisticsStruct; - mitk::ImageStatisticsCalculator::Pointer calculator = mitk::ImageStatisticsCalculator::New(); - try - { - calculator->SetImage(inputImage); - calculator->SetImageMask(maskImage); - calculator->SetMaskingModeToImage(); - } - catch( const itk::ExceptionObject& e) - { - MITK_ERROR << "Statistic Calculation Failed - ITK Exception:" << e.what(); - return -1; - } - - - calculator->SetDoIgnorePixelValue(ignoreZeroValues); - calculator->SetIgnorePixelValue(0); - try - { - calculator->ComputeStatistics(timeStep); - } - catch ( mitk::Exception& e) - { - MITK_ERROR<< "MITK Exception: " << e.what(); - return -1; - } - - - statisticsStruct = calculator->GetStatistics(timeStep); - - - // Calculate Volume - double volume = 0; - const mitk::BaseGeometry *geometry = inputImage->GetGeometry(); - if ( geometry != nullptr ) - { - const mitk::Vector3D &spacing = inputImage->GetGeometry()->GetSpacing(); - volume = spacing[0] * spacing[1] * spacing[2] * (double) statisticsStruct.GetN(); - } - - // Write Results to file - std::ofstream output; - output.open(outFile.c_str()); - output << statisticsStruct.GetMean() << " , "; - output << statisticsStruct.GetSigma() << " , "; - output << statisticsStruct.GetRMS() << " , "; - output << statisticsStruct.GetMax() << " , "; - output << statisticsStruct.GetMin() << " , "; - output << statisticsStruct.GetN() << " , "; - output << volume << "\n"; - - output.flush(); - output.close(); - return 0; -} - -RegisterDiffusionMiniApp(ExtractImageStatistics); diff --git a/Modules/DiffusionImaging/cmdapps/HotspotMiniApp.cpp b/Modules/DiffusionImaging/cmdapps/HotspotMiniApp.cpp deleted file mode 100644 index 3dae227d76..0000000000 --- a/Modules/DiffusionImaging/cmdapps/HotspotMiniApp.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/*=================================================================== - -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 "mitkCommandLineParser.h" -#include "mitkImage.h" -#include "mitkIOUtil.h" -#include -#include -#include -#include - - -int main( int argc, char* argv[] ) -{ - mitkCommandLineParser parser; - - parser.setTitle("Test basic hotspot functionality"); - parser.setCategory("Preprocessing Tools"); - parser.setDescription(""); - parser.setContributor("MBI"); - - parser.setArgumentPrefix("--", "-"); - parser.addArgument("help", "h", mitkCommandLineParser::String, "Help:", "Show this help text"); - parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(),false); - parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image / roi image denotin area on which statistics are calculated", us::Any(),true); - parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output", "output file (default: hotspotMiniApp_output.nrrd)", us::Any()); - - std::cout << "test...." << std::endl; - - std::map parsedArgs = parser.parseArguments(argc, argv); - std::cout << "parsedArgs.size()= " << parsedArgs.size() << std::endl; - if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")) - { -// std::cout << "\n\n MiniApp Description: \nCalculates and saves the hotspot of an image." << endl; -// std::cout << "Output is written to the designated output file" << endl; -// std::cout << parser.helpText(); -// return EXIT_SUCCESS; - } - - // Parameters: - std::string inputImageFile; - if (!parsedArgs.count("i") && !parsedArgs.count("input")) - { - inputImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D.nrrd"; - } - else - { - inputImageFile = us::any_cast(parsedArgs["input"]); - } - - mitk::Image::Pointer maskImage; - if (parsedArgs.count("mask") || parsedArgs.count("m")) - { - std::string maskImageFile = us::any_cast(parsedArgs["mask"]); - maskImage = mitk::IOUtil::LoadImage(maskImageFile); - } - - std::string outFile; - if (parsedArgs.count("out") || parsedArgs.count("o") ) - outFile = us::any_cast(parsedArgs["out"]); - else - outFile = "hotspotMiniApp_output.nrrd"; - - // Load image and mask - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile); - - // Calculate statistics - mitk::HotspotMaskGenerator::Pointer hotspotCalc = mitk::HotspotMaskGenerator::New(); - hotspotCalc->SetInputImage(inputImage); - hotspotCalc->SetHotspotRadiusInMM(10); - hotspotCalc->SetTimeStep(0); - mitk::Image::Pointer outImage; - try - { - outImage = hotspotCalc->GetMask(); - } - catch( const itk::ExceptionObject& e) - { - MITK_ERROR << "Failed - ITK Exception:" << e.what(); - return -1; - } - - if (outImage != nullptr) - { - mitk::IOUtil::SaveImage(outImage, outFile); - } - - - return EXIT_SUCCESS; -} diff --git a/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniApp.cpp b/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniApp.cpp deleted file mode 100644 index 0c0ae955ba..0000000000 --- a/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniApp.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/*=================================================================== - -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 "mitkCommandLineParser.h" -#include "mitkImage.h" -#include "mitkImageStatisticsCalculator.h" -#include "mitkIOUtil.h" -#include -#include -#include -#include -#include "mitkImageAccessByItk.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct statistics_res{ - double mean, variance, min, max, count, moment; -}; - -void printstats(statistics_res s) -{ - std::cout << "mean: " << s.mean << std::endl - << "variance: " << s.variance << std::endl - << "min: " << s.min << std::endl - << "max: " << s.max << std::endl - << "count: " << s.count << std::endl - << "moment: " << s.moment << std::endl; -} - -template < typename TPixel, unsigned int VImageDimension > -void get_statistics_boost(itk::Image* itkImage, statistics_res& res){ - typedef itk::Image ImageType; - - itk::ImageRegionConstIterator it(itkImage, itkImage->GetLargestPossibleRegion()); - - TPixel currentPixel; - int ctr=0; - double sum=0; - - boost::accumulators::accumulator_set> > acc; - - for (it.GoToBegin(); !it.IsAtEnd(); ++it) - { - acc(it.Get()); -// currentPixel = it.Get(); -// sum+=currentPixel; -// ctr+=1; - } - -// res.mean=(double)sum/(double)ctr; - res.mean = boost::accumulators::mean(acc); - res.variance = boost::accumulators::variance(acc); - res.min = boost::accumulators::min(acc); - res.max = boost::accumulators::max(acc); - res.count = boost::accumulators::count(acc); - res.moment = boost::accumulators::moment<2>(acc); - - std::cout << "sum: " << sum << " N: " << ctr << " mean: " << res.mean << std::endl; -} - -int main( int argc, char* argv[] ) -{ - mitkCommandLineParser parser; - - parser.setTitle("Extract Image Statistics"); - parser.setCategory("Preprocessing Tools"); - parser.setDescription(""); - parser.setContributor("MBI"); - - parser.setArgumentPrefix("--", "-"); - parser.addArgument("help", "h", mitkCommandLineParser::String, "Help:", "Show this help text"); - parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(),false); - parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image / roi image denotin area on which statistics are calculated", us::Any(),true); - parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output", "output file (default: filenameOfRoi.nrrd_statistics.txt)", us::Any()); - - std::cout << "test...." << std::endl; - - std::map parsedArgs = parser.parseArguments(argc, argv); - std::cout << "parsedArgs.size()= " << parsedArgs.size() << std::endl; - if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")) - { - std::cout << "\n\n MiniApp Description: \nCalculates statistics on the supplied image using given mask." << endl; - std::cout << "Output is written to the designated output file in this order:" << endl; - std::cout << "Mean, Standard Deviation, RMS, Max, Min, Number of Voxels, Volume [mm3]" << endl; - std::cout << "\n\n Parameters:"<< endl; - std::cout << parser.helpText(); - return EXIT_SUCCESS; - } - - - // Parameters: - bool ignoreZeroValues = false; - unsigned int timeStep = 0; - - std::string inputImageFile = us::any_cast(parsedArgs["input"]); - mitk::Image::Pointer maskImage; - if (parsedArgs.count("mask") || parsedArgs.count("m")) - { - std::string maskImageFile = us::any_cast(parsedArgs["mask"]); - maskImage = mitk::IOUtil::LoadImage(maskImageFile); - } - - std::string outFile; - if (parsedArgs.count("out") || parsedArgs.count("o") ) - outFile = us::any_cast(parsedArgs["out"]); - else - outFile = inputImageFile + "_statistics.txt"; - - // Load image and mask - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile); - - // Calculate statistics - mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer statisticsStruct; - mitk::ImageStatisticsCalculator::Pointer calculator = mitk::ImageStatisticsCalculator::New(); - try - { - calculator->SetInputImage(inputImage); - if (parsedArgs.count("mask") || parsedArgs.count("m")) - { - mitk::ImageMaskGenerator::Pointer imgMask = mitk::ImageMaskGenerator::New(); - imgMask->SetImageMask(maskImage); - imgMask->SetTimeStep(timeStep); - calculator->SetMask(imgMask.GetPointer()); - } - else - { - calculator->SetMask(nullptr); - } - - } - catch( const itk::ExceptionObject& e) - { - MITK_ERROR << "Statistic Calculation Failed - ITK Exception:" << e.what(); - return -1; - } - - - if (ignoreZeroValues) - { - // TODO, cannot have more than one mask, using ignore pixel value will override the image mask :-c - mitk::IgnorePixelMaskGenerator::Pointer ignorePixelMask = mitk::IgnorePixelMaskGenerator::New(); - ignorePixelMask->SetInputImage(inputImage); - ignorePixelMask->SetTimeStep(timeStep); - ignorePixelMask->SetIgnoredPixelValue(0); - calculator->SetMask(ignorePixelMask.GetPointer()); - } - - std::cout << "calculating statistics itk: " << std::endl; - try - { - statisticsStruct = calculator->GetStatistics(timeStep); - } - catch ( mitk::Exception& e) - { - MITK_ERROR<< "MITK Exception: " << e.what(); - return -1; - } - - - // Calculate Volume - double volume = 0; - const mitk::BaseGeometry *geometry = inputImage->GetGeometry(); - if ( geometry != nullptr ) - { - const mitk::Vector3D &spacing = inputImage->GetGeometry()->GetSpacing(); - volume = spacing[0] * spacing[1] * spacing[2] * (double) statisticsStruct->GetN(); - } - - // Write Results to file - std::ofstream output; - output.open(outFile.c_str()); - output << statisticsStruct->GetMean() << " , "; - output << statisticsStruct->GetStd() << " , "; - output << statisticsStruct->GetRMS() << " , "; - output << statisticsStruct->GetMax() << " , "; - output << statisticsStruct->GetMin() << " , "; - output << statisticsStruct->GetN() << " , "; - output << volume << "\n"; - - output.flush(); - output.close(); - - std::cout << "calculating statistics boost: " << std::endl; - - statistics_res res; - AccessByItk_n(inputImage, get_statistics_boost, (res)); - - printstats(res); - - return EXIT_SUCCESS; -} diff --git a/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniapp_3.cpp b/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniapp_3.cpp deleted file mode 100644 index ed343d9861..0000000000 --- a/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniapp_3.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*=================================================================== - -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 "mitkCommandLineParser.h" -#include "mitkImage.h" -#include -#include -#include -#include -#include "mitkIOUtil.h" -#include -#include -#include -#include -#include "mitkImageAccessByItk.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int main( int argc, char* argv[] ) -{ - unsigned int timeStep = 0; - std::string inputImageFile, maskImageFile; - inputImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D.nrrd"; - maskImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_someSegmentation.nrrd"; - // Load image - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile); - mitk::Image::Pointer maskImage = mitk::IOUtil::LoadImage(maskImageFile); - - - // Calculate statistics - mitk::ImageStatisticsCalculator::Pointer calculator = mitk::ImageStatisticsCalculator::New(); - - std::cout << "calculating statistics (unmasked) itk: " << std::endl; - mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result; - - mitk::ImageMaskGenerator::Pointer imgMaskGen = mitk::ImageMaskGenerator::New(); - imgMaskGen->SetImageMask(maskImage); - - calculator->SetMask(imgMaskGen.GetPointer()); - calculator->SetInputImage(inputImage); - calculator->SetNBinsForHistogramStatistics(100); - - for (unsigned int i=0; i < inputImage->GetTimeSteps(); i++) - { - std::cout << "Results for time step " << i << ":" << std::endl; - result = calculator->GetStatistics(i, 1); - result->Print(); - std::cout << std::endl; - } - MITK_INFO << "-------------"; - mitk::Image::Pointer test = imgMaskGen->GetMask(); - MITK_INFO << "-------------"; - - mitk::Image::Pointer test2 = imgMaskGen->GetMask(); - MITK_INFO << "-------------"; - imgMaskGen->SetTimeStep(2); - mitk::Image::Pointer test3 = imgMaskGen->GetMask(); - - - return EXIT_SUCCESS; -} diff --git a/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniapp_v2.cpp b/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniapp_v2.cpp deleted file mode 100644 index a81d680524..0000000000 --- a/Modules/DiffusionImaging/cmdapps/ImageStatisticsMiniapp_v2.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/*=================================================================== - -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 "mitkCommandLineParser.h" -#include "mitkImage.h" -#include -#include -#include -#include -#include "mitkIOUtil.h" -#include -#include -#include -#include -#include "mitkImageAccessByItk.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -struct statistics_res{ - double mean, variance, min, max, count, moment; -}; - -long getTimeInMs() -{ - std::chrono::milliseconds ms = std::chrono::duration_cast< std::chrono::milliseconds > (std::chrono::system_clock::now().time_since_epoch()); - long time = ms.count(); - return time; -} - -//std::string printstats(mitk::ImageStatisticsCalculator::Statistics statisticsStruct) -//{ -// std::string res = ""; -// res += std::string("Entropy ") + std::to_string(statisticsStruct.GetEntropy()) + std::string("\n"); -// res += std::string("Kurtosis ") + std::to_string(statisticsStruct.GetKurtosis()) + std::string("\n"); -// res += std::string("MPP ") + std::to_string(statisticsStruct.GetMPP()) + std::string("\n"); -// res += std::string("Max ") + std::to_string(statisticsStruct.GetMax()) + std::string("\n"); -// res += std::string("Mean ") + std::to_string(statisticsStruct.GetMean()) + std::string("\n"); -// res += std::string("Median ") + std::to_string(statisticsStruct.GetMedian()) + std::string("\n"); -// res += std::string("Min ") + std::to_string(statisticsStruct.GetMin()) + std::string("\n"); -// res += std::string("N ") + std::to_string(statisticsStruct.GetN()) + std::string("\n"); -// res += std::string("RMS ") + std::to_string(statisticsStruct.GetRMS()) + std::string("\n"); -// res += std::string("Skewness ") + std::to_string(statisticsStruct.GetSkewness()) + std::string("\n"); -// res += std::string("Std ") + std::to_string(statisticsStruct.GetSigma()) + std::string("\n"); -// res += std::string("UPP ") + std::to_string(statisticsStruct.GetUPP()) + std::string("\n"); -// res += std::string("Uniformity ") + std::to_string(statisticsStruct.GetUniformity()) + std::string("\n"); -// res += std::string("Variance ") + std::to_string(statisticsStruct.GetVariance()) + std::string("\n"); -// vnl_vector minIndex = statisticsStruct.GetMinIndex(); -// vnl_vector maxIndex = statisticsStruct.GetMaxIndex(); - -// res += "Min Index: "; -// for (auto it = minIndex.begin(); it != minIndex.end(); it++) -// { -// res += std::to_string(*it) + " "; -// } -// res += std::string("\n"); - -// res += "Max Index: "; -// for (auto it = maxIndex.begin(); it != maxIndex.end(); it++) -// { -// res += std::to_string(*it) + " "; -// } -// res += std::string("\n"); -// return res; -//} - -template -void printMap(std::map input) -{ - for (auto it = input.begin(); it != input.end(); ++it) - { - std::cout << it->first<< ": " << it->second<< std::endl; - } - std::cout << std::endl; -} - -template < typename TPixel, unsigned int VImageDimension > -void get_statistics_boost(itk::Image* itkImage, statistics_res& res){ - typedef itk::Image ImageType; - - itk::ImageRegionConstIterator it(itkImage, itkImage->GetLargestPossibleRegion()); - - int ctr=0; - double sum=0; - - boost::accumulators::accumulator_set> > acc; - - for (it.GoToBegin(); !it.IsAtEnd(); ++it) - { - acc(it.Get()); -// currentPixel = it.Get(); -// sum+=currentPixel; -// ctr+=1; - } - -// res.mean=(double)sum/(double)ctr; - res.mean = boost::accumulators::mean(acc); - res.variance = boost::accumulators::variance(acc); - res.min = boost::accumulators::min(acc); - res.max = boost::accumulators::max(acc); - res.count = boost::accumulators::count(acc); - res.moment = boost::accumulators::moment<2>(acc); - - std::cout << "sum: " << sum << " N: " << ctr << " mean: " << res.mean << std::endl; -} - -void compute_statistics(std::string inputImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D.nrrd", - std::string outfname = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_statistics_new.txt", - std::string outfname2 = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_statistics_old.txt", - std::string maskImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_someSegmentation.nrrd", - std::string pFfile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_rectangle.pf" ) -{ - ofstream outFile; - outFile.open(outfname); - - unsigned int timeStep = 0; - - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile); - - mitk::Image::Pointer maskImage; - maskImage = mitk::IOUtil::LoadImage(maskImageFile); - - std::vector loadedObjects; - loadedObjects = mitk::IOUtil::Load(pFfile); - mitk::BaseData::Pointer pf = loadedObjects[0]; - mitk::PlanarFigure::Pointer planarFigure = dynamic_cast(pf.GetPointer()); - - mitk::ImageStatisticsCalculator::Pointer calculator = mitk::ImageStatisticsCalculator::New(); - mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result; - calculator->SetInputImage(inputImage); - calculator->SetNBinsForHistogramStatistics(100); - - long start_time; - - outFile << "Calculating Statistics on Pic3D" << std::endl << std::endl; - - outFile << "New Image Statistics Calculator" << std::endl; - - start_time = getTimeInMs(); - outFile << "1) unmasked: " << std::endl; - calculator->SetMask(nullptr); - result = calculator->GetStatistics(timeStep); - outFile << result->GetAsString() << std::endl; - outFile << "new image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - - start_time = getTimeInMs(); - outFile << "2) planarfigure: " << std::endl; - mitk::PlanarFigureMaskGenerator::Pointer planarFigMaskExtr = mitk::PlanarFigureMaskGenerator::New(); - planarFigMaskExtr->SetPlanarFigure(planarFigure); - planarFigMaskExtr->SetInputImage(inputImage); - calculator->SetMask(planarFigMaskExtr.GetPointer()); - result = calculator->GetStatistics(timeStep, 1); - outFile << result->GetAsString() << std::endl; - outFile << "new image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - - start_time = getTimeInMs(); - outFile << "3) ignore pixel value mask: " << std::endl; - mitk::IgnorePixelMaskGenerator::Pointer ignPixVal = mitk::IgnorePixelMaskGenerator::New(); - ignPixVal->SetInputImage(inputImage); - ignPixVal->SetIgnoredPixelValue(0); - calculator->SetMask(ignPixVal.GetPointer()); - result = calculator->GetStatistics(timeStep, 1); - outFile << result->GetAsString() << std::endl; - outFile << "new image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - - start_time = getTimeInMs(); - outFile << "4) image mask: " << std::endl; - mitk::ImageMaskGenerator::Pointer binaryImageMaskGen = mitk::ImageMaskGenerator::New(); - binaryImageMaskGen->SetImageMask(maskImage); - calculator->SetMask(binaryImageMaskGen.GetPointer()); - result = calculator->GetStatistics(timeStep, 1); - outFile << result->GetAsString() << std::endl; - outFile << "new image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - - start_time = getTimeInMs(); - outFile << "5) hotspot mask: " << std::endl; - mitk::HotspotMaskGenerator::Pointer hotSpotMaskGen = mitk::HotspotMaskGenerator::New(); - hotSpotMaskGen->SetInputImage(inputImage); - hotSpotMaskGen->SetHotspotRadiusInMM(10); - hotSpotMaskGen->SetTimeStep(0); - calculator->SetMask(hotSpotMaskGen.GetPointer()); - result = calculator->GetStatistics(timeStep, 1); - outFile << result->GetAsString() << std::endl; - outFile << "new image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - //mitk::IOUtil::SaveImage(hotSpotMaskGen->GetMask(), "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic2DplusTHotspot.nrrd"); - - outFile << "6) all time steps (image mask): " << std::endl; - if (inputImage->GetTimeSteps() > 1) - { - start_time = getTimeInMs(); - for (unsigned int i=0; i < inputImage->GetTimeSteps(); i++) - { - outFile << "timestep: " << i << std::endl; - calculator->SetMask(binaryImageMaskGen.GetPointer()); - result = calculator->GetStatistics(i, 1); - outFile << result->GetAsString() << std::endl; - outFile << "new image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - } - } - else - { - outFile << "Input image has only 1 time step!" << std::endl; - } - - outFile.flush(); - outFile.close(); - - // ----------------------------------------------------------------------------------------------------------------------------------------------------------- -// outFile.open(outfname2); - -// std::cout << std::endl << std::endl << "calculating statistics old imgstatcalc: " << std::endl; -// mitk::ImageStatisticsCalculator::Statistics statisticsStruct; -// mitk::ImageStatisticsCalculator::Pointer calculator_old; - - - -// start_time = getTimeInMs(); -// outFile << "1) unmasked: " << std::endl; -// calculator_old = mitk::ImageStatisticsCalculator::New(); -// calculator_old->SetHistogramBinSize(100); -// calculator_old->SetImage(inputImage); -// calculator_old->SetMaskingModeToNone(); -// calculator_old->ComputeStatistics(timeStep); -// statisticsStruct = calculator_old->GetStatistics(timeStep); -// outFile << printstats(statisticsStruct) << std::endl; -// outFile << "old image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - -// start_time = getTimeInMs(); -// outFile << "2) planarFigure: " << std::endl; -// calculator_old = mitk::ImageStatisticsCalculator::New(); -// calculator_old->SetHistogramBinSize(100); -// calculator_old->SetImage(inputImage); -// calculator_old->SetPlanarFigure(planarFigure); -// calculator_old->SetMaskingModeToPlanarFigure(); -// calculator_old->ComputeStatistics(timeStep); -// statisticsStruct = calculator_old->GetStatistics(timeStep); -// outFile << printstats(statisticsStruct) << std::endl; -// outFile << "old image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - -// start_time = getTimeInMs(); -// outFile << "3) IgnorePixelValue: " << std::endl; -// calculator_old = mitk::ImageStatisticsCalculator::New(); -// calculator_old->SetHistogramBinSize(100); -// calculator_old->SetImage(inputImage); -// calculator_old->SetMaskingModeToNone(); -// calculator_old->SetDoIgnorePixelValue(true); -// calculator_old->SetIgnorePixelValue(0); -// calculator_old->ComputeStatistics(timeStep); -// statisticsStruct = calculator_old->GetStatistics(timeStep); -// outFile << printstats(statisticsStruct) << std::endl; -// outFile << "old image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; -// calculator_old->SetDoIgnorePixelValue(false); - -// start_time = getTimeInMs(); -// outFile << "4) Image Mask: " << std::endl; -// calculator_old = mitk::ImageStatisticsCalculator::New(); -// calculator_old->SetHistogramBinSize(100); -// calculator_old->SetImage(inputImage); -// calculator_old->SetImageMask(maskImage); -// calculator_old->SetMaskingModeToImage(); -// calculator_old->ComputeStatistics(timeStep); -// statisticsStruct = calculator_old->GetStatistics(timeStep); -// outFile << printstats(statisticsStruct) << std::endl; -// outFile << "old image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; - -// start_time = getTimeInMs(); -// outFile << "5) Hotspot Mask: " << std::endl; -// calculator_old = mitk::ImageStatisticsCalculator::New(); -// calculator_old->SetHistogramBinSize(100); -// calculator_old->SetImage(inputImage); -// calculator_old->SetMaskingModeToNone(); -// calculator_old->SetCalculateHotspot(true); -// calculator_old->SetHotspotRadiusInMM(10); -// calculator_old->ComputeStatistics(timeStep); -// statisticsStruct = calculator_old->GetStatistics(timeStep).GetHotspotStatistics(); -// outFile << printstats(statisticsStruct) << std::endl; -// outFile << "old image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; -// calculator_old->SetCalculateHotspot(false); - -// outFile << "6) all time steps (image mask): " << std::endl; -// if (inputImage->GetTimeSteps() > 1) -// { -// start_time = getTimeInMs(); -// calculator_old = mitk::ImageStatisticsCalculator::New(); -// calculator_old->SetHistogramBinSize(100); -// calculator_old->SetImage(inputImage); -// calculator_old->SetImageMask(maskImage); -// calculator_old->SetMaskingModeToImage(); -// for (unsigned int i=0; i < inputImage->GetTimeSteps(); i++) -// { -// calculator_old->ComputeStatistics(i); -// statisticsStruct = calculator_old->GetStatistics(i); -// outFile << printstats(statisticsStruct) << std::endl; -// outFile << "old image statistics calculator took: " << getTimeInMs()-start_time << " ms." << std::endl << std::endl; -// } -// } -// else -// { -// outFile << "Input image has only 1 time step!" << std::endl; -// } - -// outFile.flush(); -// outFile.close(); -} - -int main( int argc, char* argv[] ) -{ - std::string inputImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D.nrrd"; - std::string outfname = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_statistics_new.txt"; - std::string outfname2 = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_statistics_old.txt"; - std::string maskImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_someSegmentation.nrrd"; - std::string pFfile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_rectangle.pf"; - compute_statistics(inputImageFile, outfname, outfname2, maskImageFile, pFfile); - - inputImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic2DplusT.nrrd"; - outfname = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic2DplusT_statistics_new.txt"; - outfname2 = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic2DplusT_statistics_old.txt"; - maskImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic2DplusT_someSegmentation.nrrd"; - pFfile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic2DplusT_ellipse.pf"; - compute_statistics(inputImageFile, outfname, outfname2, maskImageFile, pFfile); - - inputImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/leber_ct.pic"; - outfname = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/leber_ct_statistics_new.txt"; - outfname2 = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/leber_ct_statistics_old.txt"; - maskImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/leber_ct_segmentation.nrrd"; - pFfile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/leber_ct_PF.pf"; - compute_statistics(inputImageFile, outfname, outfname2, maskImageFile, pFfile); - - - return EXIT_SUCCESS; -} diff --git a/Modules/DiffusionImaging/cmdapps/PlanarFigureMaskCreatorMiniapp.cpp b/Modules/DiffusionImaging/cmdapps/PlanarFigureMaskCreatorMiniapp.cpp deleted file mode 100644 index ec163dc9e1..0000000000 --- a/Modules/DiffusionImaging/cmdapps/PlanarFigureMaskCreatorMiniapp.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*=================================================================== - -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 "mitkCommandLineParser.h" -#include "mitkImage.h" -#include "mitkIOUtil.h" -#include -#include -#include -#include -#include -#include - - -int main( int argc, char* argv[] ) -{ - mitkCommandLineParser parser; - - parser.setTitle("Test basic hotspot functionality"); - parser.setCategory("Preprocessing Tools"); - parser.setDescription(""); - parser.setContributor("MBI"); - - parser.setArgumentPrefix("--", "-"); - parser.addArgument("help", "h", mitkCommandLineParser::String, "Help:", "Show this help text"); - parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(),false); - parser.addArgument("planarfigure", "p", mitkCommandLineParser::InputFile, "PlanarFigure:", "mask image / roi image denotin area on which statistics are calculated", us::Any(),false); - parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output", "output file (default: hotspotMiniApp_output.nrrd)", us::Any()); - - std::cout << "test...." << std::endl; - - std::map parsedArgs = parser.parseArguments(argc, argv); - std::cout << "parsedArgs.size()= " << parsedArgs.size() << std::endl; - if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")) - { -// std::cout << "\n\n MiniApp Description: \nCalculates and saves the hotspot of an image." << endl; -// std::cout << "Output is written to the designated output file" << endl; -// std::cout << parser.helpText(); -// return EXIT_SUCCESS; - } - - // Parameters: - std::string inputImageFile; - if (!parsedArgs.count("i") && !parsedArgs.count("input")) - { - inputImageFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D.nrrd"; - } - else - { - inputImageFile = us::any_cast(parsedArgs["input"]); - } - - std::string inputPFFile; - if (parsedArgs.count("planarfigure") || parsedArgs.count("p")) - { - inputPFFile = us::any_cast(parsedArgs["planarfigure"]); - } - else - { - inputPFFile = "/home/fabian/MITK/MITK_platform_project/bin/MITK-superbuild/MITK-Data/Pic3D_rectangle.pf"; - } - - - mitk::PlanarFigure::Pointer planarFigure; - try - { - std::vector loadedObjects; - // try except - loadedObjects = mitk::IOUtil::Load(inputPFFile); - mitk::BaseData::Pointer pf = loadedObjects[0]; - planarFigure = dynamic_cast(pf.GetPointer()); - if (planarFigure.IsNull()) - { - MITK_ERROR << "something went wrong"; - return -1; - } - } - catch (const itk::ExceptionObject& e) - { - MITK_ERROR << "Failed: " << e.what(); - return -1; - } - - std::string outFile; - if (parsedArgs.count("out") || parsedArgs.count("o") ) - outFile = us::any_cast(parsedArgs["out"]); - else - outFile = "planarFigureExtraction_output.nrrd"; - - // Load image and mask - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile); - - // Calculate statistics - mitk::PlanarFigureMaskGenerator::Pointer planarFigMaskExtr = mitk::PlanarFigureMaskGenerator::New(); - planarFigMaskExtr->SetPlanarFigure(planarFigure); - planarFigMaskExtr->SetInputImage(inputImage); - - mitk::Image::Pointer outImage; - try - { - outImage = planarFigMaskExtr->GetMask(); - } - catch( const itk::ExceptionObject& e) - { - MITK_ERROR << "Failed - ITK Exception:" << e.what(); - return -1; - } - - mitk::BaseGeometry *imageGeo = outImage->GetGeometry(); - std::cout << "origin: " << imageGeo->GetOrigin()[0] << " " << imageGeo->GetOrigin()[1] << " " << imageGeo->GetOrigin()[2] << std::endl; - if (outImage != nullptr) - { - mitk::IOUtil::SaveImage(outImage, outFile); - } - - - return EXIT_SUCCESS; -} diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/files.cmake b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/files.cmake index f474bd302f..cb08f4f6c7 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/files.cmake +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/files.cmake @@ -1,60 +1,65 @@ set(SRC_CPP_FILES QmitkFreeSurferParcellationHandler.cpp QmitkFreeSurferParcellationWidget.cpp ) set(INTERNAL_CPP_FILES QmitkConnectomicsDataView.cpp QmitkConnectomicsNetworkOperationsView.cpp QmitkConnectomicsStatisticsView.cpp QmitkNetworkHistogramCanvas.cpp QmitkRandomParcellationView.cpp + Perspectives/QmitkConnectomicsPerspective.cpp + mitkPluginActivator.cpp ) set(UI_FILES src/internal/QmitkConnectomicsDataViewControls.ui src/internal/QmitkConnectomicsNetworkOperationsViewControls.ui src/internal/QmitkConnectomicsStatisticsViewControls.ui src/internal/QmitkRandomParcellationViewControls.ui src/QmitkFreeSurferParcellationWidgetControls.ui ) set(MOC_H_FILES src/internal/mitkPluginActivator.h + src/internal/Perspectives/QmitkConnectomicsPerspective.h + src/internal/QmitkConnectomicsDataView.h src/internal/QmitkConnectomicsNetworkOperationsView.h src/internal/QmitkConnectomicsStatisticsView.h src/internal/QmitkNetworkHistogramCanvas.h src/internal/QmitkRandomParcellationView.h src/QmitkFreeSurferParcellationHandler.h src/QmitkFreeSurferParcellationWidget.h ) set(CACHED_RESOURCE_FILES plugin.xml resources/QmitkConnectomicsDataViewIcon_48.png resources/QmitkConnectomicsNetworkOperationsViewIcon_48.png resources/QmitkConnectomicsStatisticsViewIcon_48.png resources/QmitkRandomParcellationIcon.png + resources/parcellation.png ) set(QRC_FILES resources/QmitkDiffusionImaging.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/plugin.xml index 3bd47d3286..5fb49abd47 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/plugin.xml @@ -1,41 +1,53 @@ + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/resources/parcellation.png b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/resources/parcellation.png new file mode 100644 index 0000000000..3469f6c9d4 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/resources/parcellation.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/Perspectives/QmitkDIAppIVIMPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/Perspectives/QmitkConnectomicsPerspective.cpp similarity index 81% copy from Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/Perspectives/QmitkDIAppIVIMPerspective.cpp copy to Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/Perspectives/QmitkConnectomicsPerspective.cpp index 70c55d4280..41d242cb19 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/Perspectives/QmitkDIAppIVIMPerspective.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/Perspectives/QmitkConnectomicsPerspective.cpp @@ -1,50 +1,47 @@ /*=================================================================== 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 "QmitkDIAppIVIMPerspective.h" +#include "QmitkConnectomicsPerspective.h" #include "berryIViewLayout.h" -void QmitkDIAppIVIMPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) +void QmitkConnectomicsPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) { ///////////////////////////////////////////////////// // all di-app perspectives should have the following: ///////////////////////////////////////////////////// QString editorArea = layout->GetEditorArea(); layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false); layout->AddStandaloneView("org.mitk.views.datamanager", false, berry::IPageLayout::LEFT, 0.3f, editorArea); layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview", false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager"); berry::IFolderLayout::Pointer left = layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols", berry::IPageLayout::BOTTOM, 0.1f, "org.mitk.views.controlvisualizationpropertiesview"); layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator", berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false); ///////////////////////////////////////////// // here goes the perspective specific stuff ///////////////////////////////////////////// - left->AddView("org.mitk.views.ivim"); - berry::IViewLayout::Pointer lo = layout->GetViewLayout("org.mitk.views.ivim"); - - - left->AddView("org.mitk.views.segmentation"); - lo = layout->GetViewLayout("org.mitk.views.segmentation"); - + left->AddView("org.mitk.views.connectomicsdata"); + left->AddView("org.mitk.views.connectomicsstatistics"); + left->AddView("org.mitk.views.connectomicsnetworkoperations"); + left->AddView("org.mitk.views.randomparcellationview"); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/Perspectives/QmitkConnectomicsPerspective.h b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/Perspectives/QmitkConnectomicsPerspective.h new file mode 100644 index 0000000000..9060b0185c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/Perspectives/QmitkConnectomicsPerspective.h @@ -0,0 +1,36 @@ +/*=================================================================== + +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 QmitkConnectomicsPerspective_H_ +#define QmitkConnectomicsPerspective_H_ + +#include + +class QmitkConnectomicsPerspective : public QObject, public berry::IPerspectiveFactory +{ + Q_OBJECT + Q_INTERFACES(berry::IPerspectiveFactory) + +public: + + QmitkConnectomicsPerspective() {} + ~QmitkConnectomicsPerspective() {} + + void CreateInitialLayout(berry::IPageLayout::Pointer layout) override; +}; + +#endif /* QmitkConnectomicsPerspective_H_ */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/mitkPluginActivator.cpp index d3cf66a9e3..28913b3601 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/src/internal/mitkPluginActivator.cpp @@ -1,44 +1,47 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "src/internal/QmitkConnectomicsDataView.h" #include "src/internal/QmitkConnectomicsNetworkOperationsView.h" #include "src/internal/QmitkConnectomicsStatisticsView.h" #include "src/internal/QmitkRandomParcellationView.h" +#include "src/internal/Perspectives/QmitkConnectomicsPerspective.h" ctkPluginContext* mitk::PluginActivator::m_Context = nullptr; ctkPluginContext* mitk::PluginActivator::GetContext() { return m_Context; } void mitk::PluginActivator::start(ctkPluginContext* context) { + BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsPerspective, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsDataView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsNetworkOperationsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsStatisticsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkRandomParcellationView, context) m_Context = context; } void mitk::PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_Context = nullptr; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberfox/src/internal/QmitkFiberfoxViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberfox/src/internal/QmitkFiberfoxViewControls.ui index 4ee765fa3e..3166f3c7a3 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberfox/src/internal/QmitkFiberfoxViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberfox/src/internal/QmitkFiberfoxViewControls.ui @@ -1,3447 +1,3447 @@ QmitkFiberfoxViewControls 0 0 524 2652 Form Load Parameters :/QmitkDiffusionImaging/general_icons/upload.ico:/QmitkDiffusionImaging/general_icons/upload.ico - 0 + 1 Fiber Definition Qt::Vertical 20 40 color: rgb(255, 0, 0); Please select an image or an existing fiber bundle to draw the fiber fiducials. If you can't provide a suitable image, generate one using the "Signal Generation" tab. Qt::AutoText Qt::AlignJustify|Qt::AlignVCenter true Fiducial Options All fiducials are treated as circles with the same radius as the first fiducial. Use Constant Fiducial Radius false false Align selected fiducials with voxel grid. Shifts selected fiducials to nearest voxel center. Align With Grid :/QmitkDiffusionImaging/general_icons/right.ico:/QmitkDiffusionImaging/general_icons/right.ico Operations false Join Bundles :/QmitkDiffusionImaging/general_icons/plus.ico:/QmitkDiffusionImaging/general_icons/plus.ico QFrame::NoFrame QFrame::Raised 0 0 0 0 Y false Rotation angle (in degree) around x-axis. 3 -360.000000000000000 360.000000000000000 0.100000000000000 Axis: false Rotation angle (in degree) around y-axis. 3 -360.000000000000000 360.000000000000000 0.100000000000000 Translation: false Translation (in mm) in direction of the z-axis. 3 -1000.000000000000000 1000.000000000000000 0.100000000000000 Translation (in mm) in direction of the y-axis. 3 -1000.000000000000000 1000.000000000000000 0.100000000000000 X false Rotation: false Z false Rotation angle (in degree) around z-axis. 3 -360.000000000000000 360.000000000000000 0.100000000000000 Translation (in mm) in direction of the x-axis. 3 -1000.000000000000000 1000.000000000000000 0.100000000000000 Scaling: false Scaling factor for selected fiber bundle along the x-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 Scaling factor for selected fiber bundle along the y-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 Scaling factor for selected fiber bundle along the z-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 false Copy Bundles :/QmitkDiffusionImaging/general_icons/copy2.ico:/QmitkDiffusionImaging/general_icons/copy2.ico false Transform Selection :/QmitkDiffusionImaging/general_icons/refresh.ico:/QmitkDiffusionImaging/general_icons/refresh.ico If checked, the fiducials belonging to the modified bundle are also modified. Include Fiducials true Fiber Options QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Tension: false Fiber Sampling: false 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 Bias: false Continuity: false 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 Distance of fiber sampling points (in mm) 1 0.100000000000000 0.100000000000000 1.000000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 6 #Fibers: false Specify number of fibers to generate for the selected bundle. 1 1000000 100 100 false Generate Fibers :/QmitkDiffusionImaging/general_icons/right.ico:/QmitkDiffusionImaging/general_icons/right.ico QFrame::NoFrame QFrame::Raised 0 0 0 0 Select fiber distribution inside of the fiducials. Uniform Gaussian Fiber Distribution: false Variance of the gaussian 3 0.001000000000000 10.000000000000000 0.010000000000000 0.100000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 Disable to only generate fibers if "Generate Fibers" button is pressed. Real Time Fibers true Disable to only generate fibers if "Generate Fibers" button is pressed. Advanced Options false QFrame::NoFrame QFrame::Raised 0 0 0 0 false 30 30 Draw elliptical fiducial. :/QmitkDiffusionImaging/circle.png:/QmitkDiffusionImaging/circle.png 32 32 false true false 30 30 Flip fiber waypoints of selcted fiducial around one axis. :/QmitkDiffusionImaging/general_icons/refresh.ico:/QmitkDiffusionImaging/general_icons/refresh.ico 32 32 false true Qt::Horizontal 40 20 Signal Generation Extra-axonal Compartments QFrame::NoFrame QFrame::Raised 0 0 0 0 Volume Fraction: Select signal model for extra-axonal compartment. Ball Model Astrosticks Model Dot Model Prototype Signal Qt::Horizontal QFrame::NoFrame QFrame::Raised 0 0 0 0 Volume Fraction: Optional! If no volume fraction map for this compartment is set, the corresponding volume fractions are calculated from the input fibers. Select signal model for extra-axonal compartment. -- Ball Model Astrosticks Model Dot Model Prototype Signal Qt::Vertical 20 40 Image Settings Advanced Options QFrame::NoFrame QFrame::Raised 0 0 0 0 6 Gradient Directions: Number of gradient directions distributed over the half sphere. 0 10000 1 30 <html><head/><body><p>b-Value<span style=" font-style:italic;"> [s/mm</span><span style=" font-style:italic; vertical-align:super;">2</span><span style=" font-style:italic;">]</span>:</p></body></html> false b-value in s/mm² 0 10000 100 1000 color: rgb(255, 0, 0); Using geometry of selected image! color: rgb(255, 0, 0); Using gradients of selected DWI! QFrame::NoFrame QFrame::Raised 0 0 0 0 6 <html><head/><body><p>Number of Channels:</p></body></html> false TR in milliseconds 1 999999999 1 4000 Output one image per compartment containing the corresponding volume fractions per voxel. Reverse Phase Encoding Direction false Signal Scale: Dwell time (time to read one line in k-space) in ms. 100.000000000000000 0.100000000000000 1.000000000000000 TE in milliseconds 1 999999999 1 100 Fiber Radius: Partial Fourier: false Disable partial volume. Treat voxel content as fiber-only if at least one fiber is present. Disable Partial Volume Effects false <html><head/><body><p>Coil Sensitivity:</p></body></html> false Partial fourier factor (0.5-1) 3 0.500000000000000 1.000000000000000 0.100000000000000 1.000000000000000 Output phase image and volume fraction maps. Output Additional Images false Relaxation time due to magnetic field inhomogeneities (T2', in milliseconds). 1 10000 1 50 <html><head/><body><p>Repetition Time <span style=" font-style:italic;">TR</span>: </p></body></html> false Constant Linear Exponential Dwell Time: false <html><head/><body><p><span style=" font-style:italic;">T</span><span style=" font-style:italic; vertical-align:sub;">inhom</span> Relaxation: </p></body></html> false <html><head/><body><p><span style=" font-style:italic;">TE</span>, <span style=" font-style:italic;">T</span><span style=" font-style:italic; vertical-align:sub;">inhom</span> and <span style=" font-style:italic;">T2</span> will have no effect if unchecked.</p></body></html> Simulate Signal Relaxation true <html><head/><body><p>Echo Time <span style=" font-style:italic;">TE</span>: </p></body></html> false TE in milliseconds 1 10000 1 100 Number of coil elements used for the acquisiton. 1 128 1 1 Acquisition Type: Single Shot EPI Spin Echo Fiber radius used to calculate volume fractions (in µm). Set to 0 for automatic radius estimation. 9999.000000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 Image Spacing: 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 Image Dimensions: Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 20 Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 20 Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 3 Inter-axonal Compartment Select signal model for intra-axonal compartment. -- Stick Model Zeppelin Model Tensor Model QFrame::NoFrame QFrame::Raised 0 0 0 0 Volume Fraction: Optional! If no volume fraction map for this compartment is set, the corresponding volume fractions are calculated from the input fibers. true Stop current simulation. Abort Simulation :/QmitkDiffusionImaging/general_icons/abort.ico:/QmitkDiffusionImaging/general_icons/abort.ico Data QFrame::NoFrame QFrame::Raised 0 0 0 0 0 - ... <html><head/><body><p>Select a binary image to define the area of signal generation. Outside of the mask image only noise will be actively generated.</p></body></html> QComboBox::AdjustToMinimumContentsLength Fiber Bundle: false Save path: false Tissue Mask: false <html><head/><body><p>Select a fiber bundle to generate the white matter signal from. You can either use the fiber definition tab to manually define an input fiber bundle or you can also use any existing bundle, e.g. yielded by a tractography algorithm.</p></body></html> QComboBox::AdjustToMinimumContentsLength Template Image: false <html><head/><body><p>The parameters for the simulation (e.g. spacing, size, diffuison-weighted gradients, b-value) are adopted from this image.</p></body></html> QComboBox::AdjustToMinimumContentsLength 8 true Noise and other Artifacts Add Distortions false Add Spikes false true QFrame::NoFrame QFrame::Raised QFormLayout::AllNonFixedFieldsGrow 6 0 0 0 0 Gradient: false Eddy current induced magnetic field gradient (in mT/m). 4 1000.000000000000000 0.001000000000000 0.010000000000000 Add Motion Artifacts false Qt::Horizontal true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 K-Space Line Offset: false A larger offset increases the inensity of the ghost image. 3 1.000000000000000 0.010000000000000 0.250000000000000 Add Noise false QFrame::NoFrame QFrame::Raised 0 0 0 0 Num. Spikes: The number of randomly occurring signal spikes. 1 Spike amplitude relative to the largest signal amplitude of the corresponding k-space slice. 0.100000000000000 0.100000000000000 Scale: true QFrame::NoFrame QFrame::Raised 0 6 0 0 6 Toggle between random movement and linear movement. Randomize motion true Rotation 0 9 0 0 Degree: false x false Axis: false Maximum rotation around x-axis. 1 -360.000000000000000 360.000000000000000 1.000000000000000 0.000000000000000 Maximum rotation around z-axis. 1 -360.000000000000000 360.000000000000000 1.000000000000000 15.000000000000000 y false z false Maximum rotation around y-axis. 1 -360.000000000000000 360.000000000000000 1.000000000000000 0.000000000000000 Translation 0 0 0 Distance: false x false y false Axis: false z false Maximum translation along x-axis. 1 -1000.000000000000000 1000.000000000000000 1.000000000000000 0.000000000000000 Maximum translation along y-axis. 1 -1000.000000000000000 1000.000000000000000 1.000000000000000 0.000000000000000 Maximum translation along z-axis. 1 -1000.000000000000000 1000.000000000000000 1.000000000000000 0.000000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 Motion volumes: Type in the volume indices that should be affected by motion (e.g. "0 3 7" whithout quotation marks). Leave blank for motion in all volumes. Type in "random" to randomly select volumes for motion. A list of negative numbers (e.g. -1 -2 -3) excludes volumes (e.g. 1 2 3) selects all remaining volumes. random Add ringing artifacts occuring at strong edges in the image. Add Gibbs Ringing false Qt::Horizontal Qt::Horizontal Qt::Horizontal Qt::Horizontal Add N/2 Ghosts false Add Aliasing false Qt::Horizontal Qt::Horizontal Add Eddy Current Effects false true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 Shrink FOV (%): false Shrink FOV by this percentage. 1 0.000000000000000 90.000000000000000 0.100000000000000 25.000000000000000 true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 Frequency Map: false Select image specifying the frequency inhomogeneities (in Hz). QFrame::NoFrame QFrame::Raised 0 0 0 0 Variance: Variance of selected noise distribution. 10 0.000000000000000 999999999.000000000000000 0.001000000000000 50.000000000000000 Distribution: Noise distribution Complex Gaussian Rician true <html><head/><body><p>Start DWI generation from selected fiber bundle.</p><p>If no fiber bundle but an existing diffusion weighted image is selected, the enabled artifacts are added to this image.</p><p>If neither a fiber bundle nor a diffusion weighted image is selected, a grayscale image containing a simple gradient is generated.</p></body></html> Start Simulation :/QmitkDiffusionImaging/general_icons/right.ico:/QmitkDiffusionImaging/general_icons/right.ico Intra-axonal Compartment Select signal model for intra-axonal compartment. Stick Model Zeppelin Model Tensor Model Prototype Signal QFrame::NoFrame QFrame::Raised 0 0 0 0 Volume Fraction: Optional! If no volume fraction map for this compartment is set, the corresponding volume fractions are calculated from the input fibers. Save Parameters :/QmitkDiffusionImaging/general_icons/download.ico:/QmitkDiffusionImaging/general_icons/download.ico + + QmitkDataStorageComboBoxWithSelectNone + QComboBox +
QmitkDataStorageComboBoxWithSelectNone.h
+
QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
QmitkTensorModelParametersWidget QWidget
QmitkTensorModelParametersWidget.h
1
QmitkStickModelParametersWidget QWidget
QmitkStickModelParametersWidget.h
1
QmitkZeppelinModelParametersWidget QWidget
QmitkZeppelinModelParametersWidget.h
1
QmitkBallModelParametersWidget QWidget
QmitkBallModelParametersWidget.h
1
QmitkAstrosticksModelParametersWidget QWidget
QmitkAstrosticksModelParametersWidget.h
1
QmitkDotModelParametersWidget QWidget
QmitkDotModelParametersWidget.h
1
QmitkPrototypeSignalParametersWidget QWidget
QmitkPrototypeSignalParametersWidget.h
1
- - QmitkDataStorageComboBoxWithSelectNone - QComboBox -
QmitkDataStorageComboBoxWithSelectNone.h
-
m_CircleButton m_FlipButton m_RealTimeFibers m_AdvancedOptionsBox m_DistributionBox m_VarianceBox m_FiberDensityBox m_FiberSamplingBox m_TensionBox m_ContinuityBox m_BiasBox m_GenerateFibersButton m_ConstantRadiusBox m_AlignOnGrid m_XrotBox m_YrotBox m_ZrotBox m_XtransBox m_YtransBox m_ZtransBox m_XscaleBox m_YscaleBox m_ZscaleBox m_TransformBundlesButton m_CopyBundlesButton m_JoinBundlesButton m_IncludeFiducials m_FiberBundleComboBox m_MaskComboBox m_TemplateComboBox m_SavePathEdit m_OutputPathButton m_GenerateImageButton m_AbortSimulationButton m_SimulationStatusText m_SizeX m_SizeY m_SizeZ m_SpacingX m_SpacingY m_SpacingZ m_NumGradientsBox m_BvalueBox m_AdvancedOptionsBox_2 m_SignalScaleBox m_TEbox m_TRbox m_LineReadoutTimeBox m_PartialFourier m_T2starBox m_FiberRadius m_ReversePhaseBox m_RelaxationBox m_EnforcePureFiberVoxelsBox m_VolumeFractionsBox m_Compartment1Box m_Comp1VolumeFraction m_Compartment2Box m_Comp2VolumeFraction m_Compartment3Box m_Comp3VolumeFraction m_Compartment4Box m_Comp4VolumeFraction m_AddNoise m_NoiseDistributionBox m_NoiseLevel m_AddSpikes m_SpikeNumBox m_SpikeScaleBox m_AddGhosts m_kOffsetBox m_AddAliasing m_WrapBox m_AddDistortions m_FrequencyMapBox m_AddMotion m_RandomMotion m_MaxRotationBoxX m_MaxRotationBoxY m_MaxRotationBoxZ m_MaxTranslationBoxX m_MaxTranslationBoxY m_MaxTranslationBoxZ m_AddEddy m_EddyGradientStrength m_AddGibbsRinging m_SaveParametersButton m_LoadParametersButton tabWidget
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml index 3820786c62..7814e573c5 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml @@ -1,83 +1,80 @@ This perspective contains all views necessary to post process fibers. - - - diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/plugin.xml index fbf723ec1d..668eebc1cc 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/plugin.xml @@ -1,29 +1,29 @@ - + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/Perspectives/QmitkDIAppIVIMPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/Perspectives/QmitkDIAppIVIMPerspective.cpp index 70c55d4280..b3539be4a4 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/Perspectives/QmitkDIAppIVIMPerspective.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/Perspectives/QmitkDIAppIVIMPerspective.cpp @@ -1,50 +1,51 @@ /*=================================================================== 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 "QmitkDIAppIVIMPerspective.h" #include "berryIViewLayout.h" void QmitkDIAppIVIMPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) { ///////////////////////////////////////////////////// // all di-app perspectives should have the following: ///////////////////////////////////////////////////// QString editorArea = layout->GetEditorArea(); layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false); layout->AddStandaloneView("org.mitk.views.datamanager", false, berry::IPageLayout::LEFT, 0.3f, editorArea); layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview", false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager"); berry::IFolderLayout::Pointer left = layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols", berry::IPageLayout::BOTTOM, 0.1f, "org.mitk.views.controlvisualizationpropertiesview"); layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator", berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false); ///////////////////////////////////////////// // here goes the perspective specific stuff ///////////////////////////////////////////// left->AddView("org.mitk.views.ivim"); berry::IViewLayout::Pointer lo = layout->GetViewLayout("org.mitk.views.ivim"); left->AddView("org.mitk.views.segmentation"); lo = layout->GetViewLayout("org.mitk.views.segmentation"); - + left->AddView("org.mitk.views.diffusionquantification"); + left->AddView("org.mitk.views.diffusionpreprocessing"); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/QmitkIVIMViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/QmitkIVIMViewControls.ui index 9eda318b11..455d1cef01 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/QmitkIVIMViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.ivim/src/internal/QmitkIVIMViewControls.ui @@ -1,1172 +1,1172 @@ QmitkIVIMViewControls 0 0 - 379 + 380 1563 0 0 QmitkTemplate 9 9 9 9 Intra Voxel Incoherent Motion Estimation 0 9 0 0 Please Select Input Data Optional ROI image ROI: DWI to analyze <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> Optional ROI image <html><head/><body><p><span style=" color:#969696;">optional</span></p></body></html> DWI to analyze Raw DWI: QFrame::NoFrame QFrame::Raised 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 warning display Qt::RichText true QFrame::StyledPanel QFrame::Raised 0 0 0 0 0 - 1 + 0 0 0 IVIM Parameters 9 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 80 16777215 D* 100 60 Qt::Horizontal 51 16777215 200 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter QFrame::NoFrame QFrame::Raised 0 0 0 0 0 80 16777215 neglect b< 250 34 Qt::Horizontal 51 16777215 46.5 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter QFrame::NoFrame QFrame::Raised 0 0 0 0 0 80 16777215 #iterations 100 10 Qt::Horizontal 30 16777215 TextLabel Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter QFrame::NoFrame QFrame::Raised 0 0 0 0 0 80 16777215 lambda 1000 10 Qt::Horizontal 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 0 0 30 16777215 TextLabel Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 15 16777215 Calculate threshold from histogram * QFrame::NoFrame QFrame::Plain 0 0 0 0 0 80 16777215 neglect Si< 100 0 Qt::Horizontal 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 0 0 30 16777215 TextLabel Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 15 16777215 Calculate threshold from histogram * QFrame::NoFrame QFrame::Raised 0 0 0 0 80 0 Output Images f true D false D* false true 0 0 0 400 0 0 0 0 Choose Method 2 3 Param. Fit Fit D & f with fixed D* value Fit D & f (high b), then fit D* Linearly fit D & f (high b), then fit D* Regularized Kurtosis QFrame::StyledPanel QFrame::Raised 2 2 2 2 2 Smoothing sigma Select Fit Type Omit b=0 Measurement 80 0 Output Images Force the fitting of K to remain within the given boundaries Boundaries for K Select if the data is fitted directly (straight) or the logarithmic equation is used Straight Fit Logarithmic Fit 2 QLayout::SetMaximumSize D false K true Signa for gaussian smoothing applied prior to map computation 1.000000000000000 5.000000000000000 0.100000000000000 On 0 0 0 400 Generate Output Images QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Datapoints to Clipboard Parameters to Clipboard QmitkIVIMWidget QWidget
QmitkIVIMWidget.h
1
QmitkKurtosisWidget QWidget
QmitkKurtosisWidget.h
1
ctkRangeWidget QWidget
ctkRangeWidget.h
1
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/files.cmake b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/files.cmake index 51228b5c78..aca387a866 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/files.cmake +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/files.cmake @@ -1,62 +1,66 @@ set(SRC_CPP_FILES QmitkODFDetailsWidget.cpp QmitkODFRenderWidget.cpp QmitkResidualAnalysisWidget.cpp QmitkResidualViewWidget.cpp ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp + Perspectives/QmitkReconstructionPerspective.cpp + QmitkQBallReconstructionView.cpp QmitkDiffusionQuantificationView.cpp QmitkTensorReconstructionView.cpp QmitkODFDetailsView.cpp ) set(UI_FILES src/internal/QmitkQBallReconstructionViewControls.ui src/internal/QmitkDiffusionQuantificationViewControls.ui src/internal/QmitkTensorReconstructionViewControls.ui src/internal/QmitkODFDetailsViewControls.ui ) set(MOC_H_FILES src/internal/mitkPluginActivator.h + src/internal/Perspectives/QmitkReconstructionPerspective.h + src/internal/QmitkQBallReconstructionView.h src/internal/QmitkDiffusionQuantificationView.h src/internal/QmitkTensorReconstructionView.h src/internal/QmitkODFDetailsView.h src/QmitkODFRenderWidget.h src/QmitkODFDetailsWidget.h src/QmitkResidualAnalysisWidget.h src/QmitkResidualViewWidget.h ) set(CACHED_RESOURCE_FILES plugin.xml resources/quantification.png resources/OdfDetails.png resources/reconodf.png resources/recontensor.png resources/tensor.png resources/qball.png ) set(QRC_FILES ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/plugin.xml index aa45e53c8e..de0851208f 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/plugin.xml @@ -1,87 +1,99 @@ Q-Ball reconstruction view Calculation of tensor and Q-ball derived measures. + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkGibbsTractographyPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/Perspectives/QmitkReconstructionPerspective.cpp similarity index 86% copy from Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkGibbsTractographyPerspective.cpp copy to Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/Perspectives/QmitkReconstructionPerspective.cpp index 9fee132fe5..d1c156a3ec 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkGibbsTractographyPerspective.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/Perspectives/QmitkReconstructionPerspective.cpp @@ -1,50 +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. ===================================================================*/ -#include "QmitkGibbsTractographyPerspective.h" +#include "QmitkReconstructionPerspective.h" #include "berryIViewLayout.h" -void QmitkGibbsTractographyPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) +void QmitkReconstructionPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) { ///////////////////////////////////////////////////// // all di-app perspectives should have the following: ///////////////////////////////////////////////////// QString editorArea = layout->GetEditorArea(); layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false); layout->AddStandaloneView("org.mitk.views.datamanager", false, berry::IPageLayout::LEFT, 0.3f, editorArea); layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview", false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager"); berry::IFolderLayout::Pointer left = layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols", berry::IPageLayout::BOTTOM, 0.1f, "org.mitk.views.controlvisualizationpropertiesview"); layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator", berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false); ///////////////////////////////////////////// // here goes the perspective specific stuff ///////////////////////////////////////////// left->AddView("org.mitk.views.tensorreconstruction"); left->AddView("org.mitk.views.qballreconstruction"); - left->AddView("org.mitk.views.gibbstracking"); + left->AddView("org.mitk.views.diffusionquantification"); + left->AddView("org.mitk.views.diffusionpreprocessing"); + left->AddView("org.mitk.views.odfdetails"); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/Perspectives/QmitkReconstructionPerspective.h b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/Perspectives/QmitkReconstructionPerspective.h new file mode 100644 index 0000000000..f0f64719c5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/Perspectives/QmitkReconstructionPerspective.h @@ -0,0 +1,36 @@ +/*=================================================================== + +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 QmitkReconstructionPerspective_H_ +#define QmitkReconstructionPerspective_H_ + +#include + +class QmitkReconstructionPerspective : public QObject, public berry::IPerspectiveFactory +{ + Q_OBJECT + Q_INTERFACES(berry::IPerspectiveFactory) + +public: + + QmitkReconstructionPerspective() {} + ~QmitkReconstructionPerspective() {} + + void CreateInitialLayout(berry::IPageLayout::Pointer layout) override; +}; + +#endif /* QmitkReconstructionPerspective_H_ */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/mitkPluginActivator.cpp index 63e3cdc9b2..ceb16b327a 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.reconstruction/src/internal/mitkPluginActivator.cpp @@ -1,44 +1,47 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "src/internal/QmitkQBallReconstructionView.h" #include "src/internal/QmitkTensorReconstructionView.h" #include "src/internal/QmitkDiffusionQuantificationView.h" #include "src/internal/QmitkODFDetailsView.h" +#include "src/internal/Perspectives/QmitkReconstructionPerspective.h" ctkPluginContext* mitk::PluginActivator::m_Context = nullptr; ctkPluginContext* mitk::PluginActivator::GetContext() { return m_Context; } void mitk::PluginActivator::start(ctkPluginContext* context) { + BERRY_REGISTER_EXTENSION_CLASS(QmitkReconstructionPerspective, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkQBallReconstructionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionQuantificationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTensorReconstructionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkODFDetailsView, context) m_Context = context; } void mitk::PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_Context = nullptr; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkGibbsTrackingViewUserManual.dox b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkGibbsTrackingViewUserManual.dox index 247f8c0607..45e9e2ca1c 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkGibbsTrackingViewUserManual.dox +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkGibbsTrackingViewUserManual.dox @@ -1,40 +1,38 @@ /** \page org_mitk_views_gibbstracking Global Gibbs Tractography This view provides the user interface for the global Gibbs tractography algorithm, a global fiber tracking algorithm, originally proposed by Reisert et.al. [1]. \tableofcontents -\imageMacro{gibbstrackingview.png,"The Gibbs Tracking View",2} - \section QmitkGibbsTrackingUserManualInputData Input Data Mandatory Input: \li One Q-Ball or tensor image selected in the datamanager Optional Input: \li Mask Image: White matter probability mask. Corresponds to the probability to generate fiber segments in the respective voxel. \section QmitkGibbsTrackingUserManualParameters Q-Ball Reconstruction -\li Number of iterations: More iterations causes the algorithm to be more stable but also to take longer to finish the tracking. Recommended: 10^8 to 5x10^8 iterations for full brain tractography. +\li Number of iterations: More iterations causes the algorithm to be more stable but also to take longer to finish the tracking. Recommended: minimum 10^8 iterations for full brain tractography. \li Particle length/width/weight controlling the contribution of each particle to the model M \li Start and end temperature controlling how fast the process reaches a stable state. (usually no change needed) \li Weighting between the internal (affinity of the model to long and straigt fibers) and external energy (affinity of the model towards the data). (usually no change needed). \li Minimum fiber length constraint (in mm). Shorter fibers are discarded after the tracking. The automatic selection of parameters for the particle length/width and weight are determined directly from the input image using information about the image spacing and GFA. \imageMacro{gibbstrackingviewadvanced.png,"Advanced Tracking Parameters",10.08} \section QmitkGibbsTrackingUserManualTrackingSurveillance Surveilance of the tracking process Once started, the tracking can be monitored via the textual output that informs about the tracking progress and several stats of the current state of the algorithm. If enabled, the intermediate tracking results are displayed in the renderwindows each second. This live visualization should usually be disabled for performance reasons. It can be turned on and off during the tracking process via the according checkbox. The button next to this checkbox allows the visualization of only the next iteration step. \section QmitkGibbsTrackingUserManualReferences References [1] Reisert, M., Mader, I., Anastasopoulos, C., Weigel, M., Schnell, S., Kiselev, V.: Global fiber reconstruction becomes practical. Neuroimage 54 (2011) 955-962 */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkMLBTViewUserManual.dox b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkMLBTViewUserManual.dox index 7ddd68f71d..9e45d2e5d3 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkMLBTViewUserManual.dox +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkMLBTViewUserManual.dox @@ -1,51 +1,50 @@ /** \page org_mitk_views_mlbtview Machine Learning Based Streamline Tractography This view provides the user interface for machine-learning based streamline fiber tractography on diffusion-weighted images. It is dived in two parts: (1) training of the random-forest classifier used for tractography and (2) the actual tractography. Available sections: - \ref MlbstUserManualTraining - \ref MlbstUserManualTractography - \ref MlbstUserManualReferences \section MlbstUserManualTraining Training -Before - Parameters: \li Num. Trees: Number of trees that constitute the random forest. The default of 30 works well for most cases. \li Max. Depth: Maximum tree depth. -\li Non-WM Sampling Points: Number of randomly placed sampling points in each non-white-matter voxel. These sampling points are needed to train the classifier for non-fiber tissue. \li Sample Fraction: Fraction of randomly drawn samples used to train each tree. -\li Step Size: The fibers are resampled with this step size. Influences the number of white-matter sampling ponts. Defaul is 0.5*min. voxel size. +\li Non-WM Sampling Points: Number of randomly placed sampling points in each non-white-matter voxel. These sampling points are needed to train the classifier for non-fiber tissue. +\li Fiber Sampling: The fibers are resampled equidistantly. This influences the number of white-matter sampling ponts. Defaul is 0.5*min. voxel size. \section MlbstUserManualTractography Tractography Parameters and options: \li Input DWI: Input diffusion-weighted image for tractography. Minimum number of gradient directions is 28, since 6th order spherical harmonics are used to spherically interpolate the raw signal. -\li Num. Seeds: Number of seed points per voxel. If set to 1, the seed is defined as the voxel center. If > 1 the seeds are distributet randomly inside the voxel. +\li Seeds per Voxel: Number of seed points per voxel. If set to 1, the seed is defined as the voxel center. If > 1 the seeds are distributet randomly inside the voxel. \li Step Size: The algorithm proceeds along the streamline with a fixed stepsize (in voxels). Default is 0.5*minSpacing. -\li Angular Threshold: Sudden directional changes larger than the specified angle have a probability of 0. -\li Num. Samples: Number of samples used to probe the local neighborhood. \li Sampling Distance: Maximum distance of the sampling points from the current streamline position (in voxel). +\li Num. Samples: Number of samples used to probe the local neighborhood. \li Min. Length: Shorter fibers are discarded. \li Max. Length: Longer fibers are discarded. -\li Num. Threads: Number of threads used for tractography. Default is the maximum number of threads. If demo mode is enabled, the number of threads is automatically set to 1. -\li Random sampling: If checked, the neighborhood sampling points are distributed randomly in the current neighborhood, as oposed to spherically around the current position (default). -\li Avoid premature termination: Uses the information of the neighborhood sampling points to avoid a premature fiber termination. If unchecked, no neighborhood samples are used. -\li Secondary curvature check: If checked, a secondary curvature threshold is applied and the fiber progression stops if exceeded. This can also be done a posteriory in the Fiber Processing View. -\li Mask Image: Binary image used to limit the tractography space. If no mask image is selected, the whole image volume is included in the tractography process. Typically select a binary brain mask here. -\li Seed Image: Binary image used to define the seed voxels. If no image is selected, seeds are placed in all voxels. -\li Stop Image: Binary image to define stopping regions for the tractography process. As soon as a streamline enters a region defined by this image, the streamline progression stops. Binary gray matter segmentations are a typical input here. +\li Enable Gray Matter Seeding: Seeds are onyl placed inside of the gray matter. Needs tissue label image. +\li Only Frontal Samples: Only use neighborhood samples in front of the current streamline position. +\li Mask Image: Binary mask used to constrain the generated streamlines. Streamlines can not leave the mask area. +\li Seed Image: Binary mask used to define the seed voxels. If no seed mask is specified, the whole image volume is seeded. +\li Stop Image: Binary mask used to define stopping regions. Streamlines that enter the mask area are stopped immediately. +\li Tissue Image: Tissue label image needed for gray matter seeding (WM=3, GM=1). Use e.g. MRtrix 5ttgen to generate such a label image. + \li Demo Mode: Directly visualizes the streamline progression and the sampling points. Only use this for demonstration purposes, since it is very slow. \section MlbstUserManualReferences References -[1] Neher, P.F., Götz, M., Norajitra, T., Weber, C., Maier-Hein, K.H., 2015. A machine learning based approach to fiber tractography, in: Proceedings of International Society of Magnetic Resonance in Medicine. +[1] Neher, P.F., Côte, M-A., Houde, J-C., Descoteaux, M., Maier-Hein, K.H., 2017. Fiber tractography using machine learning, doi: https://doi.org/10.1101/104190. + +[2] Neher, P.F., Götz, M., Norajitra, T., Weber, C., Maier-Hein, K.H., 2015. A machine learning based approach to fiber tractography, in: Proceedings of International Society of Magnetic Resonance in Medicine. -[2] Neher, P.F., Götz, M., Norajitra, T., Weber, C., Maier-Hein, K.H., 2015. A machine learning based approach to fiber tractography using classifier voting, in: Proceedings of Medical Image Computing and Computer-Assisted Intervention. Presented at the Medical Image Computing and Computer-Assisted Intervention. +[3] Neher, P.F., Götz, M., Norajitra, T., Weber, C., Maier-Hein, K.H., 2015. A machine learning based approach to fiber tractography using classifier voting, in: Proceedings of Medical Image Computing and Computer-Assisted Intervention. Presented at the Medical Image Computing and Computer-Assisted Intervention. */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkStreamlineTrackingViewUserManual.dox b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkStreamlineTrackingViewUserManual.dox index 546ba0a466..83ee7a336c 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkStreamlineTrackingViewUserManual.dox +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkStreamlineTrackingViewUserManual.dox @@ -1,51 +1,58 @@ /** \page org_mitk_views_streamlinetracking Streamline Tractography Available sections: - \ref StrTrackUserManualInputData + - \ref StrTrackUserManualInteractive - \ref StrTrackUserManualParameters + - \ref StrTrackUserManualAdvancedParameters - \ref StrTrackUserManualReferences \section StrTrackUserManualInputData Input Data Input: \li One or multiple DTI images selected in the datamanager. \li One ODF image (e.g. obtained using MITK Q-ball reconstruction or MRtrix CSD). \li One peak image in MRtrix format (4D float image). Optional Input: \li Binary mask used to define the seed voxels. If no seed mask is specified, the whole image volume is seeded. \li Binary mask used to constrain the generated streamlines. Streamlines can not leave the mask area. \li Binary mask used to define stopping regions. Streamlines that enter the mask area are stopped immediately. \li Tissue label image needed for gray matter seeding (WM=3, GM=1). Use e.g. MRtrix 5ttgen to generate such a label image. \li FA/GFA image used to determine streamline termination. If no image is specified, the FA/GFA image is automatically calculated from the input image. If multiple tensor images are used as input, it is recommended to provide such an image since the FA maps calculated from the individual input tensor images can not provide a suitable termination criterion. +\section StrTrackUserManualInteractive Interactive Tractography + +Interactive tractography enables the dynamic placement of spherical seed regions simply by clicking into the image. Parameters are the number of seed points and the radius of the spherical seed region. The seed points are randomly distributed inside the sphere around the selected position. By clicking and holding the left mouse button while moving the mouse around the image, the fiber connections originating from the selected region can be explored dynamically. + \section StrTrackUserManualParameters Parameters \li Mode: Toggle between deterministic and probabilistic tractography. Peak tracking only supports deterministic mode. The probabilistic method simply samples the output direction from the discrete probability ditribution provided by the discretized ODF. \li Seeds per voxel: If set to 1, the seed is defined as the voxel center. If > 1 the seeds are distributet randomly inside the voxel. \li Max. num. fibers: Tractography is stopped after the desired number of fibers is reached, even before all seed points are processed. \li Cutoff: If the streamline reaches a position with an FA value or peak magnitude lower than the speciefied threshold, tracking is terminated. -\section StrTrackUserManualParameters Advanced Parameters +\section StrTrackUserManualAdvancedParameters Advanced Parameters \li Step Size: The algorithm proceeds along the streamline with a fixed stepsize. Default is 0.5*minSpacing. \li Angular threshold: Maximum angle between two successive steps (in degree). Default is 90° * step_size. For probabilistic tractography, candidate directions exceeding this threshold have probability 0, i.e. the respective ODF value is set to zero. The probabilities of the valid directions are normalized to sum to 1. \li Min. Tract Length: Shorter fibers are discarded. \li f and g values to balance between FACT [1] and TEND [2,3] tracking (only for tensor based tractography). For further information please refer to [2,3] \li Flip directions: Internally flips progression directions. This might be necessary depending on the input data. \li Neighborhood Samples: Number of neighborhood samples that are used to determine the next fiber progression direction [4]. \li Compress Fibers: Whole brain tractograms obtained with a small step size can contain billions of points. The tractograms can be compressed by removing points that do not really contribute to the fiber shape, such as many points on a straight line. An error threshold (in mm) can be defined to specify which points should be removed and which not. \li Enable Trilinear Interpolation: By default the image values are interpolated. Keep in mind that in the noninterpolated case, the TEND term is only applied once per voxel. In the interpolated case the TEND term is applied at each integration step which results in much higher curvatures and has to be compensated by an according choice of f and g. -\li Min-max normalize ODFs - +\li Min-max normalize ODFs: ODFs are min-max normalized before tractography. This results in sharper ODFs. +\li Output Probability Map: No streamline are generated. Instead, the tractography outputs a probability map that indicates the probability of a fiber to reach a voxel from the selected seed region. For this measure to be sensible, the number of seeds per voxel needs to be rather large. This option does not work during interactive tractography. +\li Enable Gray Matter Seeding: Seeds are onyl placed inside of the gray matter. Needs tissue label image. \section StrTrackUserManualReferences References [1] Mori et al. Annals Neurology 1999\n [2] Weinstein et al. Proceedings of IEEE Visualization 1999\n [3] Lazar et al. Human Brain Mapping 2003\n */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/plugin.xml index cb8e17d18f..8d5bc44888 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/plugin.xml @@ -1,115 +1,108 @@ - - + --> + + + - - - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkGibbsTractographyPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkGibbsTractographyPerspective.cpp index 9fee132fe5..7c043d6050 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkGibbsTractographyPerspective.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkGibbsTractographyPerspective.cpp @@ -1,50 +1,50 @@ /*=================================================================== 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 "QmitkGibbsTractographyPerspective.h" #include "berryIViewLayout.h" void QmitkGibbsTractographyPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) { ///////////////////////////////////////////////////// // all di-app perspectives should have the following: ///////////////////////////////////////////////////// QString editorArea = layout->GetEditorArea(); layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false); layout->AddStandaloneView("org.mitk.views.datamanager", false, berry::IPageLayout::LEFT, 0.3f, editorArea); layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview", false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager"); berry::IFolderLayout::Pointer left = layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols", berry::IPageLayout::BOTTOM, 0.1f, "org.mitk.views.controlvisualizationpropertiesview"); layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator", berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false); ///////////////////////////////////////////// // here goes the perspective specific stuff ///////////////////////////////////////////// - left->AddView("org.mitk.views.tensorreconstruction"); - left->AddView("org.mitk.views.qballreconstruction"); left->AddView("org.mitk.views.gibbstracking"); + left->AddView("org.mitk.views.qballreconstruction"); + left->AddView("org.mitk.views.tensorreconstruction"); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkMachineLearningTractographyPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkMachineLearningTractographyPerspective.cpp index 74e31c3612..dee7fc5715 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkMachineLearningTractographyPerspective.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkMachineLearningTractographyPerspective.cpp @@ -1,50 +1,50 @@ /*=================================================================== 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 "QmitkMachineLearningTractographyPerspective.h" #include "berryIViewLayout.h" void QmitkMachineLearningTractographyPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) { ///////////////////////////////////////////////////// // all di-app perspectives should have the following: ///////////////////////////////////////////////////// QString editorArea = layout->GetEditorArea(); layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false); layout->AddStandaloneView("org.mitk.views.datamanager", false, berry::IPageLayout::LEFT, 0.3f, editorArea); layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview", false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager"); berry::IFolderLayout::Pointer left = layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols", berry::IPageLayout::BOTTOM, 0.1f, "org.mitk.views.controlvisualizationpropertiesview"); layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator", berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false); ///////////////////////////////////////////// // here goes the perspective specific stuff ///////////////////////////////////////////// - left->AddView("org.mitk.views.diffusionpreprocessing"); - left->AddView("org.mitk.views.segmentation"); left->AddView("org.mitk.views.mlbtview"); + left->AddView("org.mitk.views.segmentation"); + left->AddView("org.mitk.views.diffusionpreprocessing"); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkStreamlineTractographyPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkStreamlineTractographyPerspective.cpp index 03b705d96e..3cc35a996e 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkStreamlineTractographyPerspective.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/Perspectives/QmitkStreamlineTractographyPerspective.cpp @@ -1,50 +1,49 @@ /*=================================================================== 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 "QmitkStreamlineTractographyPerspective.h" #include "berryIViewLayout.h" void QmitkStreamlineTractographyPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) { ///////////////////////////////////////////////////// // all di-app perspectives should have the following: ///////////////////////////////////////////////////// QString editorArea = layout->GetEditorArea(); layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false); layout->AddStandaloneView("org.mitk.views.datamanager", false, berry::IPageLayout::LEFT, 0.3f, editorArea); layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview", false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager"); berry::IFolderLayout::Pointer left = layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols", berry::IPageLayout::BOTTOM, 0.1f, "org.mitk.views.controlvisualizationpropertiesview"); layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator", berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false); ///////////////////////////////////////////// // here goes the perspective specific stuff ///////////////////////////////////////////// - left->AddView("org.mitk.views.tensorreconstruction"); - left->AddView("org.mitk.views.segmentation"); left->AddView("org.mitk.views.streamlinetracking"); + left->AddView("org.mitk.views.segmentation"); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkMLBTView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkMLBTView.cpp index 523379b757..266c9c254c 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkMLBTView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkMLBTView.cpp @@ -1,449 +1,452 @@ /*=================================================================== 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. ===================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkMLBTView.h" // Qt #include #include #include #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include const std::string QmitkMLBTView::VIEW_ID = "org.mitk.views.mlbtview"; using namespace berry; QmitkMLBTView::QmitkMLBTView() : QmitkAbstractView() , m_Controls( 0 ) { m_TrackingTimer = std::make_shared(this); m_LastLoadedForestName = "(none)"; m_ForestHandler = new mitk::TrackingHandlerRandomForest<6,100>(); } // Destructor QmitkMLBTView::~QmitkMLBTView() { delete m_ForestHandler; } void QmitkMLBTView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkMLBTViewControls; m_Controls->setupUi( parent ); connect( m_Controls->m_StartTrainingButton, SIGNAL ( clicked() ), this, SLOT( StartTrainingThread() ) ); connect( &m_TrainingWatcher, SIGNAL ( finished() ), this, SLOT( OnTrainingThreadStop() ) ); connect( m_Controls->m_StartTrackingButton, SIGNAL ( clicked() ), this, SLOT( StartTrackingThread() ) ); connect( &m_TrackingWatcher, SIGNAL ( finished() ), this, SLOT( OnTrackingThreadStop() ) ); connect( m_Controls->m_SaveForestButton, SIGNAL ( clicked() ), this, SLOT( SaveForest() ) ); connect( m_Controls->m_LoadForestButton, SIGNAL ( clicked() ), this, SLOT( LoadForest() ) ); connect( m_TrackingTimer.get(), SIGNAL(timeout()), this, SLOT(BuildFibers()) ); connect( m_Controls->m_TimerIntervalBox, SIGNAL(valueChanged(int)), this, SLOT( ChangeTimerInterval(int) )); connect( m_Controls->m_DemoModeBox, SIGNAL(stateChanged(int)), this, SLOT( ToggleDemoMode(int) )); connect( m_Controls->m_PauseTrackingButton, SIGNAL ( clicked() ), this, SLOT( PauseTracking() ) ); connect( m_Controls->m_AbortTrackingButton, SIGNAL ( clicked() ), this, SLOT( AbortTracking() ) ); connect( m_Controls->m_AddTwButton, SIGNAL ( clicked() ), this, SLOT( AddTrainingWidget() ) ); connect( m_Controls->m_RemoveTwButton, SIGNAL ( clicked() ), this, SLOT( RemoveTrainingWidget() ) ); m_Controls->m_TrackingMaskImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_TrackingSeedImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_TrackingStopImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_TrackingRawImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_TissueImageBox->SetDataStorage(this->GetDataStorage()); mitk::NodePredicateIsDWI::Pointer isDiffusionImage = mitk::NodePredicateIsDWI::New(); mitk::TNodePredicateDataType::Pointer isMitkImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage); mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage); m_Controls->m_TissueImageBox->SetPredicate(finalPredicate); mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); finalPredicate = mitk::NodePredicateAnd::New(finalPredicate, isBinaryPredicate); m_Controls->m_TrackingMaskImageBox->SetPredicate(finalPredicate); m_Controls->m_TrackingSeedImageBox->SetPredicate(finalPredicate); m_Controls->m_TrackingStopImageBox->SetPredicate(finalPredicate); m_Controls->m_TrackingRawImageBox->SetPredicate(isDiffusionImage); m_Controls->m_TrackingMaskImageBox->SetZeroEntryText("--"); m_Controls->m_TrackingSeedImageBox->SetZeroEntryText("--"); m_Controls->m_TrackingStopImageBox->SetZeroEntryText("--"); m_Controls->m_TissueImageBox->SetZeroEntryText("--"); AddTrainingWidget(); UpdateGui(); } } void QmitkMLBTView::AddTrainingWidget() { std::shared_ptr tw = std::make_shared(); tw->SetDataStorage(this->GetDataStorage()); m_Controls->m_TwFrame->layout()->addWidget(tw.get()); m_TrainingWidgets.push_back(tw); } void QmitkMLBTView::RemoveTrainingWidget() { if(m_TrainingWidgets.size()>1) { m_TrainingWidgets.back().reset(); m_TrainingWidgets.pop_back(); } } void QmitkMLBTView::UpdateGui() { if (m_ForestHandler->IsForestValid()) { std::string label_text="Random forest available: "+m_LastLoadedForestName; m_Controls->statusLabel->setText( QString(label_text.c_str()) ); m_Controls->m_SaveForestButton->setEnabled(true); m_Controls->m_StartTrackingButton->setEnabled(true); } else { m_Controls->statusLabel->setText("Please load or train random forest!"); m_Controls->m_SaveForestButton->setEnabled(false); m_Controls->m_StartTrackingButton->setEnabled(false); } } void QmitkMLBTView::SetFocus() { m_Controls->toolBox->setFocus(); } void QmitkMLBTView::AbortTracking() { if (tracker.IsNotNull()) { tracker->m_AbortTracking = true; } } void QmitkMLBTView::PauseTracking() { if (tracker.IsNotNull()) { tracker->m_PauseTracking = !tracker->m_PauseTracking; } } void QmitkMLBTView::ChangeTimerInterval(int value) { m_TrackingTimer->setInterval(value); } void QmitkMLBTView::ToggleDemoMode(int state) { if (tracker.IsNotNull()) { tracker->SetDemoMode(m_Controls->m_DemoModeBox->isChecked()); tracker->m_Stop = false; } } void QmitkMLBTView::BuildFibers() { if (m_Controls->m_DemoModeBox->isChecked() && tracker.IsNotNull() && tracker->m_BuildFibersFinished) { vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); outFib->SetFiberColors(255,255,255); m_TractogramNode->SetData(outFib); m_SamplingPointsNode->SetData(tracker->m_SamplingPointset); m_AlternativePointsNode->SetData(tracker->m_AlternativePointset); m_StopVotePointsNode->SetData(tracker->m_StopVotePointset); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); tracker->m_BuildFibersFinished = false; tracker->m_BuildFibersReady = 0; tracker->m_Stop = false; } } void QmitkMLBTView::LoadForest() { QString filename = QFileDialog::getOpenFileName(0, tr("Load Forest"), QDir::currentPath(), tr("HDF5 random forest file (*.rf)") ); if(filename.isEmpty() || filename.isNull()) return; m_ForestHandler->LoadForest( filename.toStdString() ); QFileInfo fi( filename ); m_LastLoadedForestName = QString( fi.baseName() + "." + fi.completeSuffix() ).toStdString(); UpdateGui(); } void QmitkMLBTView::StartTrackingThread() { m_TractogramNode = mitk::DataNode::New(); m_TractogramNode->SetName("MLBT Result"); //m_TractogramNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(20)); m_TractogramNode->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(true)); m_TractogramNode->SetProperty("LineWidth", mitk::IntProperty::New(1)); //m_TractogramNode->SetProperty("color",mitk::ColorProperty::New(0, 1, 1)); this->GetDataStorage()->Add(m_TractogramNode); m_SamplingPointsNode = mitk::DataNode::New(); m_SamplingPointsNode->SetName("SamplingPoints"); m_SamplingPointsNode->SetProperty("pointsize", mitk::FloatProperty::New(0.2)); m_SamplingPointsNode->SetProperty("color", mitk::ColorProperty::New(1,1,1)); mitk::PointSetShapeProperty::Pointer bla = mitk::PointSetShapeProperty::New(); bla->SetValue(8); m_SamplingPointsNode->SetProperty("Pointset.2D.shape", bla); m_SamplingPointsNode->SetProperty("Pointset.2D.distance to plane", mitk::FloatProperty::New(1.5)); m_SamplingPointsNode->SetProperty("point 2D size", mitk::FloatProperty::New(0.1)); m_SamplingPointsNode->SetProperty("Pointset.2D.fill shape", mitk::BoolProperty::New(true)); this->GetDataStorage()->Add(m_SamplingPointsNode); m_AlternativePointsNode = mitk::DataNode::New(); m_AlternativePointsNode->SetName("AlternativePoints"); m_AlternativePointsNode->SetProperty("pointsize", mitk::FloatProperty::New(0.2)); m_AlternativePointsNode->SetProperty("color", mitk::ColorProperty::New(0,1,0)); m_AlternativePointsNode->SetProperty("Pointset.2D.shape", bla); m_AlternativePointsNode->SetProperty("Pointset.2D.distance to plane", mitk::FloatProperty::New(1.5)); m_AlternativePointsNode->SetProperty("point 2D size", mitk::FloatProperty::New(0.1)); m_AlternativePointsNode->SetProperty("Pointset.2D.fill shape", mitk::BoolProperty::New(true)); this->GetDataStorage()->Add(m_AlternativePointsNode); m_StopVotePointsNode = mitk::DataNode::New(); m_StopVotePointsNode->SetName("StopVotes"); m_StopVotePointsNode->SetProperty("pointsize", mitk::FloatProperty::New(0.2)); m_StopVotePointsNode->SetProperty("color", mitk::ColorProperty::New(1,0,0)); m_StopVotePointsNode->SetProperty("Pointset.2D.shape", bla); m_StopVotePointsNode->SetProperty("Pointset.2D.distance to plane", mitk::FloatProperty::New(1.5)); m_StopVotePointsNode->SetProperty("point 2D size", mitk::FloatProperty::New(0.1)); m_StopVotePointsNode->SetProperty("Pointset.2D.fill shape", mitk::BoolProperty::New(true)); this->GetDataStorage()->Add(m_StopVotePointsNode); QFuture future = QtConcurrent::run( this, &QmitkMLBTView::StartTracking ); m_TrackingWatcher.setFuture(future); m_TrackingThreadIsRunning = true; m_Controls->m_StartTrackingButton->setEnabled(false); m_TrackingTimer->start(m_Controls->m_TimerIntervalBox->value()); } void QmitkMLBTView::OnTrackingThreadStop() { m_TrackingThreadIsRunning = false; m_Controls->m_StartTrackingButton->setEnabled(true); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); m_TractogramNode->SetData(outFib); m_TractogramNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(1)); if (m_Controls->m_DemoModeBox->isChecked()) { m_SamplingPointsNode->SetData(tracker->m_SamplingPointset); m_AlternativePointsNode->SetData(tracker->m_AlternativePointset); } tracker = nullptr; m_TrackingTimer->stop(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkMLBTView::StartTracking() { if ( m_Controls->m_TrackingRawImageBox->GetSelectedNode().IsNull() || !m_ForestHandler->IsForestValid()) return; mitk::Image::Pointer dwi = dynamic_cast(m_Controls->m_TrackingRawImageBox->GetSelectedNode()->GetData()); m_ForestHandler->AddDwi(dwi); m_ForestHandler->SetMode(mitk::TrackingDataHandler::MODE::DETERMINISTIC); // int numThread = itk::MultiThreader::GetGlobalDefaultNumberOfThreads(); tracker = TrackerType::New(); tracker->SetDemoMode(m_Controls->m_DemoModeBox->isChecked()); if (m_Controls->m_DemoModeBox->isChecked()) tracker->SetNumberOfThreads(1); if (m_Controls->m_TrackingMaskImageBox->GetSelectedNode().IsNotNull()) { mitk::Image::Pointer mask = dynamic_cast(m_Controls->m_TrackingMaskImageBox->GetSelectedNode()->GetData()); ItkUcharImgType::Pointer itkMask = ItkUcharImgType::New(); mitk::CastToItkImage(mask, itkMask); tracker->SetMaskImage(itkMask); } if (m_Controls->m_TrackingSeedImageBox->GetSelectedNode().IsNotNull()) { mitk::Image::Pointer img = dynamic_cast(m_Controls->m_TrackingSeedImageBox->GetSelectedNode()->GetData()); ItkUcharImgType::Pointer itkImg = ItkUcharImgType::New(); mitk::CastToItkImage(img, itkImg); tracker->SetSeedImage(itkImg); } if (m_Controls->m_TrackingStopImageBox->GetSelectedNode().IsNotNull()) { mitk::Image::Pointer img = dynamic_cast(m_Controls->m_TrackingStopImageBox->GetSelectedNode()->GetData()); ItkUcharImgType::Pointer itkImg = ItkUcharImgType::New(); mitk::CastToItkImage(img, itkImg); tracker->SetStoppingRegions(itkImg); } if (m_Controls->m_TissueImageBox->GetSelectedNode().IsNotNull()) { mitk::Image::Pointer img = dynamic_cast(m_Controls->m_TissueImageBox->GetSelectedNode()->GetData()); ItkUcharImgType::Pointer itkImg = ItkUcharImgType::New(); mitk::CastToItkImage(img, itkImg); tracker->SetTissueImage(itkImg); } tracker->SetSeedsPerVoxel(m_Controls->m_NumberOfSeedsBox->value()); tracker->SetStepSize(m_Controls->m_TrackingStepSizeBox->value()); tracker->SetMinTractLength(m_Controls->m_MinLengthBox->value()); tracker->SetMaxTractLength(m_Controls->m_MaxLengthBox->value()); - tracker->SetAposterioriCurvCheck(m_Controls->m_Curvcheck2->isChecked()); + tracker->SetAposterioriCurvCheck(false); tracker->SetNumberOfSamples(m_Controls->m_NumSamplesBox->value()); - tracker->SetAvoidStop(m_Controls->m_AvoidStop->isChecked()); tracker->SetTrackingHandler(m_ForestHandler); tracker->SetSamplingDistance(m_Controls->m_SamplingDistanceBox->value()); - tracker->SetDeflectionMod(m_Controls->m_DeflectionModBox->value()); - tracker->SetRandomSampling(m_Controls->m_RandomSampling->isChecked()); - tracker->SetUseStopVotes(m_Controls->m_UseStopVotes->isChecked()); + tracker->SetUseStopVotes(m_Controls->m_OnlyForwardSamples->isChecked()); tracker->SetOnlyForwardSamples(m_Controls->m_OnlyForwardSamples->isChecked()); tracker->SetNumPreviousDirections(m_Controls->m_NumPrevDirs->value()); tracker->SetSeedOnlyGm(m_Controls->m_SeedGm->isChecked()); - tracker->SetAngularThreshold(45); tracker->Update(); } void QmitkMLBTView::SaveForest() { if (!m_ForestHandler->IsForestValid()) { UpdateGui(); return; } QString filename = QFileDialog::getSaveFileName(0, tr("Save Forest"), QDir::currentPath()+"/forest.rf", tr("HDF5 random forest file (*.rf)") ); if(filename.isEmpty() || filename.isNull()) return; if(!filename.endsWith(".rf")) filename += ".rf"; m_ForestHandler->SaveForest( filename.toStdString() ); } void QmitkMLBTView::StartTrainingThread() { if (!this->IsTrainingInputValid()) { QMessageBox::warning(nullptr, "Training aborted", "Training could not be started. Not all necessary datasets were selected."); return; } QFuture future = QtConcurrent::run( this, &QmitkMLBTView::StartTraining ); m_TrainingWatcher.setFuture(future); m_Controls->m_StartTrainingButton->setEnabled(false); + m_Controls->m_StartTrainingButton->setText("Training in progress ..."); + m_Controls->m_StartTrainingButton->setToolTip("Training in progress. This can take up to a couple of hours."); + m_Controls->m_StartTrainingButton->setCursor(Qt::WaitCursor); + QApplication::processEvents(); m_Controls->m_SaveForestButton->setEnabled(false); m_Controls->m_LoadForestButton->setEnabled(false); } void QmitkMLBTView::OnTrainingThreadStop() { m_Controls->m_StartTrainingButton->setEnabled(true); m_Controls->m_SaveForestButton->setEnabled(true); m_Controls->m_LoadForestButton->setEnabled(true); + m_Controls->m_StartTrainingButton->setCursor(Qt::ArrowCursor); + m_Controls->m_StartTrainingButton->setText("Start Training"); + m_Controls->m_StartTrainingButton->setToolTip("Start Training. This can take up to a couple of hours."); + m_LastLoadedForestName = "new_forest"; UpdateGui(); + QApplication::processEvents(); } void QmitkMLBTView::StartTraining() { std::vector< mitk::Image::Pointer > m_SelectedDiffImages; std::vector< mitk::FiberBundle::Pointer > m_SelectedFB; std::vector< ItkUcharImgType::Pointer > m_MaskImages; std::vector< ItkUcharImgType::Pointer > m_WhiteMatterImages; for (auto w : m_TrainingWidgets) { m_SelectedDiffImages.push_back(dynamic_cast(w->GetImage()->GetData())); m_SelectedFB.push_back(dynamic_cast(w->GetFibers()->GetData())); if (w->GetMask().IsNotNull()) { mitk::Image::Pointer img = dynamic_cast(w->GetMask()->GetData()); ItkUcharImgType::Pointer itkMask = ItkUcharImgType::New(); mitk::CastToItkImage(img, itkMask); m_MaskImages.push_back(itkMask); } else m_MaskImages.push_back(nullptr); if (w->GetWhiteMatter().IsNotNull()) { mitk::Image::Pointer img = dynamic_cast(w->GetWhiteMatter()->GetData()); ItkUcharImgType::Pointer itkMask = ItkUcharImgType::New(); mitk::CastToItkImage(img, itkMask); m_WhiteMatterImages.push_back(itkMask); } else m_WhiteMatterImages.push_back(nullptr); } m_ForestHandler->SetDwis(m_SelectedDiffImages); m_ForestHandler->SetTractograms(m_SelectedFB); m_ForestHandler->SetMaskImages(m_MaskImages); m_ForestHandler->SetWhiteMatterImages(m_WhiteMatterImages); m_ForestHandler->SetNumTrees(m_Controls->m_NumTreesBox->value()); m_ForestHandler->SetMaxTreeDepth(m_Controls->m_MaxDepthBox->value()); m_ForestHandler->SetGrayMatterSamplesPerVoxel(m_Controls->m_GmSamplingBox->value()); m_ForestHandler->SetSampleFraction(m_Controls->m_SampleFractionBox->value()); m_ForestHandler->SetStepSize(m_Controls->m_TrainingStepSizeBox->value()); m_ForestHandler->SetNumPreviousDirections(m_Controls->m_NumPrevDirs->value()); - m_ForestHandler->SetBidirectionalFiberSampling(m_Controls->m_BidirectionalSampling->isChecked()); - m_ForestHandler->SetZeroDirWmFeatures(m_Controls->m_ZeroDirBox->isChecked()); m_ForestHandler->StartTraining(); } bool QmitkMLBTView::IsTrainingInputValid(void) const { for (auto widget : m_TrainingWidgets) { if (widget->GetImage().IsNull() || widget->GetFibers().IsNull()) { return false; } } return true; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkMLBTViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkMLBTViewControls.ui index 86a7d00841..b1425836d6 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkMLBTViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkMLBTViewControls.ui @@ -1,905 +1,877 @@ QmitkMLBTViewControls 0 0 503 672 Form - + + + + Please load or train random forest! + + + Qt::AlignCenter + + + + 1 0 0 485 517 Training - + + + + Qt::Vertical + + + + 20 + 40 + + + + + QFrame::NoFrame QFrame::Raised 0 0 0 0 - - + + - Add additional training data pair + Remove training data pair ... - :/org_mitk_icons/icons/tango/scalable/actions/list-add.svg:/org_mitk_icons/icons/tango/scalable/actions/list-add.svg + :/org_mitk_icons/icons/tango/scalable/actions/list-remove.svg:/org_mitk_icons/icons/tango/scalable/actions/list-remove.svg - - + + - Remove training data pair + Add additional training data pair ... - :/org_mitk_icons/icons/tango/scalable/actions/list-remove.svg:/org_mitk_icons/icons/tango/scalable/actions/list-remove.svg + :/org_mitk_icons/icons/tango/scalable/actions/list-add.svg:/org_mitk_icons/icons/tango/scalable/actions/list-add.svg - - - - QFrame::NoFrame + + + + Start Training. This can take up to a couple of hours. - - QFrame::Raised + + Start Training - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Input DWI: - - - Qt::AlignCenter - - - - - - - Reference Tractogram: - - - Qt::AlignCenter - - - - - - - Mask: - - - Qt::AlignCenter - - - - - - - WM: - - - Qt::AlignCenter - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + - Start Training + Save Forest - - - - Use direction as well as zero-vector as directional training feature at each point. This enables to learn to predict the direction without a previous direction (e.g. at seed point). - + + - Zero-direction features + <html><head/><body><p><span style=" font-weight:600; color:#ff0000;">It is recommended to use the command line application 'RfTraining' instead of this graphical user interface for the training process.</span></p><p><span style=" font-weight:600; color:#ff0000;">The GUI is intended for testing using smaller examples.</span></p></body></html> - + + Qt::RichText + + + Qt::AlignCenter + + true + + 5 + - + QFrame::NoFrame QFrame::Raised 0 0 0 0 - - - - Maximum tree depth. + + + + Number of tress in the final random forest. 1 999999999 - 25 - - - - - - - Non-WM Sampling Points: + 30 - + Fiber Sampling: - - - - Number of tress in the final random forest. + + + + Maximum tree depth. 1 999999999 - 30 + 25 - + + + + Fraction of samples used to train each tree. + + + 3 + + + 1.000000000000000 + + + 0.100000000000000 + + + 0.700000000000000 + + + + Fiber sampling in mm. Determines the number of white-matter samples (-1 = auto). 3 -1.000000000000000 999.000000000000000 0.100000000000000 -1.000000000000000 + + + + Non-WM Sampling Points: + + + Num. Trees: - + + + + Max. Depth: + + + + Number of sampling points outside of the white-matter (-1 = automatic estimation). -1 999999999 -1 - - - - Max. Depth: - - - - + Sample Fraction: - - - - Fraction of samples used to train each tree. - - - 3 - - - 1.000000000000000 - - - 0.100000000000000 - - - 0.700000000000000 - - - - - - - Save Forest - - - - - - - Sample fibers in both directions. - - - Bidirectional sampling + + + + QFrame::NoFrame - - true + + QFrame::Raised + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Input DWI: + + + Qt::AlignCenter + + + + + + + Reference Tractogram: + + + Qt::AlignCenter + + + + + + + Mask: + + + Qt::AlignCenter + + + + + + + WM: + + + Qt::AlignCenter + + + + + + + 0 0 471 - 657 + 524 Tractography - + + + This requires a tissue segmentation image. + - Random sampling + Enable Gray Matter Seeding false - - + + QFrame::NoFrame QFrame::Raised - + 0 0 0 0 - - - - - - - 999999999.000000000000000 - - - 1.000000000000000 - - - 400.000000000000000 - - - - - - - Deflection distance modifier: - - - - - - - Number of seeds per voxel. - - - 1 - - - 999 - - - - - - - 1.000000000000000 - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - Num. Seeds: - - - - - - 0.100000000000000 - - - 0.500000000000000 - - + - - - Step Size: - - - - - + - Num. Samples: - - - - - - - 0.000000000000000 - - - - - - - 999999999.000000000000000 - - - 1.000000000000000 - - - 20.000000000000000 + Mask Image: - + - Sampling Distance: + Seed Image: - - - - Input DWI: - - + + - + - Max. Length + Stop Image: + + + - + - Min. Length + Tissue Image: - - - - Number of seeds per voxel. - - - 0 - - - 256 - - - 30 - - + + - - + + + + Only neighborhood samples in front of the current streamline position are considered. + - Secondary curvature check + Only Frontal Samples - false + true Load Forest - + + + + Qt::Vertical + + + + 20 + 40 + + + + + QFrame::NoFrame QFrame::Raised 0 0 0 0 + + Tractigraphy is visualized in slow-motion. Single threaded. + Demo Mode 1 1000 10 - + QFrame::NoFrame QFrame::Raised 0 0 0 0 Pause tractography ... :/org_mitk_icons/icons/tango/scalable/actions/media-playback-pause.svg:/org_mitk_icons/icons/tango/scalable/actions/media-playback-pause.svg Start tractography ... :/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg:/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg Abort tractography ... :/org_mitk_icons/icons/tango/scalable/actions/media-playback-stop.svg:/org_mitk_icons/icons/tango/scalable/actions/media-playback-stop.svg - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + QFrame::NoFrame QFrame::Raised - + 0 0 0 0 - + + + Number of neighborhood samples + + + + + + 0 + + + 256 + + + 30 + + - - + + + + Number of seeds per voxel. + + + + + + 1 + + + 999 + + + + + - Mask Image: + Seeds per Voxel: - - + + + + Maximum fiber length (in mm) + + + + + + 999999999.000000000000000 + + + 1.000000000000000 + + + 400.000000000000000 + + + + + + + + - Seed Image: + Input DWI: - - + + + + Max. Length + + - - + + - Stop Image: + Step Size: - - + + + + Minimum fiber length (in mm) + + + + + + 999999999.000000000000000 + + + 1.000000000000000 + + + 20.000000000000000 + + - - + + - Tissue Image: + Sampling Distance: - - + + + + Min. Length + + + + + + + Sampling distance (in voxels) + + + 0.100000000000000 + + + 0.250000000000000 + + + + + + + Step size (in voxels) + + + 0.500000000000000 + + + + + + + Num. Samples: + + - - - - Use stop votes - - - true - - - - - - - Avoid premature termination - - - true - - - - - - - Only frontal samples - - - true - - - - - - - Seed only GM - - - false - - - - - - - Please load or train random forest! - - - Qt::AlignCenter - - - - + Training and tractography 0 0 0 0 Num. previous directions: + + Number of previous fiber directions used as features. + - Number of seeds per voxel. + 0 50 1 - + Qt::Horizontal - QmitkDataStorageComboBox + QmitkDataStorageComboBoxWithSelectNone QComboBox -
QmitkDataStorageComboBox.h
+
QmitkDataStorageComboBoxWithSelectNone.h
- QmitkDataStorageComboBoxWithSelectNone + QmitkDataStorageComboBox QComboBox -
QmitkDataStorageComboBoxWithSelectNone.h
+
QmitkDataStorageComboBox.h
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingView.cpp index 1ba7a4f1f3..9b54bdbd44 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingView.cpp @@ -1,557 +1,562 @@ /*=================================================================== 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. ===================================================================*/ // Blueberry #include #include #include // Qmitk #include "QmitkStreamlineTrackingView.h" #include "QmitkStdMultiWidget.h" // Qt #include // MITK #include #include #include #include #include #include #include #include #include #include #include #include // VTK #include #include #include #include #include #include #include #include #include - const std::string QmitkStreamlineTrackingView::VIEW_ID = "org.mitk.views.streamlinetracking"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace berry; QmitkStreamlineTrackingView::QmitkStreamlineTrackingView() : m_Controls(nullptr) { } // Destructor QmitkStreamlineTrackingView::~QmitkStreamlineTrackingView() { } void QmitkStreamlineTrackingView::CreateQtPartControl( QWidget *parent ) { if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkStreamlineTrackingViewControls; m_Controls->setupUi( parent ); m_Controls->m_FaImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_SeedImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_MaskImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_StopImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_TissueImageBox->SetDataStorage(this->GetDataStorage()); mitk::TNodePredicateDataType::Pointer isImagePredicate = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer isNotBinaryPredicate = mitk::NodePredicateNot::New( isBinaryPredicate ); mitk::NodePredicateAnd::Pointer isNotABinaryImagePredicate = mitk::NodePredicateAnd::New( isImagePredicate, isNotBinaryPredicate ); mitk::NodePredicateDimension::Pointer dimensionPredicate = mitk::NodePredicateDimension::New(3); m_Controls->m_FaImageBox->SetPredicate( mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, dimensionPredicate) ); m_Controls->m_FaImageBox->SetZeroEntryText("--"); m_Controls->m_SeedImageBox->SetPredicate( mitk::NodePredicateAnd::New(isBinaryPredicate, dimensionPredicate) ); m_Controls->m_SeedImageBox->SetZeroEntryText("--"); m_Controls->m_MaskImageBox->SetPredicate( mitk::NodePredicateAnd::New(isBinaryPredicate, dimensionPredicate) ); m_Controls->m_MaskImageBox->SetZeroEntryText("--"); m_Controls->m_StopImageBox->SetPredicate( mitk::NodePredicateAnd::New(isBinaryPredicate, dimensionPredicate) ); m_Controls->m_StopImageBox->SetZeroEntryText("--"); m_Controls->m_TissueImageBox->SetPredicate( mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, dimensionPredicate) ); m_Controls->m_TissueImageBox->SetZeroEntryText("--"); connect( m_Controls->commandLinkButton, SIGNAL(clicked()), this, SLOT(DoFiberTracking()) ); connect( m_Controls->m_InteractiveBox, SIGNAL(stateChanged(int)), this, SLOT(ToggleInteractive()) ); connect( m_Controls->m_TissueImageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()) ); connect( m_Controls->m_ModeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()) ); m_FirstTensorProbRun = true; } UpdateGui(); } void QmitkStreamlineTrackingView::ToggleInteractive() { UpdateGui(); mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if ( m_Controls->m_InteractiveBox->isChecked() ) { + QApplication::setOverrideCursor(Qt::PointingHandCursor); + QApplication::processEvents(); + m_InteractiveNode = mitk::DataNode::New(); QString name("InteractiveFib"); m_InteractiveNode->SetName(name.toStdString()); GetDataStorage()->Add(m_InteractiveNode); m_InteractivePointSetNode = mitk::DataNode::New(); m_InteractivePointSetNode->SetProperty("color", mitk::ColorProperty::New(1,1,1)); m_InteractivePointSetNode->SetName("InteractiveSeedRegion"); mitk::PointSetShapeProperty::Pointer shape_prop = mitk::PointSetShapeProperty::New(); shape_prop->SetValue(mitk::PointSetShapeProperty::PointSetShape::CIRCLE); m_InteractivePointSetNode->SetProperty("Pointset.2D.shape", shape_prop); GetDataStorage()->Add(m_InteractivePointSetNode); if (renderWindow) { { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("axial"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkStreamlineTrackingView::OnSliceChanged ); m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("sagittal"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkStreamlineTrackingView::OnSliceChanged ); m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("coronal"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkStreamlineTrackingView::OnSliceChanged ); m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } } } else { + QApplication::restoreOverrideCursor(); + QApplication::processEvents(); + m_InteractiveNode = nullptr; m_InteractivePointSetNode = nullptr; mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("axial"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag1); slicer = renderWindow->GetQmitkRenderWindow(QString("sagittal"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag2); slicer = renderWindow->GetQmitkRenderWindow(QString("coronal"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag3); } } void QmitkStreamlineTrackingView::OnSliceChanged(const itk::EventObject& /*e*/) { std::srand(std::time(0)); m_SeedPoints.clear(); itk::Point world_pos = this->GetRenderWindowPart()->GetSelectedPosition(); m_SeedPoints.push_back(world_pos); float radius = m_Controls->m_SeedRadiusBox->value(); int num = m_Controls->m_NumSeedsBox->value(); mitk::PointSet::Pointer pointset = mitk::PointSet::New(); pointset->InsertPoint(0, world_pos); m_InteractivePointSetNode->SetProperty("pointsize", mitk::FloatProperty::New(radius*2)); m_InteractivePointSetNode->SetProperty("point 2D size", mitk::FloatProperty::New(radius*2)); m_InteractivePointSetNode->SetData(pointset); for (int i=1; i p; p[0] = rand()%1000-500; p[1] = rand()%1000-500; p[2] = rand()%1000-500; p.Normalize(); p *= radius; m_SeedPoints.push_back(world_pos+p); } DoFiberTracking(); } void QmitkStreamlineTrackingView::SetFocus() { } void QmitkStreamlineTrackingView::OnSelectionChanged( berry::IWorkbenchPart::Pointer part, const QList& nodes ) { m_InputImageNodes.clear(); m_InputImages.clear(); for( auto node : nodes ) { if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { if( dynamic_cast(node->GetData()) ) { m_InputImageNodes.push_back(node); m_InputImages.push_back(dynamic_cast(node->GetData())); } else if ( dynamic_cast(node->GetData()) ) { m_InputImageNodes.push_back(node); m_InputImages.push_back(dynamic_cast(node->GetData())); } else { mitk::Image* img = dynamic_cast(node->GetData()); if (img!=nullptr) { int dim = img->GetDimension(); unsigned int* dimensions = img->GetDimensions(); if (dim==4 && dimensions[3]%3==0) { m_InputImageNodes.push_back(node); m_InputImages.push_back(dynamic_cast(node->GetData())); } } } } } UpdateGui(); } void QmitkStreamlineTrackingView::UpdateGui() { m_Controls->m_TensorImageLabel->setText("mandatory"); m_Controls->m_fBox->setVisible(false); m_Controls->m_fLabel->setVisible(false); m_Controls->m_gBox->setVisible(false); m_Controls->m_gLabel->setVisible(false); m_Controls->m_FaImageBox->setVisible(false); m_Controls->mFaImageLabel->setVisible(false); m_Controls->m_NormalizeODFsBox->setVisible(false); if (m_Controls->m_TissueImageBox->GetSelectedNode().IsNotNull()) m_Controls->m_SeedGmBox->setVisible(true); else m_Controls->m_SeedGmBox->setVisible(false); if(!m_InputImageNodes.empty()) { if (m_InputImageNodes.size()>1) m_Controls->m_TensorImageLabel->setText(m_InputImageNodes.size()+" images selected"); else m_Controls->m_TensorImageLabel->setText(m_InputImageNodes.at(0)->GetName().c_str()); m_Controls->m_InputData->setTitle("Input Data"); m_Controls->commandLinkButton->setEnabled(!m_Controls->m_InteractiveBox->isChecked()); m_Controls->m_InteractiveBox->setEnabled(true); if ( dynamic_cast(m_InputImageNodes.at(0)->GetData()) ) { m_Controls->m_fBox->setVisible(true); m_Controls->m_fLabel->setVisible(true); m_Controls->m_gBox->setVisible(true); m_Controls->m_gLabel->setVisible(true); m_Controls->mFaImageLabel->setVisible(true); m_Controls->m_FaImageBox->setVisible(true); if (m_Controls->m_ModeBox->currentIndex()==1) m_Controls->m_NormalizeODFsBox->setVisible(true); } else if ( dynamic_cast(m_InputImageNodes.at(0)->GetData()) ) { m_Controls->mFaImageLabel->setVisible(true); m_Controls->m_FaImageBox->setVisible(true); m_Controls->m_NormalizeODFsBox->setVisible(true); } else { } } else { m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->commandLinkButton->setEnabled(!m_Controls->m_InteractiveBox->isChecked()); m_Controls->m_InteractiveBox->setEnabled(false); } } void QmitkStreamlineTrackingView::DoFiberTracking() { if (m_InputImages.empty()) return; mitk::TrackingDataHandler* trackingHandler; if( dynamic_cast(m_InputImageNodes.at(0)->GetData()) ) { typedef itk::Image< itk::DiffusionTensor3D, 3> TensorImageType; typedef mitk::ImageToItk CasterType; if (m_Controls->m_ModeBox->currentIndex()==1) { if (m_InputImages.size()>1) { QMessageBox::information(nullptr, "Information", "Probabilistic tensor tractography is only implemented for single-tensor mode!"); return; } if (m_FirstTensorProbRun) { QMessageBox::information(nullptr, "Information", "Internally calculating ODF from tensor image and performing probabilistic ODF tractography. Please keep the state of the ODF normalization box (see advanced parameters) in mind. TEND parameters are ignored."); m_FirstTensorProbRun = false; } TensorImageType::Pointer itkImg = TensorImageType::New(); mitk::CastToItkImage(m_InputImages.at(0), itkImg); typedef itk::TensorImageToQBallImageFilter< float, float > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkImg ); filter->Update(); typedef mitk::ImageToItk< mitk::TrackingHandlerOdf::ItkOdfImageType > CasterType; trackingHandler = new mitk::TrackingHandlerOdf(); dynamic_cast(trackingHandler)->SetOdfImage(filter->GetOutput()); dynamic_cast(trackingHandler)->SetGfaThreshold(m_Controls->m_ScalarThresholdBox->value()); dynamic_cast(trackingHandler)->SetMinMaxNormalize(m_Controls->m_NormalizeODFsBox->isChecked()); dynamic_cast(trackingHandler)->SetOdfPower(1); if (m_Controls->m_FaImageBox->GetSelectedNode().IsNotNull()) { ItkFloatImageType::Pointer itkImg = ItkFloatImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_FaImageBox->GetSelectedNode()->GetData()), itkImg); dynamic_cast(trackingHandler)->SetGfaImage(itkImg); } } else { trackingHandler = new mitk::TrackingHandlerTensor(); for (int i=0; i<(int)m_InputImages.size(); i++) { TensorImageType::Pointer itkImg = TensorImageType::New(); mitk::CastToItkImage(m_InputImages.at(i), itkImg); dynamic_cast(trackingHandler)->AddTensorImage(itkImg); } if (m_Controls->m_FaImageBox->GetSelectedNode().IsNotNull()) { ItkFloatImageType::Pointer itkImg = ItkFloatImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_FaImageBox->GetSelectedNode()->GetData()), itkImg); dynamic_cast(trackingHandler)->SetFaImage(itkImg); } dynamic_cast(trackingHandler)->SetFaThreshold(m_Controls->m_ScalarThresholdBox->value()); dynamic_cast(trackingHandler)->SetF((float)m_Controls->m_fBox->value()); dynamic_cast(trackingHandler)->SetG((float)m_Controls->m_gBox->value()); } } else if ( dynamic_cast(m_InputImageNodes.at(0)->GetData()) ) { typedef mitk::ImageToItk< mitk::TrackingHandlerOdf::ItkOdfImageType > CasterType; trackingHandler = new mitk::TrackingHandlerOdf(); mitk::TrackingHandlerOdf::ItkOdfImageType::Pointer itkImg = mitk::TrackingHandlerOdf::ItkOdfImageType::New(); mitk::CastToItkImage(m_InputImages.at(0), itkImg); dynamic_cast(trackingHandler)->SetOdfImage(itkImg); dynamic_cast(trackingHandler)->SetGfaThreshold(m_Controls->m_ScalarThresholdBox->value()); dynamic_cast(trackingHandler)->SetMinMaxNormalize(m_Controls->m_NormalizeODFsBox->isChecked()); if (m_Controls->m_FaImageBox->GetSelectedNode().IsNotNull()) { ItkFloatImageType::Pointer itkImg = ItkFloatImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_FaImageBox->GetSelectedNode()->GetData()), itkImg); dynamic_cast(trackingHandler)->SetGfaImage(itkImg); } } else { if (m_Controls->m_ModeBox->currentIndex()==1) { QMessageBox::information(nullptr, "Information", "Probabilstic tractography is only implementedfor ODF images."); return; } try { typedef mitk::ImageToItk< mitk::TrackingHandlerPeaks::PeakImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(m_InputImages.at(0)); caster->Update(); mitk::TrackingHandlerPeaks::PeakImgType::Pointer itkImg = caster->GetOutput(); trackingHandler = new mitk::TrackingHandlerPeaks(); dynamic_cast(trackingHandler)->SetPeakImage(itkImg); dynamic_cast(trackingHandler)->SetPeakThreshold(m_Controls->m_ScalarThresholdBox->value()); } catch(...) { return; } } trackingHandler->SetFlipX(m_Controls->m_FlipXBox->isChecked()); trackingHandler->SetFlipY(m_Controls->m_FlipYBox->isChecked()); trackingHandler->SetFlipZ(m_Controls->m_FlipZBox->isChecked()); trackingHandler->SetInterpolate(m_Controls->m_InterpolationBox->isChecked()); switch (m_Controls->m_ModeBox->currentIndex()) { case 0: trackingHandler->SetMode(mitk::TrackingDataHandler::MODE::DETERMINISTIC); break; case 1: trackingHandler->SetMode(mitk::TrackingDataHandler::MODE::PROBABILISTIC); break; default: trackingHandler->SetMode(mitk::TrackingDataHandler::MODE::DETERMINISTIC); } typedef itk::StreamlineTrackingFilter TrackerType; TrackerType::Pointer tracker = TrackerType::New(); if (m_Controls->m_InteractiveBox->isChecked()) { tracker->SetSeedPoints(m_SeedPoints); } else if (m_Controls->m_SeedImageBox->GetSelectedNode().IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_SeedImageBox->GetSelectedNode()->GetData()), mask); tracker->SetSeedImage(mask); } if (m_Controls->m_MaskImageBox->GetSelectedNode().IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_MaskImageBox->GetSelectedNode()->GetData()), mask); tracker->SetMaskImage(mask); } if (m_Controls->m_StopImageBox->GetSelectedNode().IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_StopImageBox->GetSelectedNode()->GetData()), mask); tracker->SetStoppingRegions(mask); } if (m_Controls->m_TissueImageBox->GetSelectedNode().IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_TissueImageBox->GetSelectedNode()->GetData()), mask); tracker->SetTissueImage(mask); tracker->SetSeedOnlyGm(m_Controls->m_SeedGmBox->isChecked()); } tracker->SetSeedsPerVoxel(m_Controls->m_SeedsPerVoxelBox->value()); tracker->SetStepSize(m_Controls->m_StepSizeBox->value()); //tracker->SetSamplingDistance(0.7); tracker->SetUseStopVotes(false); tracker->SetOnlyForwardSamples(false); tracker->SetAposterioriCurvCheck(false); tracker->SetMaxNumTracts(m_Controls->m_NumFibersBox->value()); tracker->SetNumberOfSamples(m_Controls->m_NumSamplesBox->value()); tracker->SetTrackingHandler(trackingHandler); tracker->SetAngularThreshold(m_Controls->m_AngularThresholdBox->value()); tracker->SetMinTractLength(m_Controls->m_MinTractLengthBox->value()); tracker->SetUseOutputProbabilityMap(m_Controls->m_OutputProbMap->isChecked() && !m_Controls->m_InteractiveBox->isChecked()); tracker->Update(); delete trackingHandler; if (m_Controls->m_InteractiveBox->isChecked()) { vtkSmartPointer fiberBundle = tracker->GetFiberPolyData(); if (m_InteractiveNode.IsNull()) { m_InteractiveNode = mitk::DataNode::New(); QString name("InteractiveFib"); m_InteractiveNode->SetName(name.toStdString()); GetDataStorage()->Add(m_InteractiveNode); } mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(fiberBundle); fib->SetReferenceGeometry(dynamic_cast(m_InputImageNodes.at(0)->GetData())->GetGeometry()); if (m_Controls->m_ResampleFibersBox->isChecked()) fib->Compress(m_Controls->m_FiberErrorBox->value()); m_InteractiveNode->SetData(fib); } else if (!tracker->GetUseOutputProbabilityMap()) { vtkSmartPointer fiberBundle = tracker->GetFiberPolyData(); if (fiberBundle->GetNumberOfLines() == 0) { QMessageBox warnBox; warnBox.setWindowTitle("Warning"); warnBox.setText("No fiberbundle was generated!"); warnBox.setDetailedText("No fibers were generated using the parameters: \n\n" + m_Controls->m_FaThresholdLabel->text() + "\n" + m_Controls->m_AngularThresholdLabel->text() + "\n" + m_Controls->m_fLabel->text() + "\n" + m_Controls->m_gLabel->text() + "\n" + m_Controls->m_StepsizeLabel->text() + "\n" + m_Controls->m_MinTractLengthLabel->text() + "\n" + m_Controls->m_SeedsPerVoxelLabel->text() + "\n\nPlease check your parametersettings."); warnBox.setIcon(QMessageBox::Warning); warnBox.exec(); return; } mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(fiberBundle); fib->SetReferenceGeometry(dynamic_cast(m_InputImageNodes.at(0)->GetData())->GetGeometry()); if (m_Controls->m_ResampleFibersBox->isChecked()) fib->Compress(m_Controls->m_FiberErrorBox->value()); fib->ColorFibersByOrientation(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(fib); QString name("FiberBundle_"); name += m_InputImageNodes.at(0)->GetName().c_str(); name += "_Streamline"; node->SetName(name.toStdString()); GetDataStorage()->Add(node, m_InputImageNodes.at(0)); } else { TrackerType::ItkDoubleImgType::Pointer outImg = tracker->GetOutputProbabilityMap(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); QString name("ProbabilityMap_"); name += m_InputImageNodes.at(0)->GetName().c_str(); node->SetName(name.toStdString()); mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); lut->SetType(mitk::LookupTable::JET_TRANSPARENT); mitk::LookupTableProperty::Pointer lut_prop = mitk::LookupTableProperty::New(); lut_prop->SetLookupTable(lut); node->SetProperty("LookupTable", lut_prop); node->SetProperty("opacity", mitk::FloatProperty::New(0.5)); GetDataStorage()->Add(node, m_InputImageNodes.at(0)); } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingViewControls.ui index 96b98a3cdf..e1660a9ab8 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingViewControls.ui @@ -1,765 +1,771 @@ QmitkStreamlineTrackingViewControls 0 0 358 - 779 + 878 0 0 QmitkTemplate 0 0 3 3 Please Select Input Data Only track insida mask area. Mask Image: Fibers that enter a region defined in this image will stop immediately. QComboBox::AdjustToMinimumContentsLength - If an image is selected, the stopping criterion is not calculated from the input image but instead the selected image is used. QComboBox::AdjustToMinimumContentsLength - Binary seed ROI. If not specified, the whole image area is seeded. Seed Image: <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> true Seed points are only placed inside the mask image. QComboBox::AdjustToMinimumContentsLength - Only track insida mask area. Stop Image: Input DTI Tensor/Peak/ODF Image: Only track insida mask area. FA/GFA Image: Tractography is only performed inside the mask image. Fibers that leave the mask image are stopped. QComboBox::AdjustToMinimumContentsLength - Only track insida mask area. Tissue Image: Tissue label image needed for gray matter seeding (WM=3, GM=1). Use e.g. MRtrix 5ttgen to generate such a label image. QComboBox::AdjustToMinimumContentsLength - false Start Tractography 0 0 Parameters Mode: Toggle between deterministic and probabilistic tractography. Some modes might not be available for all types of tractography. Deterministic Probabilistic Seeds per Voxel: Number of seed points placed in each voxel. 1 9999999 Max. num. fibers: Tractography is stopped after the desired number of fibers is reached, even before all seed points are processed. 999999999 Cutoff: Threshold on peak magnitude, FA, GFA, ... 5 1.000000000000000 0.100000000000000 0.100000000000000 Qt::Horizontal QSizePolicy::Fixed 200 0 Advanced Paramaters Step Size: Step size (in voxels) 2 0.010000000000000 10.000000000000000 0.100000000000000 0.500000000000000 Angular Threshold: Default: 90° * step_size -1 90 1 -1 Min. Tract Length: Shorter fibers are discarded. + + Minimum fiber length (in mm) + 1 999.000000000000000 1.000000000000000 20.000000000000000 f parameter of tensor tractography. f=1 + g=0 means FACT (depending on the chosen interpolation). f=0 and g=1 means TEND (disable interpolation for this mode!). f: f=1 + g=0 means FACT (depending on the chosen interpolation). f=0 and g=1 means TEND (disable interpolation for this mode!). 2 1.000000000000000 0.100000000000000 1.000000000000000 g: f=1 + g=0 means FACT (depending on the chosen interpolation). f=0 and g=1 means TEND (disable interpolation for this mode!). 2 1.000000000000000 0.100000000000000 0.000000000000000 Flip directions: QFrame::NoFrame QFrame::Raised 0 0 0 0 Internally flips progression directions. This might be necessary depending on the input data. x Internally flips progression directions. This might be necessary depending on the input data. y Internally flips progression directions. This might be necessary depending on the input data. z Neighborhood Samples: Number of neighborhood samples that are used to determine the next fiber progression direction. 50 Resample fibers using the specified error constraint. Compress Fibers true Qt::StrongFocus Lossy fiber compression. Recommended for large tractograms. Maximum error in mm. 3 10.000000000000000 0.010000000000000 0.100000000000000 If false, nearest neighbor interpolation is used. Enable Trilinear Interpolation true Requires tissue image. - Enable gray matter seeding + Enable Gray Matter Seeding false - Min-max normalize ODFs + Min-max Normalize ODFs true Output probability map instead of tractogram. - Output probability map + Output Probability Map false Qt::Vertical QSizePolicy::Expanding 20 220 0 0 - Interactive Tracking + Interactive Tractography Radius: false + + Dynamically pick seed location by click into image. + - Enable interactive tracking + Enable Interactive Tractography Num. Seeds: Number of seed points normally distributed around selected position. 1 9999999 50 - Seedpoints are normally distributed within a sphere centered at the selected position with the specified radius. + Seedpoints are normally distributed within a sphere centered at the selected position with the specified radius (in mm). 2 50.000000000000000 0.100000000000000 2.500000000000000 QmitkDataStorageComboBoxWithSelectNone QComboBox
QmitkDataStorageComboBoxWithSelectNone.h