diff --git a/Modules/DiffusionImaging/MiniApps/CMakeLists.txt b/Modules/DiffusionImaging/MiniApps/CMakeLists.txt index 80021cd166..6c0dcc946f 100755 --- a/Modules/DiffusionImaging/MiniApps/CMakeLists.txt +++ b/Modules/DiffusionImaging/MiniApps/CMakeLists.txt @@ -1,63 +1,64 @@ option(BUILD_DiffusionMiniApps "Build commandline tools for diffusion" OFF) if(BUILD_DiffusionMiniApps OR MITK_BUILD_ALL_APPS) # needed include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) project( mitkDiffusionMiniApps ) # fill in the standalone executables here set(DIFFUSIONMINIAPPS mitkDiffusionMiniApps ) # set additional files here set(DIFFUSIONCORE_ADDITIONAL_FILES MiniAppManager.cpp FileFormatConverter.cpp TensorReconstruction.cpp QballReconstruction.cpp DiffusionIndices.cpp CopyGeometry.cpp GibbsTracking.cpp StreamlineTracking.cpp FiberProcessing.cpp LocalDirectionalFiberPlausibility.cpp #TractogramAngularError.cpp FiberDirectionExtraction.cpp PeakExtraction.cpp PeaksAngularError.cpp MultishellMethods.cpp #FiberFoxProcessing.cpp ExportShImage.cpp NetworkCreation.cpp NetworkStatistics.cpp + DwiDenoising.cpp ) # deprecated # FOREACH(tool ${DIFFUSIONMINIAPPS}) # ADD_EXECUTABLE( # ${tool} # ${tool}.cpp # ${DIFFUSIONCORE_ADDITIONAL_FILES} # ) # TARGET_LINK_LIBRARIES( # ${tool} # ${ALL_LIBRARIES} ) # ENDFOREACH(tool) mitk_create_executable(mitkDiffusionMiniApps DEPENDS DiffusionCore FiberTracking Connectomics PACKAGE_DEPENDS ITK|ITKDiffusionTensorImage ) if(EXECUTABLE_IS_ENABLED) MITK_INSTALL_TARGETS(EXECUTABLES mitkDiffusionMiniApps ) endif() endif() diff --git a/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp b/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp new file mode 100644 index 0000000000..cdf386775a --- /dev/null +++ b/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp @@ -0,0 +1,172 @@ +/*=================================================================== + +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 + +typedef mitk::DiffusionImage DiffusionImageType; +typedef itk::Image ImageType; + +mitk::BaseData::Pointer LoadFile(std::string filename) +{ + if( filename.empty() ) + return NULL; + + const std::string s1="", s2=""; + std::vector infile = mitk::BaseDataIO::LoadBaseDataFromFile( filename, s1, s2, false ); + if( infile.empty() ) + { + MITK_INFO << "File " << filename << " could not be read!"; + return NULL; + } + + mitk::BaseData::Pointer baseData = infile.at(0); + return baseData; +} + +/** + * Calculate indices derived from Qball or tensor images + */ +int DwiDenoising(int argc, char* argv[]) +{ + ctkCommandLineParser parser; + parser.setArgumentPrefix("--", "-"); + parser.addArgument("input", "i", ctkCommandLineParser::String, "input image (DWI)", us::Any(), false); + parser.addArgument("mask", "m", ctkCommandLineParser::String, "brainmask for input image", us::Any(), false); + parser.addArgument("search", "s", ctkCommandLineParser::Int, "search radius", us::Any(), false); + parser.addArgument("compare", "c", ctkCommandLineParser::Int, "compare radius", us::Any(), false); + parser.addArgument("channels", "ch", ctkCommandLineParser::Int, "radius of used channels", us::Any(), true); + + map parsedArgs = parser.parseArguments(argc, argv); + if (parsedArgs.size()==0) + return EXIT_FAILURE; + + string inFileName = us::any_cast(parsedArgs["input"]); + string maskName = us::any_cast(parsedArgs["mask"]); + string outFileName = inFileName; + boost::algorithm::erase_all(outFileName, ".dwi"); + int search = us::any_cast(parsedArgs["search"]); + int compare = us::any_cast(parsedArgs["compare"]); + int channels = 0; + if (parsedArgs.count("channels")) + channels = us::any_cast(parsedArgs["channels"]); + + try + { + + + if( boost::algorithm::ends_with(inFileName, ".dwi")) + { + + DiffusionImageType::Pointer dwi = dynamic_cast(LoadFile(inFileName).GetPointer()); + mitk::Image::Pointer mask = dynamic_cast(LoadFile(maskName).GetPointer()); + ImageType::Pointer itkMask = ImageType::New(); + mitk::CastToItkImage(mask, itkMask); + + itk::NonLocalMeansDenoisingFilter::Pointer filter = itk::NonLocalMeansDenoisingFilter::New(); + filter->SetNumberOfThreads(12); + filter->SetInputImage(dwi->GetVectorImage()); + filter->SetInputMask(itkMask); + + if (channels == 0) + { + MITK_INFO << "Denoising with: s = " << search << "; c = " << compare; + + filter->SetUseJointInformation(false); + filter->SetSearchRadius(search); + filter->SetComparisonRadius(compare); + filter->Update(); + + DiffusionImageType::Pointer output = DiffusionImageType::New(); + output->SetVectorImage(filter->GetOutput()); + output->SetB_Value(dwi->GetB_Value()); + output->SetDirections(dwi->GetDirections()); + output->InitializeFromVectorImage(); + + std::stringstream name; + name << outFileName << "_NLMr_" << search << "-" << compare << ".dwi"; + + MITK_INFO << "Writing: " << name.str(); + + mitk::NrrdDiffusionImageWriter::Pointer writer = mitk::NrrdDiffusionImageWriter::New(); + writer->SetInput(output); + writer->SetFileName(name.str()); + writer->Update(); + } + + else + { + MITK_INFO << "Denoising with: s = " << search << "; c = " << compare << "; ch = " << channels; + filter->SetUseJointInformation(true); + filter->SetSearchRadius(search); + filter->SetComparisonRadius(compare); + filter->SetChannelRadius(channels); + filter->Update(); + + DiffusionImageType::Pointer output = DiffusionImageType::New(); + output->SetVectorImage(filter->GetOutput()); + output->SetB_Value(dwi->GetB_Value()); + output->SetDirections(dwi->GetDirections()); + output->InitializeFromVectorImage(); + + + std::stringstream name; + name << outFileName << "_NLMv_" << search << "-" << compare << "-" << channels << ".dwi"; + + MITK_INFO << "Writing " << name.str(); + + mitk::NrrdDiffusionImageWriter::Pointer writer = mitk::NrrdDiffusionImageWriter::New(); + writer->SetInput(output); + writer->SetFileName(name.str()); + writer->Update(); + } + + MITK_INFO << "Finish!"; + } + else + { + MITK_INFO << "Only supported for .dwi!"; + } + } + catch (itk::ExceptionObject e) + { + MITK_INFO << e; + return EXIT_FAILURE; + } + catch (std::exception e) + { + MITK_INFO << e.what(); + return EXIT_FAILURE; + } + catch (...) + { + MITK_INFO << "ERROR!?!"; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + + + +RegisterDiffusionMiniApp(DwiDenoising); diff --git a/Modules/DiffusionImaging/MiniApps/files.cmake b/Modules/DiffusionImaging/MiniApps/files.cmake index 30c2fb70da..bcd58b0f7e 100644 --- a/Modules/DiffusionImaging/MiniApps/files.cmake +++ b/Modules/DiffusionImaging/MiniApps/files.cmake @@ -1,22 +1,23 @@ set(CPP_FILES mitkDiffusionMiniApps.cpp MiniAppManager.cpp FileFormatConverter.cpp TensorReconstruction.cpp QballReconstruction.cpp DiffusionIndices.cpp CopyGeometry.cpp GibbsTracking.cpp StreamlineTracking.cpp FiberProcessing.cpp LocalDirectionalFiberPlausibility.cpp #TractogramAngularError.cpp FiberDirectionExtraction.cpp PeakExtraction.cpp PeaksAngularError.cpp MultishellMethods.cpp #FiberFoxProcessing.cpp ExportShImage.cpp NetworkCreation.cpp NetworkStatistics.cpp + DwiDenoising.cpp )