diff --git a/CMake/BuildConfigurations/DiffusionAll.cmake b/CMake/BuildConfigurations/DiffusionAll.cmake index e955462..b778da8 100644 --- a/CMake/BuildConfigurations/DiffusionAll.cmake +++ b/CMake/BuildConfigurations/DiffusionAll.cmake @@ -1,32 +1,33 @@ message(STATUS "Configuring MITK Diffusion with all Plugins") # 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) set(MITK_USE_MatchPoint ON CACHE BOOL "" FORCE) set(MITK_USE_DCMTK ON CACHE BOOL "" FORCE) set(MITK_USE_DCMQI ON CACHE BOOL "" FORCE) set(MITK_USE_OpenMP ON CACHE BOOL "" FORCE) set(MITK_USE_Python3 ON CACHE BOOL "" FORCE) set(MITK_USE_BetData ON CACHE BOOL "" FORCE) set(MITK_BUILD_APP_Diffusion ON CACHE BOOL "Build MITK Diffusion" FORCE) +set(BUILD_DiffusionFiberQuantificationCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber quantification" 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) set(BUILD_DiffusionPythonCmdApps ON CACHE BOOL "Build commandline tools for diffusion with python" FORCE) # Build neither all plugins nor examples set(BUILD_TESTING ON CACHE BOOL "Build the MITK tests" 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 ON CACHE BOOL "Use this to enable or disable the console window when starting MITK GUI Applications" FORCE) diff --git a/CMake/BuildConfigurations/DiffusionCmdApps_NoPython.cmake b/CMake/BuildConfigurations/DiffusionCmdApps_NoPython.cmake index 9e80568..c2d00a6 100644 --- a/CMake/BuildConfigurations/DiffusionCmdApps_NoPython.cmake +++ b/CMake/BuildConfigurations/DiffusionCmdApps_NoPython.cmake @@ -1,39 +1,40 @@ set(BUILD_TESTING OFF CACHE BOOL "" FORCE) 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) set(BUILD_TESTING OFF CACHE BOOL "Build the MITK tests" FORCE) set(MITK_USE_BLUEBERRY OFF CACHE BOOL "" FORCE) set(MITK_USE_CTK OFF CACHE BOOL "" FORCE) set(MITK_USE_Qt5 OFF CACHE BOOL "" FORCE) set(MITK_USE_Qwt OFF CACHE BOOL "" FORCE) set(MITK_DOXYGEN_GENERATE_QCH_FILES OFF CACHE BOOL "Use doxygen to generate Qt compressed help files for MITK docs" FORCE) set(BLUEBERRY_USE_QT_HELP OFF CACHE BOOL "Enable support for integrating bundle documentation into Qt Help" FORCE) set(MITK_USE_Vigra ON CACHE BOOL "MITK Use Vigra Library" FORCE) set(MITK_USE_HDF5 ON CACHE BOOL "MITK Use HDF5 Library" FORCE) set(MITK_USE_MatchPoint ON CACHE BOOL "" FORCE) set(MITK_USE_DCMTK ON CACHE BOOL "" FORCE) set(MITK_USE_DCMQI ON CACHE BOOL "" FORCE) set(MITK_USE_OpenMP ON CACHE BOOL "" FORCE) set(MITK_USE_Python3 OFF CACHE BOOL "" FORCE) # Activate Diffusion Mini Apps +set(BUILD_DiffusionFiberQuantificationCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber quantification" 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) set(BUILD_DiffusionPythonCmdApps OFF CACHE BOOL "Build commandline tools for diffusion with python" FORCE) set(MITK_CUSTOM_REVISION_DESC "DiffusionCmdApps" CACHE STRING "" FORCE) ## Build neither all plugins nor examples #set(MITK_WHITELIST "DiffusionQuantificationCmdApps" CACHE STRING "" FORCE) #if(NOT MITK_USE_SUPERBUILD) # set(BUILD_DiffusionQuantificationCmdApps ON CACHE BOOL "" FORCE) #endif() diff --git a/CMake/BuildConfigurations/DiffusionRelease.cmake b/CMake/BuildConfigurations/DiffusionRelease.cmake index 230d9e1..1de9a0f 100644 --- a/CMake/BuildConfigurations/DiffusionRelease.cmake +++ b/CMake/BuildConfigurations/DiffusionRelease.cmake @@ -1,44 +1,45 @@ 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) set(MITK_USE_MatchPoint ON CACHE BOOL "" FORCE) set(MITK_USE_DCMTK ON CACHE BOOL "" FORCE) set(MITK_USE_DCMQI ON CACHE BOOL "" FORCE) set(MITK_USE_OpenMP ON CACHE BOOL "" FORCE) set(MITK_USE_Python3 ON CACHE BOOL "" FORCE) set(MITK_USE_BetData ON CACHE BOOL "" FORCE) set(BUILD_DiffusionPythonCmdApps ON CACHE BOOL "Build commandline tools for diffusion with python" 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_DiffusionFiberQuantificationCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber quantification" 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) set(BUILD_TESTING OFF CACHE BOOL "Build the MITK tests" 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) # Enable console window set(MITK_SHOW_CONSOLE_WINDOW ON CACHE BOOL "Use this to enable or disable the console window when starting MITK GUI Applications" FORCE) set(MITK_VTK_DEBUG_LEAKS OFF CACHE BOOL "" FORCE) set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE) set(MITK_CUSTOM_REVISION_DESC "MITK-Diffusion" CACHE STRING "" FORCE) diff --git a/CMake/BuildConfigurations/DiffusionRelease_NoPython.cmake b/CMake/BuildConfigurations/DiffusionRelease_NoPython.cmake index 659aa29..77a32d4 100644 --- a/CMake/BuildConfigurations/DiffusionRelease_NoPython.cmake +++ b/CMake/BuildConfigurations/DiffusionRelease_NoPython.cmake @@ -1,43 +1,44 @@ 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) set(MITK_USE_MatchPoint ON CACHE BOOL "" FORCE) set(MITK_USE_DCMTK ON CACHE BOOL "" FORCE) set(MITK_USE_DCMQI ON CACHE BOOL "" FORCE) set(MITK_USE_OpenMP ON CACHE BOOL "" FORCE) set(MITK_USE_Python3 OFF CACHE BOOL "" 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_DiffusionFiberQuantificationCmdApps ON CACHE BOOL "Build commandline tools for diffusion fiber quantification" 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) set(BUILD_DiffusionPythonCmdApps OFF CACHE BOOL "Build commandline tools for diffusion with python" 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) set(BUILD_TESTING OFF CACHE BOOL "Build the MITK tests" 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) # Enable console window set(MITK_SHOW_CONSOLE_WINDOW ON CACHE BOOL "Use this to enable or disable the console window when starting MITK GUI Applications" FORCE) set(MITK_VTK_DEBUG_LEAKS OFF CACHE BOOL "" FORCE) set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE) set(MITK_CUSTOM_REVISION_DESC "MITK-Diffusion-NoPython" CACHE STRING "" FORCE) diff --git a/Modules/DiffusionCmdApps/CMakeLists.txt b/Modules/DiffusionCmdApps/CMakeLists.txt index 34ed260..1d2ba7c 100644 --- a/Modules/DiffusionCmdApps/CMakeLists.txt +++ b/Modules/DiffusionCmdApps/CMakeLists.txt @@ -1,20 +1,21 @@ MITK_CREATE_MODULE( SUBPROJECTS MITK-Diffusion # INCLUDE_DIRS Helpers DEPENDS MitkDiffusionCore MitkCommandLine PACKAGE_DEPENDS PUBLIC ITK ) if(MODULE_IS_ENABLED) add_subdirectory(Connectomics) add_subdirectory(Fiberfox) add_subdirectory(FiberProcessing) add_subdirectory(Tractography) add_subdirectory(TractographyEvaluation) add_subdirectory(Misc) - add_subdirectory(Quantification) + add_subdirectory(ImageQuantification) + add_subdirectory(FiberQuantification) if(MITK_USE_Python3) add_subdirectory(Python) endif() endif() diff --git a/Modules/DiffusionCmdApps/FiberProcessing/CMakeLists.txt b/Modules/DiffusionCmdApps/FiberProcessing/CMakeLists.txt index a15b7a2..f58e95d 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/CMakeLists.txt +++ b/Modules/DiffusionCmdApps/FiberProcessing/CMakeLists.txt @@ -1,51 +1,46 @@ 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( diffusionFiberProcessingcmdapps - TractDensity^^ Sift2WeightCopy^^ FiberExtraction^^ FiberExtractionRoi^^ FiberProcessing^^ FitFibersToImage^^ FiberDirectionExtraction^^ FiberJoin^^ FiberClustering^^ TractDensityFilter^^ - PrintFiberStatistics^^ - DistanceToSegmentation^^ - TractParcellation^^ - TractometryComparison^^ ) foreach(diffusionFiberProcessingcmdapp ${diffusionFiberProcessingcmdapps}) # extract cmd app name and dependencies 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 MitkDiffusionCmdApps MitkMriSimulation MitkFiberTracking ${dependencies_list} PACKAGE_DEPENDS ) endforeach() if(EXECUTABLE_IS_ENABLED) MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET}) endif() endif() diff --git a/Modules/DiffusionCmdApps/FiberProcessing/CMakeLists.txt b/Modules/DiffusionCmdApps/FiberQuantification/CMakeLists.txt similarity index 76% copy from Modules/DiffusionCmdApps/FiberProcessing/CMakeLists.txt copy to Modules/DiffusionCmdApps/FiberQuantification/CMakeLists.txt index a15b7a2..235e276 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/CMakeLists.txt +++ b/Modules/DiffusionCmdApps/FiberQuantification/CMakeLists.txt @@ -1,51 +1,43 @@ -option(BUILD_DiffusionFiberProcessingCmdApps "Build commandline tools for diffusion fiber processing" OFF) +option(BUILD_DiffusionFiberQuantificationCmdApps "Build commandline tools for diffusion fiber processing" OFF) -if(BUILD_DiffusionFiberProcessingCmdApps OR MITK_BUILD_ALL_APPS) +if(BUILD_DiffusionFiberQuantificationCmdApps 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( diffusionFiberProcessingcmdapps TractDensity^^ - Sift2WeightCopy^^ - FiberExtraction^^ - FiberExtractionRoi^^ - FiberProcessing^^ - FitFibersToImage^^ - FiberDirectionExtraction^^ - FiberJoin^^ - FiberClustering^^ - TractDensityFilter^^ PrintFiberStatistics^^ DistanceToSegmentation^^ TractParcellation^^ TractometryComparison^^ + EstimateNumSamplesForTractometry^^ ) foreach(diffusionFiberProcessingcmdapp ${diffusionFiberProcessingcmdapps}) # extract cmd app name and dependencies 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 MitkDiffusionCmdApps MitkMriSimulation MitkFiberTracking ${dependencies_list} PACKAGE_DEPENDS ) endforeach() if(EXECUTABLE_IS_ENABLED) MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET}) endif() endif() diff --git a/Modules/DiffusionCmdApps/FiberProcessing/DistanceToSegmentation.cpp b/Modules/DiffusionCmdApps/FiberQuantification/DistanceToSegmentation.cpp similarity index 99% rename from Modules/DiffusionCmdApps/FiberProcessing/DistanceToSegmentation.cpp rename to Modules/DiffusionCmdApps/FiberQuantification/DistanceToSegmentation.cpp index 2fdd86f..39488f9 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/DistanceToSegmentation.cpp +++ b/Modules/DiffusionCmdApps/FiberQuantification/DistanceToSegmentation.cpp @@ -1,169 +1,169 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include typedef itk::Image ItkFloatImgType; /*! \brief */ int main(int argc, char* argv[]) { mitkDiffusionCommandLineParser parser; parser.setTitle("Calcualte distance between segmentation mesh and fibers in form of a mask or TDI"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Fiber Quantification Methods"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("tracts", "", mitkDiffusionCommandLineParser::String, "Tracts:", "input fiber tracts (as tractogram or as tract density iumage (TDI))", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); parser.addArgument("surface", "", mitkDiffusionCommandLineParser::String, "Segmentation:", "input segmentation mesh (.vtp)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); parser.addArgument("out_dists", "", mitkDiffusionCommandLineParser::String, "Output:", "output text file", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Output); parser.addArgument("out_image", "", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Output); parser.addArgument("thresholds", "", mitkDiffusionCommandLineParser::StringList, "Thresholds:", "distances for which voxels are counted", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string in_tracts = us::any_cast(parsedArgs["tracts"]); std::string in_seg = us::any_cast(parsedArgs["surface"]); std::string out_dists = ""; if (parsedArgs.count("out_dists")) out_dists = us::any_cast(parsedArgs["out_dists"]); std::string out_image = ""; if (parsedArgs.count("out_image")) out_image = us::any_cast(parsedArgs["out_image"]); std::vector< std::string > thresholds_str = {"0.0", "3.0", "5.0", "7.0"}; std::vector< float > thresholds; if (parsedArgs.count("thresholds")) thresholds_str = us::any_cast(parsedArgs["thresholds"]); for (auto s : thresholds_str) thresholds.push_back(boost::lexical_cast(s)); try { ItkFloatImgType::Pointer inputItkTDI; auto input= mitk::IOUtil::Load(in_tracts); if (dynamic_cast(input.GetPointer())) { mitk::CastToItkImage(dynamic_cast(input.GetPointer()), inputItkTDI); } else { mitk::FiberBundle::Pointer intput_tracts= dynamic_cast(input.GetPointer()); itk::TractDensityImageFilter< ItkFloatImgType >::Pointer tdi_filter = itk::TractDensityImageFilter< ItkFloatImgType >::New(); tdi_filter->SetFiberBundle(intput_tracts); tdi_filter->SetMode(TDI_MODE::DENSITY); tdi_filter->SetOutputAbsoluteValues(false); tdi_filter->Update(); inputItkTDI = tdi_filter->GetOutput(); } mitk::Surface::Pointer inputSeg = mitk::IOUtil::Load(in_seg); typedef itk::DistanceFromSegmentationImageFilter< float > ImageGeneratorType; ImageGeneratorType::Pointer filter = ImageGeneratorType::New(); filter->SetInput(inputItkTDI); filter->SetSegmentationSurface(inputSeg); filter->SetThresholds(thresholds); filter->Update(); auto volume = inputItkTDI->GetSpacing()[0]*inputItkTDI->GetSpacing()[1]*inputItkTDI->GetSpacing()[2]; MITK_INFO << "Tractogram file: " << in_tracts; MITK_INFO << "Segmentation surface file: " << in_seg; MITK_INFO << "Reference image spacing: " << inputItkTDI->GetSpacing(); MITK_INFO << "Distance between surface and closest fiber-containing voxel-center: " << filter->GetMinDistance() << " mm"; for (unsigned int i=0; iGetThresholds().size(); ++i) MITK_INFO << "Voxels closer than " << filter->GetThresholds().at(i) << " mm: " << filter->GetCounts().at(i) << " (" << filter->GetCounts().at(i)*volume << " mm³)"; if (!out_dists.empty()) { MITK_INFO << "Saving data to text file: " << out_dists; std::ofstream statistics_file; statistics_file.open(out_dists, std::ios_base::out | std::ios_base::app); statistics_file << "MITK Diffusion git commit hash: " << MITKDIFFUSION_REVISION << std::endl; statistics_file << "MITK Diffusion branch name: " << MITKDIFFUSION_REVISION_NAME << std::endl; statistics_file << "MITK git commit hash: " << MITK_REVISION << std::endl; statistics_file << "MITK branch name: " << MITK_REVISION_NAME << std::endl; boost::posix_time::ptime timeLocal = boost::posix_time::second_clock::local_time(); statistics_file << "Current System Time = " << timeLocal << std::endl; statistics_file << "Tractogram file: " << in_tracts << std::endl; statistics_file << "Segmentation surface file: " << in_seg << std::endl; statistics_file << "Reference image spacing: " << inputItkTDI->GetSpacing() << std::endl; statistics_file << "Distance between surface and closest fiber-containing voxel-center: " << filter->GetMinDistance() << " mm" << std::endl; for (unsigned int i=0; iGetThresholds().size(); ++i) statistics_file << "Voxels closer than " << filter->GetThresholds().at(i) << " mm: " << filter->GetCounts().at(i) << " (" << filter->GetCounts().at(i)*volume << " mm³)" << std::endl; statistics_file << "-------------------------------------------------\n\n" << std::endl; statistics_file.close(); } // save image containing voxel-wise distances if (!out_image.empty()) { MITK_INFO << "Saving voxel-wise distances to image file: " << out_image; auto outImg = filter->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg); img->SetVolume(outImg->GetBufferPointer()); mitk::IOUtil::Save(img, out_image ); } } catch (const itk::ExceptionObject& e) { std::cout << e.what(); 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/DiffusionCmdApps/FiberQuantification/EstimateNumSamplesForTractometry.cpp b/Modules/DiffusionCmdApps/FiberQuantification/EstimateNumSamplesForTractometry.cpp new file mode 100644 index 0000000..cbe48fc --- /dev/null +++ b/Modules/DiffusionCmdApps/FiberQuantification/EstimateNumSamplesForTractometry.cpp @@ -0,0 +1,111 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center. + +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 "mitkDiffusionCommandLineParser.h" +#include +#include +#include +#include +#include + + + +/*! +\brief Modify input tractogram: fiber resampling, compression, pruning and transformation. +*/ +int main(int argc, char* argv[]) +{ + mitkDiffusionCommandLineParser parser; + + parser.setTitle("Tract Density"); + parser.setCategory("Fiber Quantification Methods"); + parser.setDescription("Estimate minimal number of sampling points for along tract-radiomics based on the input image spacing and the tracts. Each cell should span at least N voxels."); + parser.setContributor("MIC"); + + parser.setArgumentPrefix("--", "-"); + parser.addArgument("tracts", "", mitkDiffusionCommandLineParser::StringList, "Input tracts:", "input tracts", us::Any(), false); + parser.addArgument("images", "", mitkDiffusionCommandLineParser::StringList, "Input images:", "input images", us::Any(), false); + parser.addArgument("voxels", "", mitkDiffusionCommandLineParser::Int, "Number of voxels per parcel:", "", 3); + parser.addArgument("out_file", "", mitkDiffusionCommandLineParser::String, "Output File:", "output file", us::Any(), false); + + std::map parsedArgs = parser.parseArguments(argc, argv); + if (parsedArgs.size()==0) + return EXIT_FAILURE; + + mitkDiffusionCommandLineParser::StringContainerType inFibs = us::any_cast(parsedArgs["tracts"]); + mitkDiffusionCommandLineParser::StringContainerType inImages = us::any_cast(parsedArgs["images"]); + std::string outfile = us::any_cast(parsedArgs["out_file"]); + + int voxels = 3; + if (parsedArgs.count("voxels")) + voxels = us::any_cast(parsedArgs["voxels"]); + + if (inFibs.size()!=inImages.size()) + { + MITK_INFO << "Equal number of tracs and images required!"; + return EXIT_FAILURE; + } + + try + { + std::vector< std::string > fib_names, img_names; + auto input_tracts = mitk::DiffusionDataIOHelper::load_fibs(inFibs, &fib_names); + auto input_images = mitk::DiffusionDataIOHelper::load_mitk_images(inImages, &img_names); + + std::ofstream statistics_file; + statistics_file.open (outfile); + statistics_file << "tract_file;image_file;num_samples" << std::endl; + for (unsigned int i=0; i::Pointer itkImage = itk::Image::New(); + CastToItkImage(input_images.at(i), itkImage); + + auto v = mitk::Tractometry::EstimateNumSamplingPoints(itkImage, input_tracts.at(i), voxels); + statistics_file << fib_names.at(i) << ";" << img_names.at(i) << ";" << boost::lexical_cast(v) << std::endl; + } + + statistics_file.close(); + } + catch (const itk::ExceptionObject& e) + { + std::cout << e.what(); + 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/DiffusionCmdApps/FiberProcessing/PrintFiberStatistics.cpp b/Modules/DiffusionCmdApps/FiberQuantification/PrintFiberStatistics.cpp similarity index 97% rename from Modules/DiffusionCmdApps/FiberProcessing/PrintFiberStatistics.cpp rename to Modules/DiffusionCmdApps/FiberQuantification/PrintFiberStatistics.cpp index 1a716d6..8dafdf4 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/PrintFiberStatistics.cpp +++ b/Modules/DiffusionCmdApps/FiberQuantification/PrintFiberStatistics.cpp @@ -1,101 +1,101 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #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 Join multiple tractograms */ int main(int argc, char* argv[]) { mitkDiffusionCommandLineParser parser; parser.setTitle("Fiber Statistics"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Fiber Quantification Methods"); parser.setContributor("MIC"); parser.setDescription("Output statistics about fiber lengths, weights, etc. to a file."); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "i", mitkDiffusionCommandLineParser::StringList, "Input:", "input tractograms", us::Any(), false); parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output File:", "output file", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkDiffusionCommandLineParser::StringContainerType inFibs = us::any_cast(parsedArgs["i"]); std::string outfile = us::any_cast(parsedArgs["o"]); try { std::vector< std::string > fib_names; auto input_tracts = mitk::DiffusionDataIOHelper::load_fibs(inFibs, &fib_names); std::ofstream statistics_file; statistics_file.open (outfile); int c=0; for (auto tract : input_tracts) { MITK_INFO << "Writing statistics of bunlde " << fib_names.at(c); statistics_file << "File: " << fib_names.at(c) << std::endl; tract->PrintSelf(statistics_file, 2); statistics_file << "-------------------------------------------------------------------------\n\n" << std::endl; ++c; } statistics_file.close(); } catch (const itk::ExceptionObject& e) { std::cout << e.what(); 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/DiffusionCmdApps/FiberProcessing/TractDensity.cpp b/Modules/DiffusionCmdApps/FiberQuantification/TractDensity.cpp similarity index 99% rename from Modules/DiffusionCmdApps/FiberProcessing/TractDensity.cpp rename to Modules/DiffusionCmdApps/FiberQuantification/TractDensity.cpp index 3afd948..561bdbd 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/TractDensity.cpp +++ b/Modules/DiffusionCmdApps/FiberQuantification/TractDensity.cpp @@ -1,213 +1,213 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 "mitkDiffusionCommandLineParser.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[]) { mitkDiffusionCommandLineParser parser; parser.setTitle("Tract Density"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Fiber Quantification Methods"); parser.setDescription("Generate tract density image, fiber envelope or fiber endpoints image."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input fiber bundle", us::Any(), false); parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false); parser.addArgument("binary", "", mitkDiffusionCommandLineParser::Bool, "Binary output:", "calculate binary tract envelope", us::Any()); parser.addArgument("normalize", "", mitkDiffusionCommandLineParser::Bool, "Normalized output:", "normalize output to 0-1", us::Any()); parser.addArgument("endpoints", "", mitkDiffusionCommandLineParser::Bool, "Output endpoints image:", "calculate image of fiber endpoints instead of mask", us::Any()); parser.addArgument("reference_image", "", mitkDiffusionCommandLineParser::String, "Reference image:", "output image will have geometry of this reference image", us::Any()); parser.addArgument("upsampling", "", mitkDiffusionCommandLineParser::Float, "Upsampling:", "upsampling", 1.0); 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"]); bool normalize = false; if (parsedArgs.count("normalize")) normalize = us::any_cast(parsedArgs["normalize"]); float upsampling = 1.0; if (parsedArgs.count("upsampling")) upsampling = us::any_cast(parsedArgs["upsampling"]); MITK_INFO << "Upsampling: " << upsampling; std::string reference_image = ""; if (parsedArgs.count("reference_image")) reference_image = us::any_cast(parsedArgs["reference_image"]); std::string inFileName = us::any_cast(parsedArgs["i"]); std::string outFileName = us::any_cast(parsedArgs["o"]); try { mitk::FiberBundle::Pointer fib = LoadFib(inFileName); mitk::Image::Pointer ref_img; if (!reference_image.empty()) ref_img = mitk::IOUtil::Load(reference_image); if (endpoints) { typedef unsigned int OutPixType; typedef itk::Image OutImageType; typedef itk::TractsToFiberEndingsImageFilter< OutImageType > ImageGeneratorType; ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); generator->SetFiberBundle(fib); generator->SetUpsamplingFactor(upsampling); 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::Save(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->SetMode(TDI_MODE::BINARY); generator->SetOutputAbsoluteValues(!normalize); generator->SetUpsamplingFactor(upsampling); 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::Save(img, outFileName ); } else { typedef float OutPixType; typedef itk::Image OutImageType; itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); generator->SetFiberBundle(fib); generator->SetMode(TDI_MODE::DENSITY); generator->SetOutputAbsoluteValues(!normalize); generator->SetUpsamplingFactor(upsampling); 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::Save(img, outFileName ); } } catch (const itk::ExceptionObject& e) { std::cout << e.what(); 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/DiffusionCmdApps/FiberProcessing/TractParcellation.cpp b/Modules/DiffusionCmdApps/FiberQuantification/TractParcellation.cpp similarity index 97% rename from Modules/DiffusionCmdApps/FiberProcessing/TractParcellation.cpp rename to Modules/DiffusionCmdApps/FiberQuantification/TractParcellation.cpp index 2b67c52..2fdc9ad 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/TractParcellation.cpp +++ b/Modules/DiffusionCmdApps/FiberQuantification/TractParcellation.cpp @@ -1,155 +1,155 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 "mitkDiffusionCommandLineParser.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[]) { mitkDiffusionCommandLineParser 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.setCategory("Fiber Quantification Methods"); + parser.setDescription("Parcellate tract for along-tract radiomics."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input fiber bundle", us::Any(), false); parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false); parser.addArgument("reference_image", "", mitkDiffusionCommandLineParser::String, "Reference image:", "output image will have geometry of this reference image", us::Any(), false); parser.addArgument("binary", "", mitkDiffusionCommandLineParser::Bool, "Binary output:", "", false); parser.addArgument("num_parcels", "", mitkDiffusionCommandLineParser::Int, "Number of parcels:", "", 15); parser.addArgument("num_centroids", "", mitkDiffusionCommandLineParser::Int, "Number of centroids:", "", 0); parser.addArgument("start_cluster_size", "", mitkDiffusionCommandLineParser::Float, "Cluster size (in mm):", "", 5.0); 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"]); int num_parcels = 15; if (parsedArgs.count("num_parcels")) num_parcels = us::any_cast(parsedArgs["num_parcels"]); int num_centroids = 0; if (parsedArgs.count("num_centroids")) num_centroids = us::any_cast(parsedArgs["num_centroids"]); float start_cluster_size = 5; if (parsedArgs.count("start_cluster_size")) start_cluster_size = us::any_cast(parsedArgs["start_cluster_size"]); std::string reference_image = us::any_cast(parsedArgs["reference_image"]); std::string inFileName = us::any_cast(parsedArgs["i"]); std::string outFileName = us::any_cast(parsedArgs["o"]); try { mitk::FiberBundle::Pointer fib = LoadFib(inFileName); mitk::Image::Pointer ref_img = mitk::IOUtil::Load(reference_image); typedef unsigned char OutPixType; typedef itk::Image OutImageType; OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(ref_img, itkImage); itk::TractParcellationFilter< >::Pointer parcellator = itk::TractParcellationFilter< >::New(); parcellator->SetInputImage(itkImage); parcellator->SetNumParcels(num_parcels); parcellator->SetInputTract(fib); parcellator->SetNumCentroids(num_centroids); parcellator->SetStartClusterSize(start_cluster_size); parcellator->Update(); OutImageType::Pointer out_image = parcellator->GetOutput(0); OutImageType::Pointer out_image_pp = parcellator->GetOutput(1); if (binary) { auto binary_segments = parcellator->GetBinarySplit(out_image_pp); int c=1; for (auto itk_segment : binary_segments) { mitk::Image::Pointer mitk_segment = mitk::Image::New(); mitk_segment->InitializeByItk(itk_segment.GetPointer()); mitk_segment->SetVolume(itk_segment->GetBufferPointer()); if (c<10) mitk::IOUtil::Save(mitk_segment, outFileName + "_0" + boost::lexical_cast(c) + ".nrrd"); else mitk::IOUtil::Save(mitk_segment, outFileName + "_" + boost::lexical_cast(c) + ".nrrd"); ++c; } } else { mitk::Image::Pointer mitk_img_pp = mitk::Image::New(); mitk_img_pp->InitializeByItk(out_image_pp.GetPointer()); mitk_img_pp->SetVolume(out_image_pp->GetBufferPointer()); mitk::IOUtil::Save(mitk_img_pp, outFileName ); } } catch (const itk::ExceptionObject& e) { std::cout << e.what(); 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/DiffusionCmdApps/FiberProcessing/TractometryComparison.cpp b/Modules/DiffusionCmdApps/FiberQuantification/TractometryComparison.cpp similarity index 97% rename from Modules/DiffusionCmdApps/FiberProcessing/TractometryComparison.cpp rename to Modules/DiffusionCmdApps/FiberQuantification/TractometryComparison.cpp index 8a42e74..fe09690 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/TractometryComparison.cpp +++ b/Modules/DiffusionCmdApps/FiberQuantification/TractometryComparison.cpp @@ -1,137 +1,137 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include /*! \brief Join multiple tractograms */ int main(int argc, char* argv[]) { mitkDiffusionCommandLineParser parser; parser.setTitle("Fiber Statistics"); - parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setCategory("Fiber Quantification Methods"); parser.setContributor("MIC"); - parser.setDescription("Output statistics about fiber lengths, weights, etc. to a file."); + parser.setDescription("Calculate mutliple tractometry methods."); parser.setArgumentPrefix("--", "-"); parser.addArgument("tracts", "", mitkDiffusionCommandLineParser::StringList, "Input tracts:", "input tracts", us::Any(), false); parser.addArgument("images", "", mitkDiffusionCommandLineParser::StringList, "Input images:", "input images", us::Any(), false); parser.addArgument("out_file", "", mitkDiffusionCommandLineParser::String, "Output File:", "output file", us::Any(), false); parser.addArgument("num_parcels", "", mitkDiffusionCommandLineParser::Int, "Number of parcels:", "", 15); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkDiffusionCommandLineParser::StringContainerType inFibs = us::any_cast(parsedArgs["tracts"]); mitkDiffusionCommandLineParser::StringContainerType inImages = us::any_cast(parsedArgs["images"]); std::string outfile = us::any_cast(parsedArgs["out_file"]); int num_parcels = 15; if (parsedArgs.count("num_parcels")) num_parcels = us::any_cast(parsedArgs["num_parcels"]); try { std::vector< std::string > fib_names, img_names; auto input_tracts = mitk::DiffusionDataIOHelper::load_fibs(inFibs, &fib_names); auto input_images = mitk::DiffusionDataIOHelper::load_itk_images>(inImages, &img_names); bool add_header = !itksys::SystemTools::FileExists(outfile, true); std::ofstream statistics_file; statistics_file.open (outfile, std::ios_base::app); if (add_header) statistics_file << "method;tract_file;image_file;parcel;value" << std::endl; auto ref = input_tracts.at(0)->GetDeepCopy(); for (unsigned int i=0; iResampleSpline(1.0); { auto output = mitk::Tractometry::StaticResamplingTractometry(input_images.at(i), fib->GetDeepCopy(), num_parcels, ref); for (unsigned int r=0; r(r) << ";" << boost::lexical_cast(output.get(r,c)) << std::endl; } { auto output = mitk::Tractometry::NearestCentroidPointTractometry(input_images.at(i), fib->GetDeepCopy(), num_parcels, 1, 99, ref); for (unsigned int r=0; r(r) << ";" << boost::lexical_cast(output.at(r).get(c)) << std::endl; } { itk::TractParcellationFilter< itk::Image, itk::Image >::Pointer parcellator = itk::TractParcellationFilter< itk::Image, itk::Image >::New(); parcellator->SetInputImage(input_images.at(i)); parcellator->SetNumParcels(num_parcels); parcellator->SetInputTract(fib->GetDeepCopy()); parcellator->SetReferenceTract(ref); parcellator->Update(); itk::Image::Pointer out_image_pp = parcellator->GetOutput(1); itk::ImageRegionConstIterator< itk::Image > it(input_images.at(i), input_images.at(i)->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< itk::Image > it2(out_image_pp, out_image_pp->GetLargestPossibleRegion()); while (!it.IsAtEnd()) { if (it2.Get()>0) statistics_file << "TractParcellationFilter;" << fib_names.at(i) << ";" << img_names.at(i) << ";" << boost::lexical_cast(it2.Get()-1) << ";" << boost::lexical_cast(it.Get()) << std::endl; ++it; ++it2; } } } statistics_file.close(); } catch (const itk::ExceptionObject& e) { std::cout << e.what(); 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/DiffusionCmdApps/Quantification/CMakeLists.txt b/Modules/DiffusionCmdApps/ImageQuantification/CMakeLists.txt similarity index 100% rename from Modules/DiffusionCmdApps/Quantification/CMakeLists.txt rename to Modules/DiffusionCmdApps/ImageQuantification/CMakeLists.txt diff --git a/Modules/DiffusionCmdApps/Quantification/DiffusionIndices.cpp b/Modules/DiffusionCmdApps/ImageQuantification/DiffusionIndices.cpp similarity index 100% rename from Modules/DiffusionCmdApps/Quantification/DiffusionIndices.cpp rename to Modules/DiffusionCmdApps/ImageQuantification/DiffusionIndices.cpp diff --git a/Modules/DiffusionCmdApps/Quantification/DiffusionIvimFit.cpp b/Modules/DiffusionCmdApps/ImageQuantification/DiffusionIvimFit.cpp similarity index 100% rename from Modules/DiffusionCmdApps/Quantification/DiffusionIvimFit.cpp rename to Modules/DiffusionCmdApps/ImageQuantification/DiffusionIvimFit.cpp diff --git a/Modules/DiffusionCmdApps/Quantification/DiffusionKurtosisFit.cpp b/Modules/DiffusionCmdApps/ImageQuantification/DiffusionKurtosisFit.cpp similarity index 100% rename from Modules/DiffusionCmdApps/Quantification/DiffusionKurtosisFit.cpp rename to Modules/DiffusionCmdApps/ImageQuantification/DiffusionKurtosisFit.cpp diff --git a/Modules/DiffusionCmdApps/Quantification/MultishellMethods.cpp b/Modules/DiffusionCmdApps/ImageQuantification/MultishellMethods.cpp similarity index 100% rename from Modules/DiffusionCmdApps/Quantification/MultishellMethods.cpp rename to Modules/DiffusionCmdApps/ImageQuantification/MultishellMethods.cpp diff --git a/Modules/DiffusionCmdApps/Quantification/QballReconstruction.cpp b/Modules/DiffusionCmdApps/ImageQuantification/QballReconstruction.cpp similarity index 100% rename from Modules/DiffusionCmdApps/Quantification/QballReconstruction.cpp rename to Modules/DiffusionCmdApps/ImageQuantification/QballReconstruction.cpp diff --git a/Modules/DiffusionCmdApps/Quantification/TensorReconstruction.cpp b/Modules/DiffusionCmdApps/ImageQuantification/TensorReconstruction.cpp similarity index 100% rename from Modules/DiffusionCmdApps/Quantification/TensorReconstruction.cpp rename to Modules/DiffusionCmdApps/ImageQuantification/TensorReconstruction.cpp diff --git a/Modules/DiffusionCmdApps/mitkDiffusionDataIOHelper.h b/Modules/DiffusionCmdApps/mitkDiffusionDataIOHelper.h index 999f258..9b7d05a 100644 --- a/Modules/DiffusionCmdApps/mitkDiffusionDataIOHelper.h +++ b/Modules/DiffusionCmdApps/mitkDiffusionDataIOHelper.h @@ -1,134 +1,171 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 __mitkDiffusionDataIOHelper_h_ #define __mitkDiffusionDataIOHelper_h_ #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; namespace mitk{ class MITKDIFFUSIONCMDAPPS_EXPORT DiffusionDataIOHelper { public: static std::vector< std::string > get_file_list(const std::string& path, const std::vector< std::string > extensions={".fib", ".trk"}); static std::vector< mitk::FiberBundle::Pointer > load_fibs(const std::vector files, std::vector* filenames=nullptr); static std::vector< mitk::Image::Pointer > load_mitk_images(const std::vector files, std::vector* filenames=nullptr); template< class TYPE > static typename TYPE::Pointer load_itk_image(const std::string file) { - mitk::LocaleSwitch localeSwitch("C"); - std::streambuf *old = cout.rdbuf(); // <-- save - std::stringstream ss; - std::cout.rdbuf (ss.rdbuf()); // <-- redirect + std::cout.setstate(std::ios_base::failbit); std::vector< typename TYPE::Pointer > out; - if (file.compare("")!=0 && itksys::SystemTools::FileExists(file)) - { - mitk::Image::Pointer image = mitk::IOUtil::Load(file); - if (image.IsNotNull()) + + try { + if (file.compare("")!=0 && itksys::SystemTools::FileExists(file)) { - typedef mitk::ImageToItk< TYPE > CasterType; - typename CasterType::Pointer caster = CasterType::New(); - caster->SetInput(image); - caster->Update(); - typename TYPE::Pointer itk_image = caster->GetOutput(); - std::cout.rdbuf (old); // <-- restore - MITK_INFO << "Loaded 1 image"; - return itk_image; + mitk::Image::Pointer image = mitk::IOUtil::Load(file); + if (image.IsNotNull()) + { + typedef mitk::ImageToItk< TYPE > CasterType; + typename CasterType::Pointer caster = CasterType::New(); + caster->SetInput(image); + caster->Update(); + typename TYPE::Pointer itk_image = caster->GetOutput(); + std::cout.clear(); + MITK_INFO << "Loaded 1 image"; + return itk_image; + } } } - std::cout.rdbuf (old); // <-- restore // <-- restore + catch (const itk::ExceptionObject& e) + { + std::cout.clear(); + std::cout << e.what(); + return nullptr; + } + catch (std::exception& e) + { + std::cout.clear(); + std::cout << e.what(); + return nullptr; + } + catch (...) + { + std::cout.clear(); + std::cout << "ERROR!?!"; + return nullptr; + } + + std::cout.clear(); MITK_INFO << "Loaded 0 images"; return nullptr; } template< class TYPE > static std::vector< typename TYPE::Pointer > load_itk_images(const std::vector files, std::vector* filenames=nullptr) { - mitk::LocaleSwitch localeSwitch("C"); - std::streambuf *old = cout.rdbuf(); // <-- save - std::stringstream ss; - std::cout.rdbuf (ss.rdbuf()); // <-- redirect + std::cout.setstate(std::ios_base::failbit); std::vector< typename TYPE::Pointer > out; - for (auto f : files) - { - if (itksys::SystemTools::FileExists(f, true)) - { - mitk::Image::Pointer image = mitk::IOUtil::Load(f); - if (image.IsNotNull()) - { - typedef mitk::ImageToItk< TYPE > CasterType; - typename CasterType::Pointer caster = CasterType::New(); - caster->SetInput(image); - caster->Update(); - typename TYPE::Pointer itk_image = caster->GetOutput(); - out.push_back(itk_image); - if (filenames!=nullptr) - filenames->push_back(f); - } - } - else if (itksys::SystemTools::PathExists(f)) + try { + for (auto f : files) { - if (!f.empty() && f.back() != '/') - f += "/"; - - auto list = get_file_list(f, {".nrrd",".nii.gz",".nii"}); - for (auto file : list) + if (itksys::SystemTools::FileExists(f, true)) { - mitk::Image::Pointer image = mitk::IOUtil::Load(file); + mitk::Image::Pointer image = mitk::IOUtil::Load(f); if (image.IsNotNull()) { typedef mitk::ImageToItk< TYPE > CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); typename TYPE::Pointer itk_image = caster->GetOutput(); out.push_back(itk_image); if (filenames!=nullptr) - filenames->push_back(file); + filenames->push_back(f); + } + } + else if (itksys::SystemTools::PathExists(f)) + { + if (!f.empty() && f.back() != '/') + f += "/"; + + auto list = get_file_list(f, {".nrrd",".nii.gz",".nii"}); + for (auto file : list) + { + mitk::Image::Pointer image = mitk::IOUtil::Load(file); + if (image.IsNotNull()) + { + typedef mitk::ImageToItk< TYPE > CasterType; + typename CasterType::Pointer caster = CasterType::New(); + caster->SetInput(image); + caster->Update(); + typename TYPE::Pointer itk_image = caster->GetOutput(); + + out.push_back(itk_image); + if (filenames!=nullptr) + filenames->push_back(file); + } } } } } + catch (const itk::ExceptionObject& e) + { + std::cout.clear(); + std::cout << e.what(); + return out; + } + catch (std::exception& e) + { + std::cout.clear(); + std::cout << e.what(); + return out; + } + catch (...) + { + std::cout.clear(); + std::cout << "ERROR!?!"; + return out; + } - std::cout.rdbuf (old); // <-- restore + std::cout.clear(); MITK_INFO << "Loaded " << out.size() << " images"; return out; } }; } #endif //__mitkDiffusionDataIOHelper_h_ diff --git a/Modules/FiberTracking/Algorithms/itkTractParcellationFilter.cpp b/Modules/FiberTracking/Algorithms/itkTractParcellationFilter.cpp index d042415..58ca994 100644 --- a/Modules/FiberTracking/Algorithms/itkTractParcellationFilter.cpp +++ b/Modules/FiberTracking/Algorithms/itkTractParcellationFilter.cpp @@ -1,469 +1,459 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 "itkTractParcellationFilter.h" // VTK #include #include #include #include #include #include #include #include #include #include #include #include #include +#include namespace itk{ template< class OutImageType, class InputImageType > TractParcellationFilter< OutImageType, InputImageType >::TractParcellationFilter() : m_UpsamplingFactor(1) , m_NumParcels(0) , m_NumCentroids(0) , m_StartClusterSize(5) , m_InputImage(nullptr) { this->SetNumberOfRequiredOutputs(2); } template< class OutImageType, class InputImageType > TractParcellationFilter< OutImageType, InputImageType >::~TractParcellationFilter() { } template< class OutImageType, class InputImageType > bool TractParcellationFilter< OutImageType, InputImageType >::Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer< vtkPolyData > ref_poly, int ref_i) { double d_direct = 0; double d_flipped = 0; vtkCell* cell1 = polydata1->GetCell(ref_i); if (ref_poly!=nullptr) cell1 = ref_poly->GetCell(ref_i); auto numPoints1 = cell1->GetNumberOfPoints(); vtkPoints* points1 = cell1->GetPoints(); std::vector> ref_points; for (int j=0; jGetPoint(j); itk::Point itk_p; itk_p[0] = p1[0]; itk_p[1] = p1[1]; itk_p[2] = p1[2]; ref_points.push_back(itk_p); } vtkCell* cell2 = polydata1->GetCell(i); vtkPoints* points2 = cell2->GetPoints(); for (int j=0; jGetPoint(j); d_direct += (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + (p1[2]-p2[2])*(p1[2]-p2[2]); double* p3 = points2->GetPoint(numPoints1-j-1); d_flipped += (p1[0]-p3[0])*(p1[0]-p3[0]) + (p1[1]-p3[1])*(p1[1]-p3[1]) + (p1[2]-p3[2])*(p1[2]-p3[2]); } if (d_direct>d_flipped) return true; return false; } template< class OutImageType, class InputImageType > mitk::FiberBundle::Pointer TractParcellationFilter< OutImageType, InputImageType >::GetWorkingFib() { mitk::FiberBundle::Pointer fib_static_resampled = m_InputTract->GetDeepCopy(); - fib_static_resampled->ResampleToNumPoints(m_NumParcels); - + mitk::Tractometry::ResampleIfNecessary(fib_static_resampled, m_NumParcels); // clustering std::vector< mitk::ClusteringMetric* > metrics; metrics.push_back({new mitk::ClusteringMetricEuclideanStd()}); // metrics.push_back({new mitk::ClusteringMetricEuclideanMean()}); // metrics.push_back({new mitk::ClusteringMetricLength()}); if (m_NumCentroids>0) { std::vector centroids; std::shared_ptr< mitk::TractClusteringFilter > clusterer = std::make_shared(); int c=0; while (c<30 && (centroids.empty() || centroids.size()>static_cast(m_NumCentroids))) { float cluster_size = m_StartClusterSize + m_StartClusterSize*0.2*c; float max_d = 0; int i=1; std::vector< float > distances; while (max_d < m_InputTract->GetGeometry()->GetDiagonalLength()/2) { distances.push_back(cluster_size*i); max_d = cluster_size*i; ++i; } clusterer->SetDistances(distances); clusterer->SetTractogram(fib_static_resampled); clusterer->SetMetrics(metrics); clusterer->SetMergeDuplicateThreshold(cluster_size); clusterer->SetDoResampling(false); clusterer->SetNumPoints(m_NumParcels); // clusterer->SetMaxClusters(m_Controls->m_MaxCentroids->value()); clusterer->SetMinClusterSize(1); clusterer->Update(); centroids = clusterer->GetOutCentroids(); ++c; } mitk::FiberBundle::Pointer centroid_bundle = mitk::FiberBundle::New(); centroid_bundle = centroid_bundle->AddBundles(centroids); return centroid_bundle; } return fib_static_resampled; } template< class OutImageType, class InputImageType > std::vector< typename itk::Image::Pointer > TractParcellationFilter< OutImageType, InputImageType >::GetBinarySplit(typename OutImageType::Pointer inImage) { std::vector< typename itk::Image::Pointer > binary_maps; for (unsigned int i=0; i::Pointer parcel_image = itk::Image::New(); parcel_image->SetSpacing( inImage->GetSpacing() ); parcel_image->SetOrigin( inImage->GetOrigin() ); parcel_image->SetDirection( inImage->GetDirection() ); parcel_image->SetRegions( inImage->GetLargestPossibleRegion() ); parcel_image->Allocate(); parcel_image->FillBuffer(0); binary_maps.push_back(parcel_image); } itk::ImageRegionIterator< itk::Image > p_it(inImage, inImage->GetLargestPossibleRegion()); while(!p_it.IsAtEnd()) { if (p_it.Get()>0) { binary_maps.at(p_it.Get()-1)->SetPixel(p_it.GetIndex(), 1); } ++p_it; } return binary_maps; } template< class OutImageType, class InputImageType > typename OutImageType::Pointer TractParcellationFilter< OutImageType, InputImageType >::PostprocessParcellation(typename OutImageType::Pointer inImage) { itk::ImageRegionConstIterator< OutImageType > in_it(inImage, inImage->GetLargestPossibleRegion()); typename OutImageType::Pointer outImage = OutImageType::New(); outImage->SetSpacing( inImage->GetSpacing() ); outImage->SetOrigin( inImage->GetOrigin() ); outImage->SetDirection( inImage->GetDirection() ); outImage->SetRegions( inImage->GetLargestPossibleRegion() ); outImage->Allocate(); outImage->FillBuffer(0); itk::ImageRegionIterator< OutImageType > out_it(outImage, outImage->GetLargestPossibleRegion()); MITK_INFO << "Postprocessing parcellation"; while( !in_it.IsAtEnd() ) { if (in_it.Get()>0) { std::vector< OutPixelType > vote; vote.resize(m_NumParcels + 1, 0); typename OutImageType::SizeType regionSize; regionSize[0] = 3; regionSize[1] = 3; regionSize[2] = 3; typename OutImageType::IndexType regionIndex = in_it.GetIndex(); regionIndex[0] -= 1; regionIndex[1] -= 1; regionIndex[2] -= 1; typename OutImageType::RegionType region; region.SetSize(regionSize); region.SetIndex(regionIndex); itk::ImageRegionConstIterator rit(inImage, region); while( !rit.IsAtEnd() ) { if (rit.GetIndex()!=regionIndex) vote[rit.Get()]++; ++rit; } OutPixelType max = 0; unsigned int max_parcel = -1; for (unsigned int i=1; imax) { max = vote[i]; max_parcel = i; } } out_it.Set(max_parcel); } ++out_it; ++in_it; } MITK_INFO << "DONE"; return outImage; } template< class OutImageType, class InputImageType > void TractParcellationFilter< OutImageType, InputImageType >::StaticResampleParcelVoting(typename OutImageType::Pointer outImage) { typename itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); generator->SetFiberBundle(m_InputTract); generator->SetMode(TDI_MODE::BINARY); generator->SetInputImage(outImage); generator->SetUseImageGeometry(true); generator->Update(); auto tdi = generator->GetOutput(); if (m_NumParcels < 3) - { - auto spacing = outImage->GetSpacing(); - float f = (spacing[0] + spacing[1] + spacing[2])/3; - f /= generator->GetAverageSegmentLength(); - MITK_INFO << generator->GetAverageSegmentLength(); - MITK_INFO << generator->GetAverageNumTraversedVoxels(); - MITK_INFO << f; - m_NumParcels = std::ceil(generator->GetAverageNumTraversedVoxels()/(3.0*f)); - - MITK_INFO << "Automatically setting number of parcels to " << m_NumParcels; - } + m_NumParcels = mitk::Tractometry::EstimateNumSamplingPoints(tdi, m_InputTract, 3); itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetMaskImage(tdi); fOdfFilter->SetFiberBundle(m_InputTract); fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter::NormalizationMethods::SINGLE_VEC_NORM); fOdfFilter->SetMaxNumDirections(1); fOdfFilter->Update(); itk::Image< float, 4 >::Pointer dir_image = fOdfFilter->GetDirectionImage(); m_WorkingTract = GetWorkingFib(); vtkSmartPointer< vtkPolyData > polydata = m_WorkingTract->GetFiberPolyData(); float maxd = m_InputTract->GetMeanFiberLength()/(0.5*m_NumParcels); itk::ImageRegionIterator< OutImageType > it(outImage, outImage->GetLargestPossibleRegion()); itk::ImageRegionIterator< OutImageType > it_tdi(tdi, tdi->GetLargestPossibleRegion()); vtkSmartPointer< vtkPolyData > reference_polydata = nullptr; if (m_ReferenceTract.IsNotNull()) reference_polydata = m_ReferenceTract->GetFiberPolyData(); unsigned long num_vox = 0; while( !it_tdi.IsAtEnd() ) { if (it_tdi.Get()>0) ++num_vox; ++it_tdi; } it_tdi.GoToBegin(); MITK_INFO << "Parcellating tract"; boost::progress_display disp(num_vox); while( !it.IsAtEnd() ) { if (it_tdi.Get()>0) { int final_seg_id = -1; int mult = 1; itk::Image< float, 4 >::IndexType idx4; idx4[0] = it_tdi.GetIndex()[0]; idx4[1] = it_tdi.GetIndex()[1]; idx4[2] = it_tdi.GetIndex()[2]; vnl_vector_fixed ref_dir; idx4[3] = 0; ref_dir[0] = dir_image->GetPixel(idx4); idx4[3] = 1; ref_dir[1] = dir_image->GetPixel(idx4); idx4[3] = 2; ref_dir[2] = dir_image->GetPixel(idx4); while(final_seg_id<0) { std::vector seg_vote; seg_vote.resize(m_NumParcels, 0); typename OutImageType::PointType image_point; tdi->TransformIndexToPhysicalPoint(it.GetIndex(), image_point); for (unsigned int i=0; iGetNumFibers(); ++i) { vtkCell* cell = polydata->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); bool flip = Flip(polydata, i, reference_polydata); float local_d = 99999999; int local_closest_seg = -1; // float weight = 1.0; for (int j=0; j p; int segment_id = -1; if (flip) { segment_id = numPoints - j - 1; p = mitk::imv::GetItkPoint(points->GetPoint(segment_id)); } else { p = mitk::imv::GetItkPoint(points->GetPoint(j)); segment_id = j; } float d = std::fabs( (p[0]-image_point[0]) ) + std::fabs( (p[1]-image_point[1]) ) + std::fabs( (p[2]-image_point[2]) ); itk::Point p2; if (segment_idGetPoint(segment_id+1)); } else { p2 = mitk::imv::GetItkPoint(points->GetPoint(segment_id-1)); } vnl_vector_fixed dir; dir[0] = p[0]-p2[0]; dir[1] = p[1]-p2[1]; dir[2] = p[2]-p2[2]; dir.normalize(); float a = std::fabs(dot_product(dir, ref_dir)); if (a<0.0000001) a += 0.0000001; d += (1.0/a - 1.0) * maxd; if (dTransformPhysicalPointToIndex(mitk_p, p_idx); // weight = tdi->GetPixel(p_idx); } } if (local_dmax_count) { final_seg_id = i; max_count = seg_vote.at(i); } } if (final_seg_id>=0) it.Set(final_seg_id + 1); ++mult; } ++disp; } ++it; ++it_tdi; } MITK_INFO << "DONE"; } template< class OutImageType, class InputImageType > void TractParcellationFilter< OutImageType, InputImageType >::GenerateData() { // generate upsampled image mitk::BaseGeometry::Pointer geometry = m_InputTract->GetGeometry(); // calculate new image parameters itk::Vector newSpacing; mitk::Point3D newOrigin; itk::Matrix newDirection; ImageRegion<3> upsampledRegion; if (!m_InputImage.IsNull()) { newSpacing = m_InputImage->GetSpacing()/m_UpsamplingFactor; upsampledRegion = m_InputImage->GetLargestPossibleRegion(); newOrigin = m_InputImage->GetOrigin(); typename OutImageType::RegionType::SizeType size = upsampledRegion.GetSize(); size[0] *= m_UpsamplingFactor; size[1] *= m_UpsamplingFactor; size[2] *= m_UpsamplingFactor; upsampledRegion.SetSize(size); newDirection = m_InputImage->GetDirection(); } else { newSpacing = geometry->GetSpacing()/m_UpsamplingFactor; newOrigin = geometry->GetOrigin(); mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds(); newOrigin[0] += bounds.GetElement(0); newOrigin[1] += bounds.GetElement(2); newOrigin[2] += bounds.GetElement(4); for (int i=0; i<3; i++) for (int j=0; j<3; j++) newDirection[j][i] = geometry->GetMatrixColumn(i)[j]; upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor); upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor); upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor); } // apply new image parameters typename OutImageType::Pointer outImage = OutImageType::New(); outImage->SetSpacing( newSpacing ); outImage->SetOrigin( newOrigin ); outImage->SetDirection( newDirection ); outImage->SetRegions( upsampledRegion ); outImage->Allocate(); outImage->FillBuffer(0); this->SetNthOutput(0, outImage); StaticResampleParcelVoting(outImage); auto outImage_pp = PostprocessParcellation(outImage); outImage_pp = PostprocessParcellation(outImage_pp); outImage_pp = PostprocessParcellation(outImage_pp); this->SetNthOutput(1, outImage_pp); } } diff --git a/Modules/FiberTracking/Algorithms/mitkTractometry.cpp b/Modules/FiberTracking/Algorithms/mitkTractometry.cpp index fa437e6..b433937 100644 --- a/Modules/FiberTracking/Algorithms/mitkTractometry.cpp +++ b/Modules/FiberTracking/Algorithms/mitkTractometry.cpp @@ -1,273 +1,298 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 "mitkTractometry.h" #define _USE_MATH_DEFINES #include #include #include #include #include +#include namespace mitk{ bool Tractometry::Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer< vtkPolyData > ref_poly) { double d_direct = 0; double d_flipped = 0; vtkCell* cell1 = polydata1->GetCell(0); if (ref_poly!=nullptr) cell1 = ref_poly->GetCell(0); auto numPoints1 = cell1->GetNumberOfPoints(); vtkPoints* points1 = cell1->GetPoints(); std::vector> ref_points; for (int j=0; jGetPoint(j); itk::Point itk_p; itk_p[0] = p1[0]; itk_p[1] = p1[1]; itk_p[2] = p1[2]; ref_points.push_back(itk_p); } vtkCell* cell2 = polydata1->GetCell(i); vtkPoints* points2 = cell2->GetPoints(); for (int j=0; jGetPoint(j); d_direct += (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + (p1[2]-p2[2])*(p1[2]-p2[2]); double* p3 = points2->GetPoint(numPoints1-j-1); d_flipped += (p1[0]-p3[0])*(p1[0]-p3[0]) + (p1[1]-p3[1])*(p1[1]-p3[1]) + (p1[2]-p3[2])*(p1[2]-p3[2]); } if (d_direct>d_flipped) return true; return false; } void Tractometry::ResampleIfNecessary(mitk::FiberBundle::Pointer fib, unsigned int num_points) { auto poly = fib->GetFiberPolyData(); bool resample = false; for (int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = poly->GetCell(i); if (cell->GetNumberOfPoints()!=num_points) { resample = true; MITK_INFO << "Resampling required!"; break; } } if (resample) fib->ResampleToNumPoints(num_points); } +unsigned int Tractometry::EstimateNumSamplingPoints(itk::Image::Pointer ref_image, mitk::FiberBundle::Pointer fib, unsigned int voxels) +{ + typename itk::TractDensityImageFilter< itk::Image >::Pointer generator = itk::TractDensityImageFilter< itk::Image >::New(); + generator->SetFiberBundle(fib); + generator->SetMode(TDI_MODE::BINARY); + generator->SetInputImage(ref_image); + generator->SetUseImageGeometry(true); + generator->Update(); + + auto spacing = ref_image->GetSpacing(); + float f = (spacing[0] + spacing[1] + spacing[2])/3; + f /= generator->GetAverageSegmentLength(); + MITK_INFO << generator->GetAverageSegmentLength(); + MITK_INFO << generator->GetAverageNumTraversedVoxels(); + MITK_INFO << f; + unsigned int n = std::ceil(generator->GetAverageNumTraversedVoxels()/(voxels*f)); + if (n<3) + n = 3; + + MITK_INFO << "Estimated number of sampling points " << n; + + return n; +} + std::vector> Tractometry::NearestCentroidPointTractometry(itk::Image::Pointer itkImage, mitk::FiberBundle::Pointer working_fib, unsigned int num_points, unsigned int max_centroids, float cluster_size, mitk::FiberBundle::Pointer ref_fib) { vtkSmartPointer< vtkPolyData > polydata = working_fib->GetFiberPolyData(); vtkSmartPointer< vtkPolyData > ref_polydata = nullptr; if (ref_fib!=nullptr) { ResampleIfNecessary(ref_fib, num_points); ref_polydata = ref_fib->GetFiberPolyData(); } auto interpolator = itk::LinearInterpolateImageFunction< itk::Image, float >::New(); interpolator->SetInputImage(itkImage); mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); lookupTable->SetType(mitk::LookupTable::MULTILABEL); std::vector> output_temp; for(unsigned int i=0; i metrics; metrics.push_back({new mitk::ClusteringMetricEuclideanStd()}); mitk::FiberBundle::Pointer resampled = working_fib->GetDeepCopy(); ResampleIfNecessary(resampled, num_points); std::vector centroids; std::shared_ptr< mitk::TractClusteringFilter > clusterer = std::make_shared(); int c=0; while (c<30 && (centroids.empty() || centroids.size()>max_centroids)) { float cs = cluster_size + cluster_size*c*0.2; float max_d = 0; int i=1; std::vector< float > distances; while (max_d < resampled->GetGeometry()->GetDiagonalLength()/2) { distances.push_back(cs*i); max_d = cs*i; ++i; } clusterer->SetDistances(distances); clusterer->SetTractogram(resampled); clusterer->SetMetrics(metrics); clusterer->SetMergeDuplicateThreshold(cs); clusterer->SetDoResampling(false); clusterer->SetNumPoints(num_points); if (c==29) clusterer->SetMaxClusters(max_centroids); clusterer->SetMinClusterSize(1); clusterer->Update(); centroids = clusterer->GetOutCentroids(); ++c; } for (unsigned int i=0; iGetNumFibers(); ++i) { vtkCell* cell = polydata->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vnl_vector values; values.set_size(numPoints); for (int j=0; jGetPoint(j); int min_bin = 0; float d=999999; for (auto centroid : centroids) { auto centroid_polydata = centroid->GetFiberPolyData(); vtkCell* centroid_cell = centroid_polydata->GetCell(0); auto centroid_numPoints = centroid_cell->GetNumberOfPoints(); vtkPoints* centroid_points = centroid_cell->GetPoints(); bool centroid_flip = Flip(centroid_polydata, 0, ref_polydata); for (int bin=0; binGetPoint(bin); float temp_d = std::sqrt((p[0]-centroid_p[0])*(p[0]-centroid_p[0]) + (p[1]-centroid_p[1])*(p[1]-centroid_p[1]) + (p[2]-centroid_p[2])*(p[2]-centroid_p[2])); if (temp_dGetColor(min_bin+1, rgb); working_fib->ColorSinglePoint(i, j, rgb); double pixelValue = mitk::imv::GetImageValue(mitk::imv::GetItkPoint(p), true, interpolator); output_temp.at(min_bin).push_back(pixelValue); } } std::vector> output; for (auto row_v : output_temp) { vnl_vector row; row.set_size(row_v.size()); int i = 0; for (auto v : row_v) { row.put(i, v); ++i; } output.push_back(row); } return output; } vnl_matrix Tractometry::StaticResamplingTractometry(itk::Image::Pointer itkImage, mitk::FiberBundle::Pointer working_fib, unsigned int num_points, mitk::FiberBundle::Pointer ref_fib) { ResampleIfNecessary(working_fib, num_points); vtkSmartPointer< vtkPolyData > polydata = working_fib->GetFiberPolyData(); vtkSmartPointer< vtkPolyData > ref_polydata = nullptr; if (ref_fib!=nullptr) { ResampleIfNecessary(ref_fib, num_points); ref_polydata = ref_fib->GetFiberPolyData(); } auto interpolator = itk::LinearInterpolateImageFunction< itk::Image, float >::New(); interpolator->SetInputImage(itkImage); mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); lookupTable->SetType(mitk::LookupTable::MULTILABEL); vnl_matrix output; output.set_size(num_points, working_fib->GetNumFibers()); output.fill(0.0); for (unsigned int i=0; iGetNumFibers(); ++i) { vtkCell* cell = polydata->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); bool flip = Flip(polydata, i, ref_polydata); for (int j=0; jGetColor(j+1, rgb); double* p; if (flip) { auto p_idx = numPoints - j - 1; p = points->GetPoint(p_idx); working_fib->ColorSinglePoint(i, p_idx, rgb); } else { p = points->GetPoint(j); working_fib->ColorSinglePoint(i, j, rgb); } double pixelValue = mitk::imv::GetImageValue(mitk::imv::GetItkPoint(p), true, interpolator); output.put(j, i, pixelValue); } } return output; } } diff --git a/Modules/FiberTracking/Algorithms/mitkTractometry.h b/Modules/FiberTracking/Algorithms/mitkTractometry.h index d328036..3e6c64b 100644 --- a/Modules/FiberTracking/Algorithms/mitkTractometry.h +++ b/Modules/FiberTracking/Algorithms/mitkTractometry.h @@ -1,57 +1,59 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 TractometryFilter_h #define TractometryFilter_h // MITK #include #include #include #include // ITK #include // VTK #include #include #include #include #include namespace mitk{ /** * \brief */ class MITKFIBERTRACKING_EXPORT Tractometry { public: static vnl_matrix StaticResamplingTractometry(itk::Image::Pointer itkImage, mitk::FiberBundle::Pointer fib, unsigned int num_points, mitk::FiberBundle::Pointer ref_fib); static std::vector> NearestCentroidPointTractometry(itk::Image::Pointer itkImage, mitk::FiberBundle::Pointer fib, unsigned int num_points, unsigned int max_centroids, float cluster_size, mitk::FiberBundle::Pointer ref_fib); + static unsigned int EstimateNumSamplingPoints(itk::Image::Pointer ref_image, mitk::FiberBundle::Pointer fib, unsigned int voxels); + + static void ResampleIfNecessary(mitk::FiberBundle::Pointer fib, unsigned int num_points); + protected: static bool Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer< vtkPolyData > ref_poly=nullptr); - static void ResampleIfNecessary(mitk::FiberBundle::Pointer fib, unsigned int num_points); - }; } #endif diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp index 96ac42d..01fba29 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp @@ -1,440 +1,450 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 "QmitkTractometryView.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 const std::string QmitkTractometryView::VIEW_ID = "org.mitk.views.tractometry"; using namespace mitk; QmitkTractometryView::QmitkTractometryView() : QmitkAbstractView() , m_Controls( nullptr ) , m_Visible(false) { } // Destructor QmitkTractometryView::~QmitkTractometryView() { } void QmitkTractometryView::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::QmitkTractometryViewControls; m_Controls->setupUi( parent ); connect( m_Controls->m_MethodBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()) ); connect( m_Controls->m_StartButton, SIGNAL(clicked()), this, SLOT(StartTractometry()) ); mitk::TNodePredicateDataType::Pointer imageP = mitk::TNodePredicateDataType::New(); mitk::NodePredicateDimension::Pointer dimP = mitk::NodePredicateDimension::New(3); m_Controls->m_ImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_ImageBox->SetPredicate(mitk::NodePredicateAnd::New(imageP, dimP)); m_Controls->m_ChartWidget->SetXAxisLabel("Tract position"); m_Controls->m_ChartWidget->SetYAxisLabel("Image Value"); m_Controls->m_ChartWidget->SetTheme(QmitkChartWidget::ColorTheme::darkstyle); } } void QmitkTractometryView::SetFocus() { } void QmitkTractometryView::UpdateGui() { berry::IWorkbenchPart::Pointer nullPart; OnSelectionChanged(nullPart, QList(m_CurrentSelection)); } void QmitkTractometryView::StaticResamplingTractometry(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector > &data, std::string& clipboard_string) { itk::Image::Pointer itkImage = itk::Image::New(); CastToItkImage(image, itkImage); mitk::FiberBundle::Pointer fib = dynamic_cast(node->GetData()); - unsigned int num_points = m_Controls->m_SamplingPointsBox->value(); + unsigned int num_points = m_NumSamplingPoints; mitk::FiberBundle::Pointer working_fib = fib->GetDeepCopy(); vnl_matrix output = mitk::Tractometry::StaticResamplingTractometry(itkImage, working_fib, num_points, m_ReferenceFib); std::vector< double > std_values1; std::vector< double > std_values2; std::vector< double > mean_values; for (unsigned int i=0; i(mean); clipboard_string += " "; clipboard_string += boost::lexical_cast(stdev); clipboard_string += "\n"; mean_values.push_back(mean); std_values1.push_back(mean + stdev); std_values2.push_back(mean - stdev); } clipboard_string += "\n"; data.push_back(mean_values); data.push_back(std_values1); data.push_back(std_values2); if (m_Controls->m_ShowBinned->isChecked()) { mitk::DataNode::Pointer new_node = mitk::DataNode::New(); new_node->SetData(working_fib); new_node->SetName("binned_static"); new_node->SetVisibility(true); node->SetVisibility(false); GetDataStorage()->Add(new_node, node); } } void QmitkTractometryView::NearestCentroidPointTractometry(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string) { mitk::FiberBundle::Pointer fib = dynamic_cast(node->GetData()); - unsigned int num_points = m_Controls->m_SamplingPointsBox->value(); + unsigned int num_points = m_NumSamplingPoints; mitk::FiberBundle::Pointer working_fib = fib->GetDeepCopy(); working_fib->ResampleSpline(1.0); itk::Image::Pointer itkImage = itk::Image::New(); CastToItkImage(image, itkImage); auto output = mitk::Tractometry::NearestCentroidPointTractometry(itkImage, working_fib, num_points, m_Controls->m_MaxCentroids->value(), m_Controls->m_ClusterSize->value(), m_ReferenceFib); std::vector< double > std_values1; std::vector< double > std_values2; std::vector< double > mean_values; for (auto row : output) { float mean = row.mean(); double stdev = 0; for (unsigned int j=0; j(mean); clipboard_string += " "; clipboard_string += boost::lexical_cast(stdev); clipboard_string += "\n"; mean_values.push_back(mean); std_values1.push_back(mean + stdev); std_values2.push_back(mean - stdev); } clipboard_string += "\n"; data.push_back(mean_values); data.push_back(std_values1); data.push_back(std_values2); if (m_Controls->m_ShowBinned->isChecked()) { mitk::DataNode::Pointer new_node = mitk::DataNode::New(); new_node->SetData(working_fib); new_node->SetName("binned_centroid"); new_node->SetVisibility(true); node->SetVisibility(false); GetDataStorage()->Add(new_node, node); } } void QmitkTractometryView::Activated() { } void QmitkTractometryView::Deactivated() { } void QmitkTractometryView::Visible() { m_Visible = true; QList selection = GetDataManagerSelection(); berry::IWorkbenchPart::Pointer nullPart; OnSelectionChanged(nullPart, selection); } void QmitkTractometryView::Hidden() { m_Visible = false; } std::string QmitkTractometryView::RGBToHexString(double *rgb) { std::ostringstream os; for (int i = 0; i < 3; ++i) { os << std::setw(2) << std::setfill('0') << std::hex << static_cast(rgb[i] * 255); } return os.str(); } void QmitkTractometryView::AlongTractRadiomicsPreprocessing(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string) { mitk::FiberBundle::Pointer fib = dynamic_cast(node->GetData()); // calculate mask typedef itk::Image ParcellationImageType; ParcellationImageType::Pointer itkImage = ParcellationImageType::New(); CastToItkImage(image, itkImage); itk::TractParcellationFilter< >::Pointer parcellator = itk::TractParcellationFilter< >::New(); parcellator->SetInputImage(itkImage); - parcellator->SetNumParcels(m_Controls->m_SamplingPointsBox->value()); + parcellator->SetNumParcels(m_NumSamplingPoints); parcellator->SetInputTract(fib); parcellator->SetNumCentroids(m_Controls->m_MaxCentroids->value()); parcellator->SetStartClusterSize(m_Controls->m_ClusterSize->value()); parcellator->Update(); ParcellationImageType::Pointer out_image = parcellator->GetOutput(0); ParcellationImageType::Pointer out_image_pp = parcellator->GetOutput(1); auto binary_masks = parcellator->GetBinarySplit(out_image_pp); mitk::Image::Pointer seg_img = mitk::Image::New(); seg_img->InitializeByItk(out_image.GetPointer()); seg_img->SetVolume(out_image->GetBufferPointer()); mitk::Image::Pointer seg_img_pp = mitk::Image::New(); seg_img_pp->InitializeByItk(out_image_pp.GetPointer()); seg_img_pp->SetVolume(out_image_pp->GetBufferPointer()); std::vector< double > std_values1; std::vector< double > std_values2; std::vector< double > mean_values; for (auto mask : binary_masks) { itk::Image::Pointer data_image = itk::Image::New(); CastToItkImage(image, data_image); itk::MaskedStatisticsImageFilter>::Pointer statisticsImageFilter = itk::MaskedStatisticsImageFilter>::New(); statisticsImageFilter->SetInput(data_image); statisticsImageFilter->SetMask(mask); statisticsImageFilter->Update(); double mean = statisticsImageFilter->GetMean(); double stdev = std::sqrt(statisticsImageFilter->GetVariance()); std_values1.push_back(mean + stdev); std_values2.push_back(mean - stdev); mean_values.push_back(mean); clipboard_string += boost::lexical_cast(mean); clipboard_string += " "; clipboard_string += boost::lexical_cast(stdev); clipboard_string += "\n"; } clipboard_string += "\n"; data.push_back(mean_values); data.push_back(std_values1); data.push_back(std_values2); mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); lut->SetType( mitk::LookupTable::MULTILABEL ); mitk::LookupTableProperty::Pointer lut_prop = mitk::LookupTableProperty::New(); lut_prop->SetLookupTable( lut ); mitk::LevelWindow lw; lw.SetRangeMinMax(0, parcellator->GetNumParcels()); // mitk::DataNode::Pointer new_node = mitk::DataNode::New(); // new_node->SetData(seg_img); // new_node->SetName("tract parcellation"); // new_node->SetVisibility(true); // new_node->SetProperty("LookupTable", lut_prop ); // new_node->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( lw ) ); // node->SetVisibility(false); // GetDataStorage()->Add(new_node, node); mitk::DataNode::Pointer new_node2 = mitk::DataNode::New(); new_node2->SetData(seg_img_pp); new_node2->SetName("tract parcellation pp"); new_node2->SetVisibility(false); new_node2->SetProperty("LookupTable", lut_prop ); new_node2->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( lw ) ); GetDataStorage()->Add(new_node2, node); mitk::DataNode::Pointer new_node3 = mitk::DataNode::New(); auto working_fib = fib->GetDeepCopy(); working_fib->ColorFibersByScalarMap(seg_img, false, false, mitk::LookupTable::LookupTableType::MULTILABEL, 0.9); new_node3->SetData(working_fib); new_node3->SetName("centroids"); GetDataStorage()->Add(new_node3, node); } void QmitkTractometryView::StartTractometry() { m_ReferenceFib = dynamic_cast(m_CurrentSelection.at(0)->GetData())->GetDeepCopy(); + mitk::Image::Pointer image = dynamic_cast(m_Controls->m_ImageBox->GetSelectedNode()->GetData()); + MITK_INFO << "Resanmpling reference fibers"; - m_ReferenceFib->ResampleToNumPoints(m_Controls->m_SamplingPointsBox->value()); + if (m_Controls->m_SamplingPointsBox->value()<3) + { + typedef itk::Image ParcellationImageType; + ParcellationImageType::Pointer itkImage = ParcellationImageType::New(); + CastToItkImage(image, itkImage); + + m_NumSamplingPoints = mitk::Tractometry::EstimateNumSamplingPoints(itkImage, m_ReferenceFib, 3); + } + else + m_NumSamplingPoints = m_Controls->m_SamplingPointsBox->value(); + m_ReferenceFib->ResampleToNumPoints(m_NumSamplingPoints); double color[3] = {0,0,0}; mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); lookupTable->SetType(mitk::LookupTable::MULTILABEL); - mitk::Image::Pointer image = dynamic_cast(m_Controls->m_ImageBox->GetSelectedNode()->GetData()); - this->m_Controls->m_ChartWidget->Clear(); std::string clipboardString = ""; int c = 1; for (auto node : m_CurrentSelection) { clipboardString += node->GetName() + "\n"; clipboardString += "mean stdev\n"; std::vector< std::vector< double > > data; switch (m_Controls->m_MethodBox->currentIndex()) { case 0: { StaticResamplingTractometry( image, node, data, clipboardString ); break; } case 1: { NearestCentroidPointTractometry( image, node, data, clipboardString ); break; } case 2: { AlongTractRadiomicsPreprocessing(image, node, data, clipboardString); break; } default: { StaticResamplingTractometry( image, node, data, clipboardString ); } } m_Controls->m_ChartWidget->AddData1D(data.at(0), node->GetName() + " Mean", QmitkChartWidget::ChartType::line); m_Controls->m_ChartWidget->SetLineStyle(node->GetName() + " Mean", QmitkChartWidget::LineStyle::solid); if (m_Controls->m_StDevBox->isChecked()) { m_Controls->m_ChartWidget->AddData1D(data.at(1), node->GetName() + " +STDEV", QmitkChartWidget::ChartType::line); m_Controls->m_ChartWidget->AddData1D(data.at(2), node->GetName() + " -STDEV", QmitkChartWidget::ChartType::line); m_Controls->m_ChartWidget->SetLineStyle(node->GetName() + " +STDEV", QmitkChartWidget::LineStyle::dashed); m_Controls->m_ChartWidget->SetLineStyle(node->GetName() + " -STDEV", QmitkChartWidget::LineStyle::dashed); } lookupTable->GetTableValue(c, color); this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " Mean", RGBToHexString(color)); if (m_Controls->m_StDevBox->isChecked()) { color[0] *= 0.5; color[1] *= 0.5; color[2] *= 0.5; this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " +STDEV", RGBToHexString(color)); this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " -STDEV", RGBToHexString(color)); } this->m_Controls->m_ChartWidget->Show(true); this->m_Controls->m_ChartWidget->SetShowDataPoints(false); ++c; } QApplication::clipboard()->setText(clipboardString.c_str(), QClipboard::Clipboard); } void QmitkTractometryView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes) { m_Controls->m_StartButton->setEnabled(false); if (!m_Visible) return; if (m_Controls->m_MethodBox->currentIndex()==0) m_Controls->m_ClusterFrame->setVisible(false); else m_Controls->m_ClusterFrame->setVisible(true); m_CurrentSelection.clear(); if(m_Controls->m_ImageBox->GetSelectedNode().IsNull()) return; for (auto node: nodes) if ( dynamic_cast(node->GetData()) ) m_CurrentSelection.push_back(node); if (!m_CurrentSelection.empty()) m_Controls->m_StartButton->setEnabled(true); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h index 618203d..ed7b3b5 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h @@ -1,83 +1,84 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. 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 QmitkTractometryView_h #define QmitkTractometryView_h #include #include "ui_QmitkTractometryViewControls.h" #include #include #include #include #include #include /*! \brief Weight fibers by linearly fitting them to the image data. */ class QmitkTractometryView : public QmitkAbstractView, public mitk::ILifecycleAwarePart { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; QmitkTractometryView(); virtual ~QmitkTractometryView(); virtual void CreateQtPartControl(QWidget *parent) override; void StaticResamplingTractometry(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string); void NearestCentroidPointTractometry(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string); void AlongTractRadiomicsPreprocessing(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector > &data, std::string &clipboard_string); virtual void SetFocus() override; virtual void Activated() override; virtual void Deactivated() override; virtual void Visible() override; virtual void Hidden() override; protected slots: void UpdateGui(); void StartTractometry(); protected: /// \brief called by QmitkAbstractView when DataManager's selection has changed virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override; Ui::QmitkTractometryViewControls* m_Controls; std::string RGBToHexString(double *rgb); mitk::FiberBundle::Pointer m_ReferenceFib; QList m_CurrentSelection; + unsigned int m_NumSamplingPoints; bool m_Visible; }; #endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED