diff --git a/Modules/DiffusionCmdApps/CMakeLists.txt b/Modules/DiffusionCmdApps/CMakeLists.txt index ac0bdff..e4616a0 100644 --- a/Modules/DiffusionCmdApps/CMakeLists.txt +++ b/Modules/DiffusionCmdApps/CMakeLists.txt @@ -1,20 +1,20 @@ MITK_CREATE_MODULE( SUBPROJECTS MITK-Diffusion # INCLUDE_DIRS Helpers - DEPENDS MitkDiffusionCore MitkDiffusionIO + DEPENDS MitkDiffusionCore MitkDiffusionIO 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) if(MITK_USE_Python) add_subdirectory(Python) endif() endif() diff --git a/Modules/DiffusionCmdApps/Connectomics/NetworkCreation.cpp b/Modules/DiffusionCmdApps/Connectomics/NetworkCreation.cpp index d9646e0..b410d8e 100644 --- a/Modules/DiffusionCmdApps/Connectomics/NetworkCreation.cpp +++ b/Modules/DiffusionCmdApps/Connectomics/NetworkCreation.cpp @@ -1,119 +1,119 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // std includes #include // CTK includes -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" // MITK includes #include "mitkConnectomicsNetworkCreator.h" #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Network Creation"); parser.setCategory("Connectomics"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "f", mitkCommandLineParser::String, "Input Tractogram", "input tractogram (.fib)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "p", mitkCommandLineParser::String, "Parcellation", "parcellation image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output network", "where to save the output (.cnf; .mat)", us::Any(), false); + parser.addArgument("", "f", mitkDiffusionCommandLineParser::String, "Input Tractogram", "input tractogram (.fib)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "p", mitkDiffusionCommandLineParser::String, "Parcellation", "parcellation image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output network", "where to save the output (.cnf; .mat)", us::Any(), false); - parser.addArgument("noCenterOfMass", "", mitkCommandLineParser::Bool, "No center of mass", "Do not use center of mass for node positions"); + parser.addArgument("noCenterOfMass", "", mitkDiffusionCommandLineParser::Bool, "No center of mass", "Do not use center of mass for node positions"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; //default values bool noCenterOfMass( false ); // parse command line arguments std::string fiberFilename = us::any_cast(parsedArgs["f"]); std::string parcellationFilename = us::any_cast(parsedArgs["p"]); std::string outputFilename = us::any_cast(parsedArgs["o"]); if (parsedArgs.count("noCenterOfMass")) noCenterOfMass = us::any_cast(parsedArgs["noCenterOfMass"]); try { // load fiber image std::vector fiberInfile = mitk::IOUtil::Load( fiberFilename); if( fiberInfile.empty() ) { std::string errorMessage = "Fiber Image at " + fiberFilename + " could not be read. Aborting."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } mitk::BaseData* fiberBaseData = fiberInfile.at(0); mitk::FiberBundle* fiberBundle = dynamic_cast( fiberBaseData ); // load parcellation std::vector parcellationInFile = mitk::IOUtil::Load( parcellationFilename); if( parcellationInFile.empty() ) { std::string errorMessage = "Parcellation at " + parcellationFilename + " could not be read. Aborting."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } mitk::BaseData* parcellationBaseData = parcellationInFile.at(0); mitk::Image* parcellationImage = dynamic_cast( parcellationBaseData ); // do creation mitk::ConnectomicsNetworkCreator::Pointer connectomicsNetworkCreator = mitk::ConnectomicsNetworkCreator::New(); connectomicsNetworkCreator->SetSegmentation( parcellationImage ); connectomicsNetworkCreator->SetFiberBundle( fiberBundle ); if( !noCenterOfMass ) { connectomicsNetworkCreator->CalculateCenterOfMass(); } connectomicsNetworkCreator->SetMappingStrategy(mitk::ConnectomicsNetworkCreator::MappingStrategy::EndElementPosition); connectomicsNetworkCreator->CreateNetworkFromFibersAndSegmentation(); mitk::ConnectomicsNetwork::Pointer network = connectomicsNetworkCreator->GetNetwork(); mitk::IOUtil::Save(network.GetPointer(), outputFilename ); return EXIT_SUCCESS; } 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; } std::cout << "DONE"; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/Connectomics/NetworkStatistics.cpp b/Modules/DiffusionCmdApps/Connectomics/NetworkStatistics.cpp index 758babe..2d62607 100644 --- a/Modules/DiffusionCmdApps/Connectomics/NetworkStatistics.cpp +++ b/Modules/DiffusionCmdApps/Connectomics/NetworkStatistics.cpp @@ -1,570 +1,570 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // std includes #include #include #include #include #include #include // boost includes #include // ITK includes #include // CTK includes -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" // MITK includes #include #include #include #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Network Creation"); parser.setCategory("Connectomics"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input network", "input connectomics network (.cnf)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output file", "name of output file", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input network", "input connectomics network (.cnf)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output file", "name of output file", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); - parser.addArgument("noGlobalStatistics", "g", mitkCommandLineParser::Bool, "No global statistics", "Do not calculate global statistics"); - parser.addArgument("createConnectivityMatriximage", "I", mitkCommandLineParser::Bool, "Write connectivity matrix image", "Write connectivity matrix image"); - parser.addArgument("binaryConnectivity", "b", mitkCommandLineParser::Bool, "Binary connectivity", "Whether to create a binary connectivity matrix"); - parser.addArgument("rescaleConnectivity", "r", mitkCommandLineParser::Bool, "Rescale connectivity", "Whether to rescale the connectivity matrix"); - parser.addArgument("localStatistics", "L", mitkCommandLineParser::StringList, "Local statistics", "Provide a list of node labels for local statistics", us::Any()); - parser.addArgument("regionList", "R", mitkCommandLineParser::StringList, "Region list", "A space separated list of regions. Each region has the format\n regionname;label1;label2;...;labelN", us::Any()); - parser.addArgument("granularity", "gr", mitkCommandLineParser::Int, "Granularity", "How finely to test the density range and how many thresholds to consider",1); - parser.addArgument("startDensity", "d", mitkCommandLineParser::Float, "Start Density", "Largest density for the range",1.0); - parser.addArgument("thresholdStepSize", "t", mitkCommandLineParser::Int, "Step size threshold", "Distance of two adjacent thresholds",3); + parser.addArgument("noGlobalStatistics", "g", mitkDiffusionCommandLineParser::Bool, "No global statistics", "Do not calculate global statistics"); + parser.addArgument("createConnectivityMatriximage", "I", mitkDiffusionCommandLineParser::Bool, "Write connectivity matrix image", "Write connectivity matrix image"); + parser.addArgument("binaryConnectivity", "b", mitkDiffusionCommandLineParser::Bool, "Binary connectivity", "Whether to create a binary connectivity matrix"); + parser.addArgument("rescaleConnectivity", "r", mitkDiffusionCommandLineParser::Bool, "Rescale connectivity", "Whether to rescale the connectivity matrix"); + parser.addArgument("localStatistics", "L", mitkDiffusionCommandLineParser::StringList, "Local statistics", "Provide a list of node labels for local statistics", us::Any()); + parser.addArgument("regionList", "R", mitkDiffusionCommandLineParser::StringList, "Region list", "A space separated list of regions. Each region has the format\n regionname;label1;label2;...;labelN", us::Any()); + parser.addArgument("granularity", "gr", mitkDiffusionCommandLineParser::Int, "Granularity", "How finely to test the density range and how many thresholds to consider",1); + parser.addArgument("startDensity", "d", mitkDiffusionCommandLineParser::Float, "Start Density", "Largest density for the range",1.0); + parser.addArgument("thresholdStepSize", "t", mitkDiffusionCommandLineParser::Int, "Step size threshold", "Distance of two adjacent thresholds",3); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; //default values bool noGlobalStatistics( false ); bool binaryConnectivity( false ); bool rescaleConnectivity( false ); bool createConnectivityMatriximage( false ); int granularity( 1 ); double startDensity( 1.0 ); int thresholdStepSize( 3 ); // parse command line arguments std::string networkName = us::any_cast(parsedArgs["i"]); std::string outName = us::any_cast(parsedArgs["o"]); - mitkCommandLineParser::StringContainerType localLabels; + mitkDiffusionCommandLineParser::StringContainerType localLabels; if(parsedArgs.count("localStatistics")) { - localLabels = us::any_cast(parsedArgs["localStatistics"]); + localLabels = us::any_cast(parsedArgs["localStatistics"]); } - mitkCommandLineParser::StringContainerType unparsedRegions; + mitkDiffusionCommandLineParser::StringContainerType unparsedRegions; std::map< std::string, std::vector > parsedRegions; std::map< std::string, std::vector >::iterator parsedRegionsIterator; if(parsedArgs.count("regionList")) { - unparsedRegions = us::any_cast(parsedArgs["regionList"]); + unparsedRegions = us::any_cast(parsedArgs["regionList"]); for(unsigned int index(0); index < unparsedRegions.size(); index++ ) { std::vector< std::string > tempRegionVector; boost::split(tempRegionVector, unparsedRegions.at(index), boost::is_any_of(";")); std::vector< std::string >::const_iterator begin = tempRegionVector.begin(); std::vector< std::string >::const_iterator last = tempRegionVector.begin() + tempRegionVector.size(); std::vector< std::string > insertRegionVector(begin + 1, last); if( parsedRegions.count( tempRegionVector.at(0) ) == 0 ) { parsedRegions.insert( std::pair< std::string, std::vector >( tempRegionVector.at(0), insertRegionVector) ); } else { MITK_ERROR << "Region already exists. Skipping second occurrence."; } } } if (parsedArgs.count("noGlobalStatistics")) noGlobalStatistics = us::any_cast(parsedArgs["noGlobalStatistics"]); if (parsedArgs.count("binaryConnectivity")) binaryConnectivity = us::any_cast(parsedArgs["binaryConnectivity"]); if (parsedArgs.count("rescaleConnectivity")) rescaleConnectivity = us::any_cast(parsedArgs["rescaleConnectivity"]); if (parsedArgs.count("createConnectivityMatriximage")) createConnectivityMatriximage = us::any_cast(parsedArgs["createConnectivityMatriximage"]); if (parsedArgs.count("granularity")) granularity = us::any_cast(parsedArgs["granularity"]); if (parsedArgs.count("startDensity")) startDensity = us::any_cast(parsedArgs["startDensity"]); if (parsedArgs.count("thresholdStepSize")) thresholdStepSize = us::any_cast(parsedArgs["thresholdStepSize"]); try { // load network std::vector networkFile = mitk::IOUtil::Load( networkName); if( networkFile.empty() ) { std::string errorMessage = "File at " + networkName + " could not be read. Aborting."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } mitk::BaseData* networkBaseData = networkFile.at(0); mitk::ConnectomicsNetwork* network = dynamic_cast( networkBaseData ); if( !network ) { std::string errorMessage = "Read file at " + networkName + " could not be recognized as network. Aborting."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } // streams std::stringstream globalHeaderStream; globalHeaderStream << "NumberOfVertices " << "NumberOfEdges " << "AverageDegree " << "ConnectionDensity " << "NumberOfConnectedComponents " << "AverageComponentSize " << "LargestComponentSize " << "RatioOfNodesInLargestComponent " << "HopPlotExponent " << "EffectiveHopDiameter " << "AverageClusteringCoefficientsC " << "AverageClusteringCoefficientsD " << "AverageClusteringCoefficientsE " << "AverageVertexBetweennessCentrality " << "AverageEdgeBetweennessCentrality " << "NumberOfIsolatedPoints " << "RatioOfIsolatedPoints " << "NumberOfEndPoints " << "RatioOfEndPoints " << "Diameter " << "Diameter90 " << "Radius " << "Radius90 " << "AverageEccentricity " << "AverageEccentricity90 " << "AveragePathLength " << "NumberOfCentralPoints " << "RatioOfCentralPoints " << "SpectralRadius " << "SecondLargestEigenValue " << "AdjacencyTrace " << "AdjacencyEnergy " << "LaplacianTrace " << "LaplacianEnergy " << "LaplacianSpectralGap " << "NormalizedLaplacianTrace " << "NormalizedLaplacianEnergy " << "NormalizedLaplacianNumberOf2s " << "NormalizedLaplacianNumberOf1s " << "NormalizedLaplacianNumberOf0s " << "NormalizedLaplacianLowerSlope " << "NormalizedLaplacianUpperSlope " << "SmallWorldness" << std::endl; std::stringstream localHeaderStream; std::stringstream regionalHeaderStream; std::stringstream globalDataStream; std::stringstream localDataStream; std::stringstream regionalDataStream; std::string globalOutName = outName + "_global.txt"; std::string localOutName = outName + "_local.txt"; std::string regionalOutName = outName + "_regional.txt"; bool firstRun( true ); // iterate over all three possible methods for(unsigned int method( 0 ); method < 3; method++) { // 0 - Random removal threshold // 1 - Largest density below threshold // 2 - Threshold based // iterate over possible targets for( int step = 0; step < granularity; ++step ) { double targetValue( 0.0 ); switch ( method ) { case mitk::ConnectomicsNetworkThresholder::RandomRemovalOfWeakest : case mitk::ConnectomicsNetworkThresholder::LargestLowerThanDensity : targetValue = startDensity * (1 - static_cast( step ) / ( granularity + 0.5 ) ); break; case mitk::ConnectomicsNetworkThresholder::ThresholdBased : targetValue = static_cast( thresholdStepSize * step ); break; default: MITK_ERROR << "Invalid thresholding method called, aborting."; return EXIT_FAILURE; break; } mitk::ConnectomicsNetworkThresholder::Pointer thresholder = mitk::ConnectomicsNetworkThresholder::New(); thresholder->SetNetwork( network ); thresholder->SetTargetThreshold( targetValue ); thresholder->SetTargetDensity( targetValue ); thresholder->SetThresholdingScheme( static_cast(method) ); mitk::ConnectomicsNetwork::Pointer thresholdedNetwork = thresholder->GetThresholdedNetwork(); mitk::ConnectomicsStatisticsCalculator::Pointer statisticsCalculator = mitk::ConnectomicsStatisticsCalculator::New(); statisticsCalculator->SetNetwork( thresholdedNetwork ); statisticsCalculator->Update(); // global statistics if( !noGlobalStatistics ) { globalDataStream << statisticsCalculator->GetNumberOfVertices() << " " << statisticsCalculator->GetNumberOfEdges() << " " << statisticsCalculator->GetAverageDegree() << " " << statisticsCalculator->GetConnectionDensity() << " " << statisticsCalculator->GetNumberOfConnectedComponents() << " " << statisticsCalculator->GetAverageComponentSize() << " " << statisticsCalculator->GetLargestComponentSize() << " " << statisticsCalculator->GetRatioOfNodesInLargestComponent() << " " << statisticsCalculator->GetHopPlotExponent() << " " << statisticsCalculator->GetEffectiveHopDiameter() << " " << statisticsCalculator->GetAverageClusteringCoefficientsC() << " " << statisticsCalculator->GetAverageClusteringCoefficientsD() << " " << statisticsCalculator->GetAverageClusteringCoefficientsE() << " " << statisticsCalculator->GetAverageVertexBetweennessCentrality() << " " << statisticsCalculator->GetAverageEdgeBetweennessCentrality() << " " << statisticsCalculator->GetNumberOfIsolatedPoints() << " " << statisticsCalculator->GetRatioOfIsolatedPoints() << " " << statisticsCalculator->GetNumberOfEndPoints() << " " << statisticsCalculator->GetRatioOfEndPoints() << " " << statisticsCalculator->GetDiameter() << " " << statisticsCalculator->GetDiameter90() << " " << statisticsCalculator->GetRadius() << " " << statisticsCalculator->GetRadius90() << " " << statisticsCalculator->GetAverageEccentricity() << " " << statisticsCalculator->GetAverageEccentricity90() << " " << statisticsCalculator->GetAveragePathLength() << " " << statisticsCalculator->GetNumberOfCentralPoints() << " " << statisticsCalculator->GetRatioOfCentralPoints() << " " << statisticsCalculator->GetSpectralRadius() << " " << statisticsCalculator->GetSecondLargestEigenValue() << " " << statisticsCalculator->GetAdjacencyTrace() << " " << statisticsCalculator->GetAdjacencyEnergy() << " " << statisticsCalculator->GetLaplacianTrace() << " " << statisticsCalculator->GetLaplacianEnergy() << " " << statisticsCalculator->GetLaplacianSpectralGap() << " " << statisticsCalculator->GetNormalizedLaplacianTrace() << " " << statisticsCalculator->GetNormalizedLaplacianEnergy() << " " << statisticsCalculator->GetNormalizedLaplacianNumberOf2s() << " " << statisticsCalculator->GetNormalizedLaplacianNumberOf1s() << " " << statisticsCalculator->GetNormalizedLaplacianNumberOf0s() << " " << statisticsCalculator->GetNormalizedLaplacianLowerSlope() << " " << statisticsCalculator->GetNormalizedLaplacianUpperSlope() << " " << statisticsCalculator->GetSmallWorldness() << std::endl; } // end global statistics //create connectivity matrix png if( createConnectivityMatriximage ) { std::string connectivity_png_postfix = "_connectivity"; if( binaryConnectivity ) { connectivity_png_postfix += "_binary"; } else if( rescaleConnectivity ) { connectivity_png_postfix += "_rescaled"; } connectivity_png_postfix += ".png"; /* File format * A png file depicting the binary connectivity matrix */ itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::Pointer filter = itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::New(); filter->SetInputNetwork( network ); filter->SetBinaryConnectivity( binaryConnectivity ); filter->SetRescaleConnectivity( rescaleConnectivity ); filter->Update(); typedef itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::OutputImageType connectivityMatrixImageType; mitk::LocaleSwitch localeSwitch("C"); itk::ImageFileWriter< connectivityMatrixImageType >::Pointer connectivityWriter = itk::ImageFileWriter< connectivityMatrixImageType >::New(); connectivityWriter->SetInput( filter->GetOutput() ); connectivityWriter->SetFileName( outName + connectivity_png_postfix); connectivityWriter->Update(); std::cout << "Connectivity matrix image written."; } // end create connectivity matrix png /* * We can either calculate local indices for specific nodes, or specific regions */ // Create LabelToIndex translation std::map< std::string, int > labelToIdMap; std::vector< mitk::ConnectomicsNetwork::NetworkNode > nodeVector = thresholdedNetwork->GetVectorOfAllNodes(); for(std::size_t loop(0); loop < nodeVector.size(); loop++) { labelToIdMap.insert( std::pair< std::string, int>(nodeVector.at(loop).label, nodeVector.at(loop).id) ); } std::vector< int > degreeVector = thresholdedNetwork->GetDegreeOfNodes(); std::vector< double > ccVector = thresholdedNetwork->GetLocalClusteringCoefficients( ); std::vector< double > bcVector = thresholdedNetwork->GetNodeBetweennessVector( ); // calculate local indices { // only add to header for the first step of the first method if( firstRun ) { localHeaderStream << "Th_method " << "Th_target " << "density"; } double density = statisticsCalculator->GetConnectionDensity(); localDataStream << "\n" << method << " " << targetValue << " " << density; for(unsigned int loop(0); loop < localLabels.size(); loop++ ) { if( network->CheckForLabel(localLabels.at( loop )) ) { if( firstRun ) { localHeaderStream << " " << localLabels.at( loop ) << "_Degree " << localLabels.at( loop ) << "_CC " << localLabels.at( loop ) << "_BC"; } localDataStream << " " << degreeVector.at( labelToIdMap.find( localLabels.at( loop ) )->second ) << " " << ccVector.at( labelToIdMap.find( localLabels.at( loop ) )->second ) << " " << bcVector.at( labelToIdMap.find( localLabels.at( loop ) )->second ); } else { MITK_ERROR << "Illegal label. Label: \"" << localLabels.at( loop ) << "\" not found."; } } } // calculate regional indices { // only add to header for the first step of the first method if( firstRun ) { regionalHeaderStream << "Th_method " << "Th_target " << "density"; } double density = statisticsCalculator->GetConnectionDensity(); regionalDataStream << "\n" << method << " " << targetValue << " " << density; for( parsedRegionsIterator = parsedRegions.begin(); parsedRegionsIterator != parsedRegions.end(); parsedRegionsIterator++ ) { std::vector regionLabelsVector = parsedRegionsIterator->second; std::string regionName = parsedRegionsIterator->first; double sumDegree( 0 ); double sumCC( 0 ); double sumBC( 0 ); double count( 0 ); for( std::size_t loop(0); loop < regionLabelsVector.size(); loop++ ) { if( thresholdedNetwork->CheckForLabel(regionLabelsVector.at( loop )) ) { sumDegree = sumDegree + degreeVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second ); sumCC = sumCC + ccVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second ); sumBC = sumBC + bcVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second ); count = count + 1; } else { MITK_ERROR << "Illegal label. Label: \"" << regionLabelsVector.at( loop ) << "\" not found."; } } // only add to header for the first step of the first method if( firstRun ) { regionalHeaderStream << " " << regionName << "_LocalAverageDegree " << regionName << "_LocalAverageCC " << regionName << "_LocalAverageBC " << regionName << "_NumberOfNodes"; } regionalDataStream << " " << sumDegree / count << " " << sumCC / count << " " << sumBC / count << " " << count; // count number of connections and fibers between regions std::map< std::string, std::vector >::iterator loopRegionsIterator; for (loopRegionsIterator = parsedRegionsIterator; loopRegionsIterator != parsedRegions.end(); loopRegionsIterator++) { int numberConnections(0), possibleConnections(0); double summedFiberCount(0.0); std::vector loopLabelsVector = loopRegionsIterator->second; std::string loopName = loopRegionsIterator->first; for (std::size_t loop(0); loop < regionLabelsVector.size(); loop++) { if (thresholdedNetwork->CheckForLabel(regionLabelsVector.at(loop))) { for (std::size_t innerLoop(0); innerLoop < loopLabelsVector.size(); innerLoop++) { if (thresholdedNetwork->CheckForLabel(loopLabelsVector.at(loop))) { bool exists = thresholdedNetwork->EdgeExists( labelToIdMap.find(regionLabelsVector.at(loop))->second, labelToIdMap.find(loopLabelsVector.at(innerLoop))->second); possibleConnections++; if (exists) { numberConnections++; summedFiberCount += thresholdedNetwork->GetEdge( labelToIdMap.find(regionLabelsVector.at(loop))->second, labelToIdMap.find(loopLabelsVector.at(innerLoop))->second).fiber_count; } } else { MITK_ERROR << "Illegal label. Label: \"" << loopLabelsVector.at(loop) << "\" not found."; } } } else { MITK_ERROR << "Illegal label. Label: \"" << regionLabelsVector.at(loop) << "\" not found."; } } if (firstRun) { regionalHeaderStream << " " << regionName << "_" << loopName << "_Connections " << " " << regionName << "_" << loopName << "_possibleConnections " << " " << regionName << "_" << loopName << "_ConnectingFibers"; } regionalDataStream << " " << numberConnections << " " << possibleConnections << " " << summedFiberCount; } } } firstRun = false; } }// end calculate local averages if( !noGlobalStatistics ) { std::cout << "Writing to " << globalOutName; std::ofstream glocalOutFile( globalOutName.c_str(), ios::out ); if( ! glocalOutFile.is_open() ) { std::string errorMessage = "Could not open " + globalOutName + " for writing."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } glocalOutFile << globalHeaderStream.str() << globalDataStream.str(); glocalOutFile.close(); } if( localLabels.size() > 0 ) { std::cout << "Writing to " << localOutName; std::ofstream localOutFile( localOutName.c_str(), ios::out ); if( ! localOutFile.is_open() ) { std::string errorMessage = "Could not open " + localOutName + " for writing."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } localOutFile << localHeaderStream.str() << localDataStream.str(); localOutFile.close(); } if( parsedRegions.size() > 0 ) { std::cout << "Writing to " << regionalOutName; std::ofstream regionalOutFile( regionalOutName.c_str(), ios::out ); if( ! regionalOutFile.is_open() ) { std::string errorMessage = "Could not open " + regionalOutName + " for writing."; MITK_ERROR << errorMessage; return EXIT_FAILURE; } regionalOutFile << regionalHeaderStream.str() << regionalDataStream.str(); regionalOutFile.close(); } return EXIT_SUCCESS; } catch (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; } std::cout << "DONE"; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/FiberProcessing/FiberClustering.cpp b/Modules/DiffusionCmdApps/FiberProcessing/FiberClustering.cpp index 0ddcd5a..7a68249 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/FiberClustering.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/FiberClustering.cpp @@ -1,273 +1,273 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; 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 Spatially cluster fibers */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Fiber Clustering"); parser.setCategory("Fiber Processing"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input fiber bundle (.fib; .trk; .tck)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkCommandLineParser::Output); - - parser.addArgument("cluster_size", "", mitkCommandLineParser::Int, "Cluster size:", "", 10); - parser.addArgument("fiber_points", "", mitkCommandLineParser::Int, "Fiber points:", "", 12); - parser.addArgument("min_fibers", "", mitkCommandLineParser::Int, "Min. fibers per cluster:", "", 1); - parser.addArgument("max_clusters", "", mitkCommandLineParser::Int, "Max. clusters:", ""); - parser.addArgument("merge_clusters", "", mitkCommandLineParser::Float, "Merge clusters:", "Set to 0 to avoid merging and to -1 to use the original cluster size", -1.0); - parser.addArgument("output_centroids", "", mitkCommandLineParser::Bool, "Output centroids:", ""); - parser.addArgument("only_centroids", "", mitkCommandLineParser::Bool, "Output only centroids:", ""); - parser.addArgument("merge_centroids", "", mitkCommandLineParser::Bool, "Merge centroids:", ""); - parser.addArgument("metrics", "", mitkCommandLineParser::StringList, "Metrics:", "EU_MEAN; EU_STD; EU_MAX; ANAT; MAP; LENGTH", std::string("EU_MEAN")); - parser.addArgument("metric_weights", "", mitkCommandLineParser::StringList, "Metric weights:", "add one float weight for each used metric"); - parser.addArgument("input_centroids", "", mitkCommandLineParser::String, "Input centroids:", "", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("scalar_map", "", mitkCommandLineParser::String, "Scalar map:", "", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("parcellation", "", mitkCommandLineParser::String, "Parcellation:", "", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("file_ending", "", mitkCommandLineParser::String, "File ending:", ""); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input fiber bundle (.fib; .trk; .tck)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + + parser.addArgument("cluster_size", "", mitkDiffusionCommandLineParser::Int, "Cluster size:", "", 10); + parser.addArgument("fiber_points", "", mitkDiffusionCommandLineParser::Int, "Fiber points:", "", 12); + parser.addArgument("min_fibers", "", mitkDiffusionCommandLineParser::Int, "Min. fibers per cluster:", "", 1); + parser.addArgument("max_clusters", "", mitkDiffusionCommandLineParser::Int, "Max. clusters:", ""); + parser.addArgument("merge_clusters", "", mitkDiffusionCommandLineParser::Float, "Merge clusters:", "Set to 0 to avoid merging and to -1 to use the original cluster size", -1.0); + parser.addArgument("output_centroids", "", mitkDiffusionCommandLineParser::Bool, "Output centroids:", ""); + parser.addArgument("only_centroids", "", mitkDiffusionCommandLineParser::Bool, "Output only centroids:", ""); + parser.addArgument("merge_centroids", "", mitkDiffusionCommandLineParser::Bool, "Merge centroids:", ""); + parser.addArgument("metrics", "", mitkDiffusionCommandLineParser::StringList, "Metrics:", "EU_MEAN; EU_STD; EU_MAX; ANAT; MAP; LENGTH", std::string("EU_MEAN")); + parser.addArgument("metric_weights", "", mitkDiffusionCommandLineParser::StringList, "Metric weights:", "add one float weight for each used metric"); + parser.addArgument("input_centroids", "", mitkDiffusionCommandLineParser::String, "Input centroids:", "", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("scalar_map", "", mitkDiffusionCommandLineParser::String, "Scalar map:", "", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("parcellation", "", mitkDiffusionCommandLineParser::String, "Parcellation:", "", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("file_ending", "", mitkDiffusionCommandLineParser::String, "File ending:", ""); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["i"]); std::string out_root = us::any_cast(parsedArgs["o"]); bool only_centroids = false; if (parsedArgs.count("only_centroids")) only_centroids = us::any_cast(parsedArgs["only_centroids"]); bool merge_centroids = false; if (parsedArgs.count("merge_centroids")) merge_centroids = us::any_cast(parsedArgs["merge_centroids"]); int cluster_size = 10; if (parsedArgs.count("cluster_size")) cluster_size = us::any_cast(parsedArgs["cluster_size"]); int fiber_points = 12; if (parsedArgs.count("fiber_points")) fiber_points = us::any_cast(parsedArgs["fiber_points"]); int min_fibers = 1; if (parsedArgs.count("min_fibers")) min_fibers = us::any_cast(parsedArgs["min_fibers"]); int max_clusters = 0; if (parsedArgs.count("max_clusters")) max_clusters = us::any_cast(parsedArgs["max_clusters"]); float merge_clusters = -1.0; if (parsedArgs.count("merge_clusters")) merge_clusters = us::any_cast(parsedArgs["merge_clusters"]); bool output_centroids = false; if (parsedArgs.count("output_centroids")) output_centroids = us::any_cast(parsedArgs["output_centroids"]); std::vector< std::string > metric_strings = {"EU_MEAN"}; if (parsedArgs.count("metrics")) - metric_strings = us::any_cast(parsedArgs["metrics"]); + metric_strings = us::any_cast(parsedArgs["metrics"]); std::vector< std::string > metric_weights = {"1.0"}; if (parsedArgs.count("metric_weights")) - metric_weights = us::any_cast(parsedArgs["metric_weights"]); + metric_weights = us::any_cast(parsedArgs["metric_weights"]); std::string input_centroids = ""; if (parsedArgs.count("input_centroids")) input_centroids = us::any_cast(parsedArgs["input_centroids"]); std::string scalar_map = ""; if (parsedArgs.count("scalar_map")) scalar_map = us::any_cast(parsedArgs["scalar_map"]); std::string parcellation = ""; if (parsedArgs.count("parcellation")) parcellation = us::any_cast(parsedArgs["parcellation"]); std::string file_ending = ".fib"; if (parsedArgs.count("file_ending")) file_ending = us::any_cast(parsedArgs["file_ending"]); if (metric_strings.size()!=metric_weights.size()) { MITK_INFO << "Each metric needs an associated metric weight!"; return EXIT_FAILURE; } try { typedef itk::Image< float, 3 > FloatImageType; typedef itk::Image< short, 3 > ShortImageType; mitk::FiberBundle::Pointer fib = LoadFib(inFileName); float max_d = 0; int i=1; std::vector< float > distances; while (max_d < fib->GetGeometry()->GetDiagonalLength()/2) { distances.push_back(cluster_size*i); max_d = cluster_size*i; ++i; } itk::TractClusteringFilter::Pointer clusterer = itk::TractClusteringFilter::New(); clusterer->SetDistances(distances); clusterer->SetTractogram(fib); if (input_centroids!="") { mitk::FiberBundle::Pointer in_centroids = LoadFib(input_centroids); clusterer->SetInCentroids(in_centroids); } std::vector< mitk::ClusteringMetric* > metrics; int mc = 0; for (auto m : metric_strings) { float w = boost::lexical_cast(metric_weights.at(mc)); MITK_INFO << "Metric: " << m << " (w=" << w << ")"; if (m=="EU_MEAN") metrics.push_back({new mitk::ClusteringMetricEuclideanMean()}); else if (m=="EU_STD") metrics.push_back({new mitk::ClusteringMetricEuclideanStd()}); else if (m=="EU_MAX") metrics.push_back({new mitk::ClusteringMetricEuclideanMax()}); else if (m=="ANGLES") metrics.push_back({new mitk::ClusteringMetricInnerAngles()}); else if (m=="LENGTH") metrics.push_back({new mitk::ClusteringMetricLength()}); else if (m=="MAP" && scalar_map!="") { mitk::Image::Pointer mitk_map = mitk::IOUtil::Load(scalar_map); if (mitk_map->GetDimension()==3) { FloatImageType::Pointer itk_map = FloatImageType::New(); mitk::CastToItkImage(mitk_map, itk_map); mitk::ClusteringMetricScalarMap* metric = new mitk::ClusteringMetricScalarMap(); metric->SetImages({itk_map}); metric->SetScale(distances.at(0)); metrics.push_back(metric); } } else if (m=="ANAT" && parcellation!="") { mitk::Image::Pointer mitk_map = mitk::IOUtil::Load(parcellation); if (mitk_map->GetDimension()==3) { ShortImageType::Pointer itk_map = ShortImageType::New(); mitk::CastToItkImage(mitk_map, itk_map); mitk::ClusteringMetricAnatomic* metric = new mitk::ClusteringMetricAnatomic(); metric->SetParcellations({itk_map}); metrics.push_back(metric); } } metrics.back()->SetScale(w); mc++; } if (metrics.empty()) { MITK_INFO << "No metric selected!"; return EXIT_FAILURE; } clusterer->SetMetrics(metrics); clusterer->SetMergeDuplicateThreshold(merge_clusters); clusterer->SetNumPoints(fiber_points); clusterer->SetMaxClusters(max_clusters); clusterer->SetMinClusterSize(min_fibers); clusterer->Update(); std::vector tracts = clusterer->GetOutTractograms(); std::vector centroids = clusterer->GetOutCentroids(); MITK_INFO << "Saving clusters"; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect if (!only_centroids) for (unsigned int i=0; i(i) + file_ending); if (output_centroids && !merge_centroids) { for (unsigned int i=0; i(i) + file_ending); } else if (output_centroids) { mitk::FiberBundle::Pointer centroid = mitk::FiberBundle::New(); centroid = centroid->AddBundles(centroids); mitk::IOUtil::Save(centroid, out_root + ist::GetFilenameWithoutExtension(inFileName) + "_Centroids" + file_ending); } std::cout.rdbuf (old); // <-- restore } 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/FiberDirectionExtraction.cpp b/Modules/DiffusionCmdApps/FiberProcessing/FiberDirectionExtraction.cpp index 4bb955b..bdad859 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/FiberDirectionExtraction.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/FiberDirectionExtraction.cpp @@ -1,183 +1,183 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include /*! \brief Extract principal fiber directions from a tractogram */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Fiber Direction Extraction"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Extract principal fiber directions from a tractogram"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("mask", "", mitkCommandLineParser::String, "Mask:", "mask image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("athresh", "", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); - parser.addArgument("peakthresh", "", mitkCommandLineParser::Float, "Peak size threshold:", "peak size threshold relative to largest peak in voxel", 0.2, true); - parser.addArgument("only_mask_geometry", "", mitkCommandLineParser::Bool, "Only mask geometry:", "don't use content of mask image, only use it's geometry", false); - parser.addArgument("verbose", "", mitkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results"); - parser.addArgument("numdirs", "", mitkCommandLineParser::Int, "Max. num. directions:", "maximum number of fibers per voxel", 3, true); - parser.addArgument("normalization", "", mitkCommandLineParser::Int, "Normalization method:", "1=global maximum; 2=single vector; 3=voxel-wise maximum", 1); - parser.addArgument("file_ending", "", mitkCommandLineParser::String, "Image type:", ".nrrd; .nii; .nii.gz", std::string(".nii.gz")); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input tractogram (.fib/.trk)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("mask", "", mitkDiffusionCommandLineParser::String, "Mask:", "mask image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("athresh", "", mitkDiffusionCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); + parser.addArgument("peakthresh", "", mitkDiffusionCommandLineParser::Float, "Peak size threshold:", "peak size threshold relative to largest peak in voxel", 0.2, true); + parser.addArgument("only_mask_geometry", "", mitkDiffusionCommandLineParser::Bool, "Only mask geometry:", "don't use content of mask image, only use it's geometry", false); + parser.addArgument("verbose", "", mitkDiffusionCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results"); + parser.addArgument("numdirs", "", mitkDiffusionCommandLineParser::Int, "Max. num. directions:", "maximum number of fibers per voxel", 3, true); + parser.addArgument("normalization", "", mitkDiffusionCommandLineParser::Int, "Normalization method:", "1=global maximum; 2=single vector; 3=voxel-wise maximum", 1); + parser.addArgument("file_ending", "", mitkDiffusionCommandLineParser::String, "Image type:", ".nrrd; .nii; .nii.gz", std::string(".nii.gz")); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string fibFile = us::any_cast(parsedArgs["i"]); std::string maskImage(""); if (parsedArgs.count("mask")) maskImage = us::any_cast(parsedArgs["mask"]); float peakThreshold = 0.2; if (parsedArgs.count("peakthresh")) peakThreshold = us::any_cast(parsedArgs["peakthresh"]); float angularThreshold = 25; if (parsedArgs.count("athresh")) angularThreshold = us::any_cast(parsedArgs["athresh"]); std::string outRoot = us::any_cast(parsedArgs["o"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); bool only_mask_geometry = false; if (parsedArgs.count("only_mask_geometry")) only_mask_geometry = us::any_cast(parsedArgs["only_mask_geometry"]); int maxNumDirs = 3; if (parsedArgs.count("numdirs")) maxNumDirs = us::any_cast(parsedArgs["numdirs"]); int normalization = 1; if (parsedArgs.count("normalization")) normalization = us::any_cast(parsedArgs["normalization"]); std::string file_ending = ".nii.gz"; if (parsedArgs.count("file_ending")) file_ending = us::any_cast(parsedArgs["file_ending"]); try { typedef itk::Image ItkUcharImgType; // load fiber bundle mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(fibFile); // load/create mask image ItkUcharImgType::Pointer itkMaskImage = nullptr; if (maskImage.compare("")!=0) { std::cout << "Using mask image"; itkMaskImage = ItkUcharImgType::New(); mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::Load(maskImage); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); } // extract directions from fiber bundle itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetOnlyUseMaskGeometry(only_mask_geometry); fOdfFilter->SetMaskImage(itkMaskImage); fOdfFilter->SetAngularThreshold(cos(angularThreshold*itk::Math::pi/180)); switch (normalization) { case 1: fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter::NormalizationMethods::GLOBAL_MAX); break; case 2: fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter::NormalizationMethods::SINGLE_VEC_NORM); break; case 3: fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter::NormalizationMethods::MAX_VEC_NORM); break; } fOdfFilter->SetSizeThreshold(peakThreshold); fOdfFilter->SetMaxNumDirections(maxNumDirs); fOdfFilter->Update(); mitk::LocaleSwitch localeSwitch("C"); { itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer itkImg = fOdfFilter->GetDirectionImage(); typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter::ItkDirectionImageType > WriterType; WriterType::Pointer writer = WriterType::New(); std::string outfilename = outRoot; outfilename.append("_DIRECTIONS"); outfilename.append(file_ending); writer->SetFileName(outfilename.c_str()); writer->SetInput(itkImg); writer->Update(); } if (verbose) { // write num direction image ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage(); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); std::string outfilename = outRoot; outfilename.append("_NUM_DIRECTIONS"); outfilename.append(file_ending); writer->SetFileName(outfilename.c_str()); writer->SetInput(numDirImage); writer->Update(); } } 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/FiberExtraction.cpp b/Modules/DiffusionCmdApps/FiberProcessing/FiberExtraction.cpp index 9eb0dbe..19d9521 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/FiberExtraction.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/FiberExtraction.cpp @@ -1,151 +1,151 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include /*! \brief Extract fibers from a tractogram using planar figure ROIs */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Fiber Extraction"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setDescription("Extract fibers from a tractogram using planar figure ROIs"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk)", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); - parser.addArgument("planfirgure1", "pf1", mitkCommandLineParser::String, "Figure 1:", "first planar figure ROI", us::Any(), false); - parser.addArgument("planfirgure2", "pf2", mitkCommandLineParser::String, "Figure 2:", "second planar figure ROI", us::Any()); - parser.addArgument("operation", "op", mitkCommandLineParser::String, "Operation:", "logical operation (AND; OR; NOT)", us::Any()); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input tractogram (.fib/.trk)", us::Any(), false); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); + parser.addArgument("planfirgure1", "pf1", mitkDiffusionCommandLineParser::String, "Figure 1:", "first planar figure ROI", us::Any(), false); + parser.addArgument("planfirgure2", "pf2", mitkDiffusionCommandLineParser::String, "Figure 2:", "second planar figure ROI", us::Any()); + parser.addArgument("operation", "op", mitkDiffusionCommandLineParser::String, "Operation:", "logical operation (AND; OR; NOT)", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFib = us::any_cast(parsedArgs["i"]); std::string outFib = us::any_cast(parsedArgs["o"]); std::string pf1_path = us::any_cast(parsedArgs["planfirgure1"]); std::string operation(""); std::string pf2_path(""); if (parsedArgs.count("operation")) { operation = us::any_cast(parsedArgs["operation"]); if (parsedArgs.count("planfirgure2") && (operation=="AND" || operation=="OR")) pf2_path = us::any_cast(parsedArgs["planfirgure2"]); } try { // load fiber bundle mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(inFib); mitk::FiberBundle::Pointer result; mitk::StandaloneDataStorage::Pointer storage = mitk::StandaloneDataStorage::New(); auto data = mitk::IOUtil::Load(pf1_path)[0]; auto input1 = mitk::DataNode::New(); input1->SetData(data); if (input1.IsNotNull()) { mitk::PlanarFigureComposite::Pointer pfc = mitk::PlanarFigureComposite::New(); mitk::DataNode::Pointer pfcNode = mitk::DataNode::New(); pfcNode->SetData(pfc); mitk::DataStorage::SetOfObjects::Pointer set1 = mitk::DataStorage::SetOfObjects::New(); set1->push_back(pfcNode); storage->Add(pfcNode); auto input2 = mitk::DataNode::New(); if (!pf2_path.empty()) { data = mitk::IOUtil::Load(pf2_path)[0]; input2->SetData(data); } if (operation.empty()) { result = inputTractogram->ExtractFiberSubset(input1, nullptr); } else if (operation=="NOT") { pfc->setOperationType(mitk::PlanarFigureComposite::NOT); storage->Add(input1, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else if (operation=="AND" && input2.IsNotNull()) { pfc->setOperationType(mitk::PlanarFigureComposite::AND); storage->Add(input1, set1); storage->Add(input2, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else if (operation=="OR" && input2.IsNotNull()) { pfc->setOperationType(mitk::PlanarFigureComposite::OR); storage->Add(input1, set1); storage->Add(input2, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else { std::cout << "Could not process input:"; std::cout << pf1_path; std::cout << pf2_path; std::cout << operation; } } if (result.IsNotNull()) mitk::IOUtil::Save(result, outFib); else std::cout << "No valid fiber bundle extracted."; } 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/FiberExtractionRoi.cpp b/Modules/DiffusionCmdApps/FiberProcessing/FiberExtractionRoi.cpp index a464985..88baaaf 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/FiberExtractionRoi.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/FiberExtractionRoi.cpp @@ -1,276 +1,276 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; ItkFloatImgType::Pointer LoadItkImage(const std::string& filename) { mitk::Image::Pointer img = mitk::IOUtil::Load(filename); ItkFloatImgType::Pointer itk_image = ItkFloatImgType::New(); mitk::CastToItkImage(img, itk_image); return itk_image; } /*! \brief Extract fibers from a tractogram using binary image ROIs */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Fiber Extraction With ROI Image"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setDescription("Extract fibers from a tractogram using binary image ROIs"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory arguments:"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk/.tck/.dcm)", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output root", us::Any(), false); - parser.addArgument("rois", "", mitkCommandLineParser::StringList, "ROI images:", "ROI images", us::Any(), false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input tractogram (.fib/.trk/.tck/.dcm)", us::Any(), false); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output root", us::Any(), false); + parser.addArgument("rois", "", mitkDiffusionCommandLineParser::StringList, "ROI images:", "ROI images", us::Any(), false); parser.endGroup(); parser.beginGroup("2. Label based extraction:"); - parser.addArgument("split_labels", "", mitkCommandLineParser::Bool, "Split labels:", "output a separate tractogram for each label-->label tract", false); - parser.addArgument("skip_self_connections", "", mitkCommandLineParser::Bool, "Skip self connections:", "ignore streamlines between two identical labels", false); - parser.addArgument("all_labels", "", mitkCommandLineParser::Bool, "All labels:", "use all labels (0 is excluded)", false); - parser.addArgument("labels", "", mitkCommandLineParser::StringList, "Labels:", "positive means roi image value in labels vector", us::Any()); - parser.addArgument("start_labels", "", mitkCommandLineParser::StringList, "Start Labels:", "use separate start and end labels instead of one mixed set", us::Any()); - parser.addArgument("end_labels", "", mitkCommandLineParser::StringList, "End Labels:", "use separate start and end labels instead of one mixed set", us::Any()); - parser.addArgument("paired", "", mitkCommandLineParser::Bool, "Paired:", "start and end label list are paired", false); + parser.addArgument("split_labels", "", mitkDiffusionCommandLineParser::Bool, "Split labels:", "output a separate tractogram for each label-->label tract", false); + parser.addArgument("skip_self_connections", "", mitkDiffusionCommandLineParser::Bool, "Skip self connections:", "ignore streamlines between two identical labels", false); + parser.addArgument("all_labels", "", mitkDiffusionCommandLineParser::Bool, "All labels:", "use all labels (0 is excluded)", false); + parser.addArgument("labels", "", mitkDiffusionCommandLineParser::StringList, "Labels:", "positive means roi image value in labels vector", us::Any()); + parser.addArgument("start_labels", "", mitkDiffusionCommandLineParser::StringList, "Start Labels:", "use separate start and end labels instead of one mixed set", us::Any()); + parser.addArgument("end_labels", "", mitkDiffusionCommandLineParser::StringList, "End Labels:", "use separate start and end labels instead of one mixed set", us::Any()); + parser.addArgument("paired", "", mitkDiffusionCommandLineParser::Bool, "Paired:", "start and end label list are paired", false); parser.endGroup(); parser.beginGroup("3. Misc:"); - parser.addArgument("both_ends", "", mitkCommandLineParser::Bool, "Both ends:", "Fibers are extracted if both endpoints are located in the ROI.", false); - parser.addArgument("overlap_fraction", "", mitkCommandLineParser::Float, "Overlap fraction:", "Extract by overlap, not by endpoints. Extract fibers that overlap to at least the provided factor (0-1) with the ROI.", -1); - parser.addArgument("invert", "", mitkCommandLineParser::Bool, "Invert:", "get streamlines not positive for any of the ROI images", false); - parser.addArgument("output_negatives", "", mitkCommandLineParser::Bool, "Negatives:", "output negatives", false); - parser.addArgument("interpolate", "", mitkCommandLineParser::Bool, "Interpolate:", "interpolate ROI images (only for endpoint based extraction)", false); - parser.addArgument("threshold", "", mitkCommandLineParser::Float, "Threshold:", "positive means ROI image value threshold", 0.5); - parser.addArgument("min_fibers", "", mitkCommandLineParser::Int, "Min. num. fibers:", "discard positive tracts with less fibers", 0); - parser.addArgument("split_rois", "", mitkCommandLineParser::Bool, "Split ROIs:", "output a separate tractogram for each ROI", false); + parser.addArgument("both_ends", "", mitkDiffusionCommandLineParser::Bool, "Both ends:", "Fibers are extracted if both endpoints are located in the ROI.", false); + parser.addArgument("overlap_fraction", "", mitkDiffusionCommandLineParser::Float, "Overlap fraction:", "Extract by overlap, not by endpoints. Extract fibers that overlap to at least the provided factor (0-1) with the ROI.", -1); + parser.addArgument("invert", "", mitkDiffusionCommandLineParser::Bool, "Invert:", "get streamlines not positive for any of the ROI images", false); + parser.addArgument("output_negatives", "", mitkDiffusionCommandLineParser::Bool, "Negatives:", "output negatives", false); + parser.addArgument("interpolate", "", mitkDiffusionCommandLineParser::Bool, "Interpolate:", "interpolate ROI images (only for endpoint based extraction)", false); + parser.addArgument("threshold", "", mitkDiffusionCommandLineParser::Float, "Threshold:", "positive means ROI image value threshold", 0.5); + parser.addArgument("min_fibers", "", mitkDiffusionCommandLineParser::Int, "Min. num. fibers:", "discard positive tracts with less fibers", 0); + parser.addArgument("split_rois", "", mitkDiffusionCommandLineParser::Bool, "Split ROIs:", "output a separate tractogram for each ROI", false); parser.endGroup(); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFib = us::any_cast(parsedArgs["i"]); std::string outFib = us::any_cast(parsedArgs["o"]); - mitkCommandLineParser::StringContainerType roi_files = us::any_cast(parsedArgs["rois"]); + mitkDiffusionCommandLineParser::StringContainerType roi_files = us::any_cast(parsedArgs["rois"]); bool both_ends = false; if (parsedArgs.count("both_ends")) both_ends = us::any_cast(parsedArgs["both_ends"]); bool invert = false; if (parsedArgs.count("invert")) invert = us::any_cast(parsedArgs["invert"]); unsigned int min_fibers = 0; if (parsedArgs.count("min_fibers")) min_fibers = us::any_cast(parsedArgs["min_fibers"]); bool all_labels = false; if (parsedArgs.count("all_labels")) all_labels = us::any_cast(parsedArgs["all_labels"]); bool split_labels = false; if (parsedArgs.count("split_labels")) split_labels = us::any_cast(parsedArgs["split_labels"]); bool split_rois = false; if (parsedArgs.count("split_rois")) split_rois = us::any_cast(parsedArgs["split_rois"]); bool skip_self_connections = false; if (parsedArgs.count("skip_self_connections")) skip_self_connections = us::any_cast(parsedArgs["skip_self_connections"]); bool output_negatives = false; if (parsedArgs.count("output_negatives")) output_negatives = us::any_cast(parsedArgs["output_negatives"]); float overlap_fraction = -1; if (parsedArgs.count("overlap_fraction")) overlap_fraction = us::any_cast(parsedArgs["overlap_fraction"]); bool any_point = false; if (overlap_fraction>=0) any_point = true; bool interpolate = false; if (parsedArgs.count("interpolate")) interpolate = us::any_cast(parsedArgs["interpolate"]); float threshold = 0.5; if (parsedArgs.count("threshold")) threshold = us::any_cast(parsedArgs["threshold"]); - mitkCommandLineParser::StringContainerType labels; + mitkDiffusionCommandLineParser::StringContainerType labels; if (parsedArgs.count("labels")) - labels = us::any_cast(parsedArgs["labels"]); + labels = us::any_cast(parsedArgs["labels"]); - mitkCommandLineParser::StringContainerType start_labels; + mitkDiffusionCommandLineParser::StringContainerType start_labels; if (parsedArgs.count("start_labels")) - start_labels = us::any_cast(parsedArgs["start_labels"]); + start_labels = us::any_cast(parsedArgs["start_labels"]); - mitkCommandLineParser::StringContainerType end_labels; + mitkDiffusionCommandLineParser::StringContainerType end_labels; if (parsedArgs.count("end_labels")) - end_labels = us::any_cast(parsedArgs["end_labels"]); + end_labels = us::any_cast(parsedArgs["end_labels"]); bool paired = false; if (parsedArgs.count("paired")) paired = us::any_cast(parsedArgs["paired"]); try { // load fiber bundle mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(inFib); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect std::vector< ItkFloatImgType::Pointer > roi_images; std::vector< std::string > roi_names; for (std::size_t i=0; i roi_images2; for (auto roi : roi_images) roi_images2.push_back(roi); std::vector< unsigned short > short_labels; for (auto l : labels) short_labels.push_back(boost::lexical_cast(l)); std::vector< unsigned short > short_start_labels; for (auto l : start_labels) short_start_labels.push_back(boost::lexical_cast(l)); std::vector< unsigned short > short_end_labels; for (auto l : end_labels) short_end_labels.push_back(boost::lexical_cast(l)); itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetInputFiberBundle(inputTractogram); extractor->SetRoiImages(roi_images2); extractor->SetRoiImageNames(roi_names); extractor->SetOverlapFraction(overlap_fraction); extractor->SetBothEnds(both_ends); extractor->SetInterpolate(interpolate); extractor->SetThreshold(threshold); extractor->SetLabels(short_labels); extractor->SetStartLabels(short_start_labels); extractor->SetEndLabels(short_end_labels); extractor->SetSplitLabels(split_labels); extractor->SetSplitByRoi(split_rois); extractor->SetMinFibersPerTract(min_fibers); extractor->SetSkipSelfConnections(skip_self_connections); extractor->SetPairedStartEndLabels(paired); if (!any_point) extractor->SetMode(itk::FiberExtractionFilter::MODE::ENDPOINTS); if (all_labels || short_labels.size()>0 || short_start_labels.size()>0 || short_end_labels.size()>0) extractor->SetInputType(itk::FiberExtractionFilter::INPUT::LABEL_MAP); extractor->Update(); std::string ext = itksys::SystemTools::GetFilenameExtension(outFib); if (ext.empty()) ext = ".trk"; outFib = itksys::SystemTools::GetFilenamePath(outFib) + '/' + itksys::SystemTools::GetFilenameWithoutExtension(outFib); if (invert) mitk::IOUtil::Save(extractor->GetNegatives().at(0), outFib + ext); else { int c = 0; std::vector< std::string > positive_labels = extractor->GetPositiveLabels(); for (auto fib : extractor->GetPositives()) { std::string l = positive_labels.at(c); if (l.size()>0) mitk::IOUtil::Save(fib, outFib + "_" + l + ext); else mitk::IOUtil::Save(fib, outFib + ext); ++c; } } if (output_negatives) { invert = !invert; if (invert) mitk::IOUtil::Save(extractor->GetNegatives().at(0), outFib + "_negatives" + ext); else { int c = 0; std::vector< std::string > positive_labels = extractor->GetPositiveLabels(); for (auto fib : extractor->GetPositives()) { std::string l = positive_labels.at(c); if (l.size()>0) mitk::IOUtil::Save(fib, outFib + "_" + l + "_negatives" + ext); else mitk::IOUtil::Save(fib, outFib + "_negatives" + ext); ++c; } } } } 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/FiberJoin.cpp b/Modules/DiffusionCmdApps/FiberProcessing/FiberJoin.cpp index fb9bcdd..eb2b191 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/FiberJoin.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/FiberJoin.cpp @@ -1,100 +1,100 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #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[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Fiber Join"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setDescription("Join multiple tractograms"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::StringList, "Input:", "input tractograms", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::StringList, "Input:", "input tractograms", us::Any(), false); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; - mitkCommandLineParser::StringContainerType inFibs = us::any_cast(parsedArgs["i"]); + mitkDiffusionCommandLineParser::StringContainerType inFibs = us::any_cast(parsedArgs["i"]); std::string outFib = us::any_cast(parsedArgs["o"]); if (inFibs.size()<=1) { std::cout << "More than one input tractogram required!"; return EXIT_FAILURE; } try { std::vector< mitk::FiberBundle::Pointer > tractograms; mitk::FiberBundle::Pointer result = LoadFib(inFibs.at(0)); for (std::size_t i=1; iAddBundles(tractograms); mitk::IOUtil::Save(result, outFib); } 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/FiberProcessing.cpp b/Modules/DiffusionCmdApps/FiberProcessing/FiberProcessing.cpp index 648fe20..b994135 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/FiberProcessing.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/FiberProcessing.cpp @@ -1,301 +1,301 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include mitk::FiberBundle::Pointer LoadFib(std::string filename) { std::vector fibInfile = mitk::IOUtil::Load(filename); if( fibInfile.empty() ) std::cout << "File " << filename << " could not be read!"; mitk::BaseData::Pointer baseData = fibInfile.at(0); return dynamic_cast(baseData.GetPointer()); } /*! \brief Modify input tractogram: fiber resampling, compression, pruning and transformation. */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Fiber Processing"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Modify input tractogram: fiber resampling, compression, pruning and transformation."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory arguments:"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "Input fiber bundle (.fib, .trk, .tck)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "Output fiber bundle (.fib, .trk)", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "Input fiber bundle (.fib, .trk, .tck)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "Output fiber bundle (.fib, .trk)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); parser.endGroup(); parser.beginGroup("2. Resampling:"); - parser.addArgument("spline_resampling", "", mitkCommandLineParser::Float, "Spline resampling:", "Resample fiber using splines with the given point distance (in mm)"); - parser.addArgument("linear_resampling", "", mitkCommandLineParser::Float, "Linear resampling:", "Resample fiber linearly with the given point distance (in mm)"); - parser.addArgument("num_resampling", "", mitkCommandLineParser::Int, "Num. fiber points resampling:", "Resample all fibers to the given number of points"); - parser.addArgument("compress", "", mitkCommandLineParser::Float, "Compress:", "Compress fiber using the given error threshold (in mm)"); + parser.addArgument("spline_resampling", "", mitkDiffusionCommandLineParser::Float, "Spline resampling:", "Resample fiber using splines with the given point distance (in mm)"); + parser.addArgument("linear_resampling", "", mitkDiffusionCommandLineParser::Float, "Linear resampling:", "Resample fiber linearly with the given point distance (in mm)"); + parser.addArgument("num_resampling", "", mitkDiffusionCommandLineParser::Int, "Num. fiber points resampling:", "Resample all fibers to the given number of points"); + parser.addArgument("compress", "", mitkDiffusionCommandLineParser::Float, "Compress:", "Compress fiber using the given error threshold (in mm)"); parser.endGroup(); parser.beginGroup("3. Filtering:"); - parser.addArgument("min_length", "", mitkCommandLineParser::Float, "Minimum length:", "Minimum fiber length (in mm)"); - parser.addArgument("max_length", "", mitkCommandLineParser::Float, "Maximum length:", "Maximum fiber length (in mm)"); - parser.addArgument("max_angle", "", mitkCommandLineParser::Float, "Maximum angle:", "Maximum angular STDEV (in degree) over given distance"); - parser.addArgument("max_angle_dist", "", mitkCommandLineParser::Float, "Distance:", "Distance in mm", 10); - parser.addArgument("remove", "", mitkCommandLineParser::Bool, "Remove fibers exceeding curvature threshold:", "If false, only the high curvature parts are removed"); - parser.addArgument("subsample", "", mitkCommandLineParser::Float, "Randomly select fraction of streamlines:", "Randomly select the specified fraction of streamlines from the input tractogram"); - parser.addArgument("random_subsample", "", mitkCommandLineParser::Bool, "Randomly seed subsampling:", "Randomly seed subsampling. Else, use seed 0."); + parser.addArgument("min_length", "", mitkDiffusionCommandLineParser::Float, "Minimum length:", "Minimum fiber length (in mm)"); + parser.addArgument("max_length", "", mitkDiffusionCommandLineParser::Float, "Maximum length:", "Maximum fiber length (in mm)"); + parser.addArgument("max_angle", "", mitkDiffusionCommandLineParser::Float, "Maximum angle:", "Maximum angular STDEV (in degree) over given distance"); + parser.addArgument("max_angle_dist", "", mitkDiffusionCommandLineParser::Float, "Distance:", "Distance in mm", 10); + parser.addArgument("remove", "", mitkDiffusionCommandLineParser::Bool, "Remove fibers exceeding curvature threshold:", "If false, only the high curvature parts are removed"); + parser.addArgument("subsample", "", mitkDiffusionCommandLineParser::Float, "Randomly select fraction of streamlines:", "Randomly select the specified fraction of streamlines from the input tractogram"); + parser.addArgument("random_subsample", "", mitkDiffusionCommandLineParser::Bool, "Randomly seed subsampling:", "Randomly seed subsampling. Else, use seed 0."); parser.endGroup(); parser.beginGroup("4. Transformation:"); - parser.addArgument("mirror", "", mitkCommandLineParser::Int, "Invert coordinates:", "Invert fiber coordinates XYZ (e.g. 010 to invert y-coordinate of each fiber point)"); + parser.addArgument("mirror", "", mitkDiffusionCommandLineParser::Int, "Invert coordinates:", "Invert fiber coordinates XYZ (e.g. 010 to invert y-coordinate of each fiber point)"); - parser.addArgument("rotate_x", "", mitkCommandLineParser::Float, "Rotate x-axis:", "Rotate around x-axis (in deg)"); - parser.addArgument("rotate_y", "", mitkCommandLineParser::Float, "Rotate y-axis:", "Rotate around y-axis (in deg)"); - parser.addArgument("rotate_z", "", mitkCommandLineParser::Float, "Rotate z-axis:", "Rotate around z-axis (in deg)"); + parser.addArgument("rotate_x", "", mitkDiffusionCommandLineParser::Float, "Rotate x-axis:", "Rotate around x-axis (in deg)"); + parser.addArgument("rotate_y", "", mitkDiffusionCommandLineParser::Float, "Rotate y-axis:", "Rotate around y-axis (in deg)"); + parser.addArgument("rotate_z", "", mitkDiffusionCommandLineParser::Float, "Rotate z-axis:", "Rotate around z-axis (in deg)"); - parser.addArgument("scale_x", "", mitkCommandLineParser::Float, "Scale x-axis:", "Scale in direction of x-axis"); - parser.addArgument("scale_y", "", mitkCommandLineParser::Float, "Scale y-axis:", "Scale in direction of y-axis"); - parser.addArgument("scale_z", "", mitkCommandLineParser::Float, "Scale z-axis", "Scale in direction of z-axis"); + parser.addArgument("scale_x", "", mitkDiffusionCommandLineParser::Float, "Scale x-axis:", "Scale in direction of x-axis"); + parser.addArgument("scale_y", "", mitkDiffusionCommandLineParser::Float, "Scale y-axis:", "Scale in direction of y-axis"); + parser.addArgument("scale_z", "", mitkDiffusionCommandLineParser::Float, "Scale z-axis", "Scale in direction of z-axis"); - parser.addArgument("translate_x", "", mitkCommandLineParser::Float, "Translate x-axis:", "Translate in direction of x-axis (in mm)"); - parser.addArgument("translate_y", "", mitkCommandLineParser::Float, "Translate y-axis:", "Translate in direction of y-axis (in mm)"); - parser.addArgument("translate_z", "", mitkCommandLineParser::Float, "Translate z-axis:", "Translate in direction of z-axis (in mm)"); + parser.addArgument("translate_x", "", mitkDiffusionCommandLineParser::Float, "Translate x-axis:", "Translate in direction of x-axis (in mm)"); + parser.addArgument("translate_y", "", mitkDiffusionCommandLineParser::Float, "Translate y-axis:", "Translate in direction of y-axis (in mm)"); + parser.addArgument("translate_z", "", mitkDiffusionCommandLineParser::Float, "Translate z-axis:", "Translate in direction of z-axis (in mm)"); parser.endGroup(); parser.beginGroup("5. Remove fiber parts:"); - parser.addArgument("remove_inside", "", mitkCommandLineParser::Bool, "Remove fibers inside mask:", "remove fibers inside mask"); - parser.addArgument("remove_outside", "", mitkCommandLineParser::Bool, "Remove fibers outside mask:", "remove fibers outside mask"); - parser.addArgument("mask", "", mitkCommandLineParser::String, "Mask image:", "mask image", us::Any(), true, false, false, mitkCommandLineParser::Input); + parser.addArgument("remove_inside", "", mitkDiffusionCommandLineParser::Bool, "Remove fibers inside mask:", "remove fibers inside mask"); + parser.addArgument("remove_outside", "", mitkDiffusionCommandLineParser::Bool, "Remove fibers outside mask:", "remove fibers outside mask"); + parser.addArgument("mask", "", mitkDiffusionCommandLineParser::String, "Mask image:", "mask image", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); parser.endGroup(); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; bool remove_outside = false; if (parsedArgs.count("remove_outside")) remove_outside = us::any_cast(parsedArgs["remove_outside"]); bool remove_inside = false; if (!remove_outside && parsedArgs.count("remove_inside")) remove_inside = us::any_cast(parsedArgs["remove_inside"]); typedef itk::Image< unsigned char, 3 > UcharImageType; UcharImageType::Pointer mask = nullptr; if (remove_inside || remove_outside) { if (parsedArgs.count("mask")) mask = mitk::DiffusionDataIOHelper::load_itk_image< UcharImageType >(us::any_cast(parsedArgs["mask"])); else { MITK_INFO << "Mask needed to remove fibers inside or outside mask!"; return EXIT_FAILURE; } } bool remove = false; if (parsedArgs.count("remove")) remove = us::any_cast(parsedArgs["remove"]); bool random_subsample = false; if (parsedArgs.count("random_subsample")) random_subsample = us::any_cast(parsedArgs["random_subsample"]); float spline_resampling = -1; if (parsedArgs.count("spline_resampling")) spline_resampling = us::any_cast(parsedArgs["spline_resampling"]); float linear_resampling = -1; if (parsedArgs.count("linear_resampling")) linear_resampling = us::any_cast(parsedArgs["linear_resampling"]); int num_resampling = -1; if (parsedArgs.count("num_resampling")) num_resampling = us::any_cast(parsedArgs["num_resampling"]); float subsample = -1; if (parsedArgs.count("subsample")) subsample = us::any_cast(parsedArgs["subsample"]); float compress = -1; if (parsedArgs.count("compress")) compress = us::any_cast(parsedArgs["compress"]); float minFiberLength = -1; if (parsedArgs.count("min_length")) minFiberLength = us::any_cast(parsedArgs["min_length"]); float maxFiberLength = -1; if (parsedArgs.count("max_length")) maxFiberLength = us::any_cast(parsedArgs["max_length"]); float max_angle_dist = 10; if (parsedArgs.count("max_angle_dist")) max_angle_dist = us::any_cast(parsedArgs["max_angle_dist"]); float maxAngularDev = -1; if (parsedArgs.count("max_angle")) maxAngularDev = us::any_cast(parsedArgs["max_angle"]); int axis = 0; if (parsedArgs.count("mirror")) axis = us::any_cast(parsedArgs["mirror"]); float rotateX = 0; if (parsedArgs.count("rotate_x")) rotateX = us::any_cast(parsedArgs["rotate_x"]); float rotateY = 0; if (parsedArgs.count("rotate_y")) rotateY = us::any_cast(parsedArgs["rotate_y"]); float rotateZ = 0; if (parsedArgs.count("rotate_z")) rotateZ = us::any_cast(parsedArgs["rotate_z"]); float scaleX = 0; if (parsedArgs.count("scale_x")) scaleX = us::any_cast(parsedArgs["scale_x"]); float scaleY = 0; if (parsedArgs.count("scale_y")) scaleY = us::any_cast(parsedArgs["scale_y"]); float scaleZ = 0; if (parsedArgs.count("scale_z")) scaleZ = us::any_cast(parsedArgs["scale_z"]); float translateX = 0; if (parsedArgs.count("translate_x")) translateX = us::any_cast(parsedArgs["translate_x"]); float translateY = 0; if (parsedArgs.count("translate_y")) translateY = us::any_cast(parsedArgs["translate_y"]); float translateZ = 0; if (parsedArgs.count("translate_z")) translateZ = us::any_cast(parsedArgs["translate_z"]); std::string inFileName = us::any_cast(parsedArgs["i"]); std::string outFileName = us::any_cast(parsedArgs["o"]); try { mitk::FiberBundle::Pointer fib = LoadFib(inFileName); if (subsample>0) fib = fib->SubsampleFibers(subsample, random_subsample); if (maxAngularDev>0) { auto filter = itk::FiberCurvatureFilter::New(); filter->SetInputFiberBundle(fib); filter->SetAngularDeviation(maxAngularDev); filter->SetDistance(max_angle_dist); filter->SetRemoveFibers(remove); filter->Update(); fib = filter->GetOutputFiberBundle(); } if (minFiberLength>0) fib->RemoveShortFibers(minFiberLength); if (maxFiberLength>0) fib->RemoveLongFibers(maxFiberLength); if (spline_resampling>0) fib->ResampleSpline(spline_resampling); if (linear_resampling>0) fib->ResampleLinear(linear_resampling); if (num_resampling>0) fib->ResampleToNumPoints(num_resampling); if (compress>0) fib->Compress(compress); if ( mask.IsNotNull() ) { if (remove_outside) fib = fib->RemoveFibersOutside(mask, false); else if (remove_inside) fib = fib->RemoveFibersOutside(mask, true); } if (axis/100==1) fib->MirrorFibers(0); if ((axis%100)/10==1) fib->MirrorFibers(1); if (axis%10==1) fib->MirrorFibers(2); if (rotateX > 0 || rotateY > 0 || rotateZ > 0){ std::cout << "Rotate " << rotateX << " " << rotateY << " " << rotateZ; fib->RotateAroundAxis(rotateX, rotateY, rotateZ); } if (translateX > 0 || translateY > 0 || translateZ > 0){ fib->TranslateFibers(translateX, translateY, translateZ); } if (scaleX > 0 || scaleY > 0 || scaleZ > 0) fib->ScaleFibers(scaleX, scaleY, scaleZ); mitk::IOUtil::Save(fib.GetPointer(), 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/FitFibersToImage.cpp b/Modules/DiffusionCmdApps/FiberProcessing/FitFibersToImage.cpp index bd9b319..5fc0390 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/FitFibersToImage.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/FitFibersToImage.cpp @@ -1,321 +1,321 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include typedef itk::Point PointType4; typedef itk::Image< float, 4 > PeakImgType; /*! \brief Fits the tractogram to the input peak image by assigning a weight to each fiber (similar to https://doi.org/10.1016/j.neuroimage.2015.06.092). */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Fit Fibers To Image"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Assigns a weight to each fiber in order to optimally explain the input peak image"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i1", mitkCommandLineParser::StringList, "Input tractograms:", "input tractograms (files or folder)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "i2", mitkCommandLineParser::String, "Input image:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkCommandLineParser::Output); - - parser.addArgument("max_iter", "", mitkCommandLineParser::Int, "Max. iterations:", "maximum number of optimizer iterations", 20); - parser.addArgument("bundle_based", "", mitkCommandLineParser::Bool, "Bundle based fit:", "fit one weight per input tractogram/bundle, not for each fiber", false); - parser.addArgument("min_g", "", mitkCommandLineParser::Float, "Min. g:", "lower termination threshold for gradient magnitude", 1e-5); - parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda:", "modifier for regularization", 1.0); - parser.addArgument("save_res", "", mitkCommandLineParser::Bool, "Save Residuals:", "save residual images", false); - parser.addArgument("save_weights", "", mitkCommandLineParser::Bool, "Save Weights:", "save fiber weights in a separate text file", false); - parser.addArgument("filter_zero", "", mitkCommandLineParser::Bool, "Filter Zero Weights:", "filter fibers with zero weight", false); - parser.addArgument("filter_outliers", "", mitkCommandLineParser::Bool, "Filter outliers:", "perform second optimization run with an upper weight bound based on the first weight estimation (99% quantile)", false); - parser.addArgument("join_tracts", "", mitkCommandLineParser::Bool, "Join output tracts:", "outout tracts are merged into a single tractogram", false); - parser.addArgument("regu", "", mitkCommandLineParser::String, "Regularization:", "MSM; Variance; VoxelVariance; Lasso; GroupLasso; GroupVariance; NONE", std::string("VoxelVariance")); + parser.addArgument("", "i1", mitkDiffusionCommandLineParser::StringList, "Input tractograms:", "input tractograms (files or folder)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "i2", mitkDiffusionCommandLineParser::String, "Input image:", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + + parser.addArgument("max_iter", "", mitkDiffusionCommandLineParser::Int, "Max. iterations:", "maximum number of optimizer iterations", 20); + parser.addArgument("bundle_based", "", mitkDiffusionCommandLineParser::Bool, "Bundle based fit:", "fit one weight per input tractogram/bundle, not for each fiber", false); + parser.addArgument("min_g", "", mitkDiffusionCommandLineParser::Float, "Min. g:", "lower termination threshold for gradient magnitude", 1e-5); + parser.addArgument("lambda", "", mitkDiffusionCommandLineParser::Float, "Lambda:", "modifier for regularization", 1.0); + parser.addArgument("save_res", "", mitkDiffusionCommandLineParser::Bool, "Save Residuals:", "save residual images", false); + parser.addArgument("save_weights", "", mitkDiffusionCommandLineParser::Bool, "Save Weights:", "save fiber weights in a separate text file", false); + parser.addArgument("filter_zero", "", mitkDiffusionCommandLineParser::Bool, "Filter Zero Weights:", "filter fibers with zero weight", false); + parser.addArgument("filter_outliers", "", mitkDiffusionCommandLineParser::Bool, "Filter outliers:", "perform second optimization run with an upper weight bound based on the first weight estimation (99% quantile)", false); + parser.addArgument("join_tracts", "", mitkDiffusionCommandLineParser::Bool, "Join output tracts:", "outout tracts are merged into a single tractogram", false); + parser.addArgument("regu", "", mitkDiffusionCommandLineParser::String, "Regularization:", "MSM; Variance; VoxelVariance; Lasso; GroupLasso; GroupVariance; NONE", std::string("VoxelVariance")); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; - mitkCommandLineParser::StringContainerType fib_files = us::any_cast(parsedArgs["i1"]); + mitkDiffusionCommandLineParser::StringContainerType fib_files = us::any_cast(parsedArgs["i1"]); std::string input_image_name = us::any_cast(parsedArgs["i2"]); std::string outRoot = us::any_cast(parsedArgs["o"]); bool single_fib = true; if (parsedArgs.count("bundle_based")) single_fib = !us::any_cast(parsedArgs["bundle_based"]); bool save_residuals = false; if (parsedArgs.count("save_res")) save_residuals = us::any_cast(parsedArgs["save_res"]); bool filter_zero = false; if (parsedArgs.count("filter_zero")) filter_zero = us::any_cast(parsedArgs["filter_zero"]); bool save_weights = false; if (parsedArgs.count("save_weights")) save_weights = us::any_cast(parsedArgs["save_weights"]); std::string regu = "VoxelVariance"; if (parsedArgs.count("regu")) regu = us::any_cast(parsedArgs["regu"]); bool join_tracts = false; if (parsedArgs.count("join_tracts")) join_tracts = us::any_cast(parsedArgs["join_tracts"]); int max_iter = 20; if (parsedArgs.count("max_iter")) max_iter = us::any_cast(parsedArgs["max_iter"]); float g_tol = 1e-5; if (parsedArgs.count("min_g")) g_tol = us::any_cast(parsedArgs["min_g"]); float lambda = 1.0; if (parsedArgs.count("lambda")) lambda = us::any_cast(parsedArgs["lambda"]); bool filter_outliers = false; if (parsedArgs.count("filter_outliers")) filter_outliers = us::any_cast(parsedArgs["filter_outliers"]); try { MITK_INFO << "Loading data"; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image", "Fiberbundles"}, {}); std::vector< std::string > fib_names; auto input_tracts = mitk::DiffusionDataIOHelper::load_fibs(fib_files, &fib_names); itk::FitFibersToImageFilter::Pointer fitter = itk::FitFibersToImageFilter::New(); mitk::BaseData::Pointer inputData = mitk::IOUtil::Load(input_image_name, &functor)[0].GetPointer(); mitk::Image::Pointer mitk_image = dynamic_cast(inputData.GetPointer()); mitk::PeakImage::Pointer mitk_peak_image = dynamic_cast(inputData.GetPointer()); if (mitk_peak_image.IsNotNull()) { typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(mitk_peak_image); caster->Update(); mitk::PeakImage::ItkPeakImageType::Pointer peak_image = caster->GetOutput(); fitter->SetPeakImage(peak_image); } else if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(mitk_image)) { fitter->SetDiffImage(mitk::DiffusionPropertyHelper::GetItkVectorImage(mitk_image)); mitk::TensorModel<>* model = new mitk::TensorModel<>(); model->SetBvalue(1000); model->SetDiffusivity1(0.0010); model->SetDiffusivity2(0.00015); model->SetDiffusivity3(0.00015); model->SetGradientList(mitk::DiffusionPropertyHelper::GetGradientContainer(mitk_image)); fitter->SetSignalModel(model); } else if (mitk_image->GetDimension()==3) { itk::FitFibersToImageFilter::DoubleImgType::Pointer scalar_image = itk::FitFibersToImageFilter::DoubleImgType::New(); mitk::CastToItkImage(mitk_image, scalar_image); fitter->SetScalarImage(scalar_image); } else { MITK_INFO << "Input image invalid. Valid options are peak image, 3D scalar image or raw diffusion-weighted image."; return EXIT_FAILURE; } fitter->SetTractograms(input_tracts); fitter->SetFitIndividualFibers(single_fib); fitter->SetMaxIterations(max_iter); fitter->SetGradientTolerance(g_tol); fitter->SetLambda(lambda); fitter->SetFilterOutliers(filter_outliers); if (regu=="MSM") fitter->SetRegularization(VnlCostFunction::REGU::MSM); else if (regu=="Variance") fitter->SetRegularization(VnlCostFunction::REGU::VARIANCE); else if (regu=="Lasso") fitter->SetRegularization(VnlCostFunction::REGU::LASSO); else if (regu=="VoxelVariance") fitter->SetRegularization(VnlCostFunction::REGU::VOXEL_VARIANCE); else if (regu=="GroupLasso") fitter->SetRegularization(VnlCostFunction::REGU::GROUP_LASSO); else if (regu=="GroupVariance") fitter->SetRegularization(VnlCostFunction::REGU::GROUP_VARIANCE); else if (regu=="NONE") fitter->SetRegularization(VnlCostFunction::REGU::NONE); fitter->Update(); mitk::LocaleSwitch localeSwitch("C"); if (save_residuals && mitk_peak_image.IsNotNull()) { itk::ImageFileWriter< PeakImgType >::Pointer writer = itk::ImageFileWriter< PeakImgType >::New(); writer->SetInput(fitter->GetFittedImage()); writer->SetFileName(outRoot + "_fitted.nii.gz"); writer->Update(); writer->SetInput(fitter->GetResidualImage()); writer->SetFileName(outRoot + "_residual.nii.gz"); writer->Update(); writer->SetInput(fitter->GetOverexplainedImage()); writer->SetFileName(outRoot + "_overexplained.nii.gz"); writer->Update(); writer->SetInput(fitter->GetUnderexplainedImage()); writer->SetFileName(outRoot + "_underexplained.nii.gz"); writer->Update(); } else if (save_residuals && mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(mitk_image)) { { mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetFittedImageDiff().GetPointer() ); mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true); mitk::DiffusionPropertyHelper::InitializeImage( outImage ); mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_fitted_image.nii.gz"); } { mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetResidualImageDiff().GetPointer() ); mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true); mitk::DiffusionPropertyHelper::InitializeImage( outImage ); mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_residual_image.nii.gz"); } { mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetOverexplainedImageDiff().GetPointer() ); mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true); mitk::DiffusionPropertyHelper::InitializeImage( outImage ); mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_overexplained_image.nii.gz"); } { mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetUnderexplainedImageDiff().GetPointer() ); mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true); mitk::DiffusionPropertyHelper::InitializeImage( outImage ); mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_underexplained_image.nii.gz"); } } else if (save_residuals) { itk::ImageFileWriter< itk::FitFibersToImageFilter::DoubleImgType >::Pointer writer = itk::ImageFileWriter< itk::FitFibersToImageFilter::DoubleImgType >::New(); writer->SetInput(fitter->GetFittedImageScalar()); writer->SetFileName(outRoot + "_fitted_image.nii.gz"); writer->Update(); writer->SetInput(fitter->GetResidualImageScalar()); writer->SetFileName(outRoot + "_residual_image.nii.gz"); writer->Update(); writer->SetInput(fitter->GetOverexplainedImageScalar()); writer->SetFileName(outRoot + "_overexplained_image.nii.gz"); writer->Update(); writer->SetInput(fitter->GetUnderexplainedImageScalar()); writer->SetFileName(outRoot + "_underexplained_image.nii.gz"); writer->Update(); } std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms(); if (!join_tracts) { for (unsigned int bundle=0; bundleFilterByWeights(0.0); if (fib->GetNumFibers()>0) { fib->ColorFibersByFiberWeights(false, true); mitk::IOUtil::Save(fib, outRoot + name + "_fitted.fib"); if (save_weights) { ofstream logfile; logfile.open (outRoot + name + "_weights.txt"); for (unsigned int f=0; fGetNumFibers(); ++f) logfile << output_tracts.at(bundle)->GetFiberWeight(f) << "\n"; logfile.close(); } } else MITK_INFO << "Output contains no fibers!"; } } else { mitk::FiberBundle::Pointer out = mitk::FiberBundle::New(); out = out->AddBundles(output_tracts); if (filter_zero) out = out->FilterByWeights(0.0); if (out->GetNumFibers()>0) { out->ColorFibersByFiberWeights(false, true); mitk::IOUtil::Save(out, outRoot + "_fitted.fib"); if (save_weights) { ofstream logfile; logfile.open (outRoot + "_weights.txt"); for (unsigned int f=0; fGetNumFibers(); ++f) logfile << out->GetFiberWeight(f) << "\n"; logfile.close(); } } else MITK_INFO << "Output contains no fibers!"; } } 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/Sift2WeightCopy.cpp b/Modules/DiffusionCmdApps/FiberProcessing/Sift2WeightCopy.cpp index e0cd363..47b1ab0 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/Sift2WeightCopy.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/Sift2WeightCopy.cpp @@ -1,107 +1,107 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "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 Import Sift2 Fiber Weights txt file. */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("SIFT2 Fiber Weight Import"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Import SIFT2 fiber weights."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input fiber bundle", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output fiber bundle (.fib)", us::Any(), false); - parser.addArgument("weights", "", mitkCommandLineParser::String, "Weights:", "input weights file (.txt)", us::Any(), false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input fiber bundle", us::Any(), false); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output fiber bundle (.fib)", us::Any(), false); + parser.addArgument("weights", "", mitkDiffusionCommandLineParser::String, "Weights:", "input weights file (.txt)", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["i"]); std::string weightsFileName = us::any_cast(parsedArgs["weights"]); std::string outFileName = us::any_cast(parsedArgs["o"]); try { mitk::FiberBundle::Pointer fib = LoadFib(inFileName); std::ifstream fin; fin.open(weightsFileName); if (!fin.good()) return 1; // exit if file not found std::vector weights; for (float d; fin >> d; ) { weights.push_back(d); } for(std::size_t i = 0; i != weights.size(); i++) { fib->SetFiberWeight(i, weights[i]); } mitk::IOUtil::Save(fib.GetPointer(), 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/TractDensity.cpp b/Modules/DiffusionCmdApps/FiberProcessing/TractDensity.cpp index 0fdc816..6226519 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/TractDensity.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/TractDensity.cpp @@ -1,213 +1,213 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "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[]) { - mitkCommandLineParser parser; + 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.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input fiber bundle", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false); - parser.addArgument("binary", "", mitkCommandLineParser::Bool, "Binary output:", "calculate binary tract envelope", us::Any()); - parser.addArgument("normalize", "", mitkCommandLineParser::Bool, "Normalized output:", "normalize output to 0-1", us::Any()); - parser.addArgument("endpoints", "", mitkCommandLineParser::Bool, "Output endpoints image:", "calculate image of fiber endpoints instead of mask", us::Any()); - parser.addArgument("reference_image", "", mitkCommandLineParser::String, "Reference image:", "output image will have geometry of this reference image", us::Any()); - parser.addArgument("upsampling", "", mitkCommandLineParser::Float, "Upsampling:", "upsampling", 1.0); + 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->SetBinaryOutput(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->SetBinaryOutput(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 ); } } 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/TractDensityFilter.cpp b/Modules/DiffusionCmdApps/FiberProcessing/TractDensityFilter.cpp index 125cf41..b89ce41 100644 --- a/Modules/DiffusionCmdApps/FiberProcessing/TractDensityFilter.cpp +++ b/Modules/DiffusionCmdApps/FiberProcessing/TractDensityFilter.cpp @@ -1,110 +1,110 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; /*! \brief Extract fibers from a tractogram using binary image ROIs */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Filter Outliers by Tract Density"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk/.tck/.dcm)", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input tractogram (.fib/.trk/.tck/.dcm)", us::Any(), false); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); - parser.addArgument("threshold", "", mitkCommandLineParser::Float, "Threshold:", "positive means ROI image value threshold", 0.05); - parser.addArgument("overlap", "", mitkCommandLineParser::Float, "Overlap:", "positive means ROI image value threshold", 0.5); - parser.addArgument("min_fibers", "", mitkCommandLineParser::Int, "Min. num. fibers:", "discard positive tracts with less fibers", 0); + parser.addArgument("threshold", "", mitkDiffusionCommandLineParser::Float, "Threshold:", "positive means ROI image value threshold", 0.05); + parser.addArgument("overlap", "", mitkDiffusionCommandLineParser::Float, "Overlap:", "positive means ROI image value threshold", 0.5); + parser.addArgument("min_fibers", "", mitkDiffusionCommandLineParser::Int, "Min. num. fibers:", "discard positive tracts with less fibers", 0); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFib = us::any_cast(parsedArgs["i"]); std::string outFib = us::any_cast(parsedArgs["o"]); int min_fibers = 0; if (parsedArgs.count("min_fibers")) min_fibers = us::any_cast(parsedArgs["min_fibers"]); float overlap = 0.5; if (parsedArgs.count("overlap")) overlap = us::any_cast(parsedArgs["overlap"]); float threshold = 0.05f; if (parsedArgs.count("threshold")) threshold = us::any_cast(parsedArgs["threshold"]); try { mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(inFib); itk::TractDensityImageFilter< ItkFloatImgType >::Pointer generator = itk::TractDensityImageFilter< ItkFloatImgType >::New(); generator->SetFiberBundle(inputTractogram); generator->SetBinaryOutput(false); generator->SetOutputAbsoluteValues(false); generator->Update(); itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetRoiImages({generator->GetOutput()}); extractor->SetInputFiberBundle(inputTractogram); extractor->SetOverlapFraction(overlap); extractor->SetInterpolate(true); extractor->SetThreshold(threshold); extractor->SetNoNegatives(true); extractor->Update(); if (extractor->GetPositives().at(0)->GetNumFibers() >= static_cast(min_fibers)) mitk::IOUtil::Save(extractor->GetPositives().at(0), outFib); } 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/Fiberfox/Fiberfox.cpp b/Modules/DiffusionCmdApps/Fiberfox/Fiberfox.cpp index 534aef2..78a7794 100644 --- a/Modules/DiffusionCmdApps/Fiberfox/Fiberfox.cpp +++ b/Modules/DiffusionCmdApps/Fiberfox/Fiberfox.cpp @@ -1,288 +1,289 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include +#include using namespace mitk; /*! * \brief Command line interface to Fiberfox. * Simulate a diffusion-weighted image from a tractogram using the specified parameter file. */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Fiberfox"); parser.setCategory("Diffusion Simulation Tools"); parser.setContributor("MIC"); parser.setDescription("Command line interface to Fiberfox." " Simulate a diffusion-weighted image from a tractogram using the specified parameter file."); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output root:", "output folder and file prefix", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input tractogram or diffusion-weighted image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("parameters", "p", mitkCommandLineParser::String, "Parameter file:", "fiberfox parameter file (.ffp)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("template", "t", mitkCommandLineParser::String, "Template image:", "use parameters of the template image", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Output additional images:", "output volume fraction images etc.", us::Any()); - parser.addArgument("dont_apply_direction_matrix", "", mitkCommandLineParser::Bool, "Don't apply direction matrix:", "don't rotate gradients by image direction matrix", us::Any()); - parser.addArgument("fix_seed", "", mitkCommandLineParser::Bool, "Use fix random seed:", "always use same sequence of random numbers", us::Any()); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output root:", "output folder and file prefix", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input tractogram or diffusion-weighted image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("parameters", "p", mitkDiffusionCommandLineParser::String, "Parameter file:", "fiberfox parameter file (.ffp)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("template", "t", mitkDiffusionCommandLineParser::String, "Template image:", "use parameters of the template image", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("verbose", "v", mitkDiffusionCommandLineParser::Bool, "Output additional images:", "output volume fraction images etc.", us::Any()); + parser.addArgument("dont_apply_direction_matrix", "", mitkDiffusionCommandLineParser::Bool, "Don't apply direction matrix:", "don't rotate gradients by image direction matrix", us::Any()); + parser.addArgument("fix_seed", "", mitkDiffusionCommandLineParser::Bool, "Use fix random seed:", "always use same sequence of random numbers", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } std::string outName = us::any_cast(parsedArgs["o"]); std::string paramName = us::any_cast(parsedArgs["parameters"]); std::string input=""; if (parsedArgs.count("i")) input = us::any_cast(parsedArgs["i"]); bool fix_seed = false; if (parsedArgs.count("fix_seed")) fix_seed = us::any_cast(parsedArgs["fix_seed"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); bool apply_direction_matrix = true; if (parsedArgs.count("dont_apply_direction_matrix")) apply_direction_matrix = false; FiberfoxParameters parameters; parameters.LoadParameters(paramName, fix_seed); // Test if /path/dir is an existing directory: std::string file_extension = ""; if( itksys::SystemTools::FileIsDirectory( outName ) ) { while( *(--(outName.cend())) == '/') { outName.pop_back(); } outName = outName + '/'; parameters.m_Misc.m_OutputPath = outName; outName = outName + parameters.m_Misc.m_OutputPrefix; // using default m_OutputPrefix as initialized. } else { // outName is NOT an existing directory, so we need to remove all trailing slashes: while( *(--(outName.cend())) == '/') { outName.pop_back(); } // now split up the given outName into directory and (prefix of) filename: if( ! itksys::SystemTools::GetFilenamePath( outName ).empty() && itksys::SystemTools::FileIsDirectory(itksys::SystemTools::GetFilenamePath( outName ) ) ) { parameters.m_Misc.m_OutputPath = itksys::SystemTools::GetFilenamePath( outName ) + '/'; } else { parameters.m_Misc.m_OutputPath = itksys::SystemTools::GetCurrentWorkingDirectory() + '/'; } file_extension = itksys::SystemTools::GetFilenameExtension(outName); if( ! itksys::SystemTools::GetFilenameWithoutExtension( outName ).empty() ) { parameters.m_Misc.m_OutputPrefix = itksys::SystemTools::GetFilenameWithoutExtension( outName ); } else { parameters.m_Misc.m_OutputPrefix = "fiberfox"; } outName = parameters.m_Misc.m_OutputPath + parameters.m_Misc.m_OutputPrefix; } mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images", "Fiberbundles"}, {}); mitk::BaseData::Pointer inputData = mitk::IOUtil::Load(input, &functor)[0]; itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New(); if ( dynamic_cast(inputData.GetPointer()) ) // simulate dataset from fibers { tractsToDwiFilter->SetFiberBundle(dynamic_cast(inputData.GetPointer())); if (parsedArgs.count("template")) { MITK_INFO << "Loading template image"; typedef itk::VectorImage< short, 3 > ItkDwiType; typedef itk::Image< short, 3 > ItkImageType; mitk::BaseData::Pointer templateData = mitk::IOUtil::Load(us::any_cast(parsedArgs["template"]), &functor)[0]; mitk::Image::Pointer template_image = dynamic_cast(templateData.GetPointer()); if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(template_image)) { ItkDwiType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(template_image); parameters.m_SignalGen.m_ImageRegion = itkVectorImagePointer->GetLargestPossibleRegion(); parameters.m_SignalGen.m_ImageSpacing = itkVectorImagePointer->GetSpacing(); parameters.m_SignalGen.m_ImageOrigin = itkVectorImagePointer->GetOrigin(); parameters.m_SignalGen.m_ImageDirection = itkVectorImagePointer->GetDirection(); parameters.SetBvalue(mitk::DiffusionPropertyHelper::GetReferenceBValue(template_image)); parameters.SetGradienDirections(mitk::DiffusionPropertyHelper::GetOriginalGradientContainer(template_image)); } else { ItkImageType::Pointer itkImagePointer = ItkImageType::New(); mitk::CastToItkImage(template_image, itkImagePointer); parameters.m_SignalGen.m_ImageRegion = itkImagePointer->GetLargestPossibleRegion(); parameters.m_SignalGen.m_ImageSpacing = itkImagePointer->GetSpacing(); parameters.m_SignalGen.m_ImageOrigin = itkImagePointer->GetOrigin(); parameters.m_SignalGen.m_ImageDirection = itkImagePointer->GetDirection(); } } } else if ( dynamic_cast(inputData.GetPointer()) ) // add artifacts to existing image { typedef itk::VectorImage< short, 3 > ItkDwiType; mitk::Image::Pointer diffImg = dynamic_cast(inputData.GetPointer()); ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); mitk::CastToItkImage(diffImg, itkVectorImagePointer); parameters.m_SignalGen.m_SignalScale = 1; parameters.m_SignalGen.m_ImageRegion = itkVectorImagePointer->GetLargestPossibleRegion(); parameters.m_SignalGen.m_ImageSpacing = itkVectorImagePointer->GetSpacing(); parameters.m_SignalGen.m_ImageOrigin = itkVectorImagePointer->GetOrigin(); parameters.m_SignalGen.m_ImageDirection = itkVectorImagePointer->GetDirection(); parameters.SetBvalue(mitk::DiffusionPropertyHelper::GetReferenceBValue(diffImg)); parameters.SetGradienDirections(mitk::DiffusionPropertyHelper::GetOriginalGradientContainer(diffImg)); tractsToDwiFilter->SetInputImage(itkVectorImagePointer); } if (verbose) { MITK_DEBUG << outName << ".ffp"; parameters.m_Misc.m_OutputAdditionalImages = true; parameters.SaveParameters(outName+".ffp"); } else parameters.m_Misc.m_OutputAdditionalImages = false; if (apply_direction_matrix) { MITK_INFO << "Applying direction matrix to gradient directions."; parameters.ApplyDirectionMatrix(); } tractsToDwiFilter->SetParameters(parameters); tractsToDwiFilter->SetUseConstantRandSeed(fix_seed); tractsToDwiFilter->Update(); mitk::Image::Pointer image = mitk::GrabItkImageMemory(tractsToDwiFilter->GetOutput()); if (parameters.m_SignalGen.GetNumWeightedVolumes()>0) { if (apply_direction_matrix) mitk::DiffusionPropertyHelper::SetGradientContainer(image, parameters.m_SignalGen.GetItkGradientContainer()); else mitk::DiffusionPropertyHelper::SetOriginalGradientContainer(image, parameters.m_SignalGen.GetItkGradientContainer()); mitk::DiffusionPropertyHelper::SetReferenceBValue(image, parameters.m_SignalGen.GetBvalue()); mitk::DiffusionPropertyHelper::InitializeImage(image); if (file_extension=="") mitk::IOUtil::Save(image, "DWI_NIFTI", outName+".nii.gz"); else if (file_extension==".nii" || file_extension==".nii.gz") mitk::IOUtil::Save(image, "DWI_NIFTI", outName+file_extension); else mitk::IOUtil::Save(image, outName+file_extension); } else mitk::IOUtil::Save(image, outName+".nii.gz"); if (verbose) { if (tractsToDwiFilter->GetTickImage().IsNotNull()) { mitk::Image::Pointer mitkImage = mitk::Image::New(); itk::TractsToDWIImageFilter< short >::Float2DImageType::Pointer itkImage = tractsToDwiFilter->GetTickImage(); mitkImage = mitk::GrabItkImageMemory( itkImage.GetPointer() ); mitk::IOUtil::Save(mitkImage, outName+"_Ticks.nii.gz"); } if (tractsToDwiFilter->GetRfImage().IsNotNull()) { mitk::Image::Pointer mitkImage = mitk::Image::New(); itk::TractsToDWIImageFilter< short >::Float2DImageType::Pointer itkImage = tractsToDwiFilter->GetRfImage(); mitkImage = mitk::GrabItkImageMemory( itkImage.GetPointer() ); mitk::IOUtil::Save(mitkImage, outName+"_TimeFromRf.nii.gz"); } std::vector< itk::TractsToDWIImageFilter< short >::ItkDoubleImgType::Pointer > volumeFractions = tractsToDwiFilter->GetVolumeFractions(); for (unsigned int k=0; kInitializeByItk(volumeFractions.at(k).GetPointer()); image->SetVolume(volumeFractions.at(k)->GetBufferPointer()); mitk::IOUtil::Save(image, outName+"_Compartment"+boost::lexical_cast(k+1)+".nii.gz"); } if (tractsToDwiFilter->GetPhaseImage().IsNotNull()) { mitk::Image::Pointer image = mitk::Image::New(); itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer itkPhase = tractsToDwiFilter->GetPhaseImage(); image = mitk::GrabItkImageMemory( itkPhase.GetPointer() ); mitk::IOUtil::Save(image, outName+"_Phase.nii.gz"); } if (tractsToDwiFilter->GetKspaceImage().IsNotNull()) { mitk::Image::Pointer image = mitk::Image::New(); itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer itkImage = tractsToDwiFilter->GetKspaceImage(); image = mitk::GrabItkImageMemory( itkImage.GetPointer() ); mitk::IOUtil::Save(image, outName+"_kSpace.nii.gz"); } int c = 1; std::vector< itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer > output_real = tractsToDwiFilter->GetOutputImagesReal(); for (auto real : output_real) { mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(real.GetPointer()); image->SetVolume(real->GetBufferPointer()); mitk::IOUtil::Save(image, outName+"_Coil-"+boost::lexical_cast(c)+"-real.nii.gz"); ++c; } c = 1; std::vector< itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer > output_imag = tractsToDwiFilter->GetOutputImagesImag(); for (auto imag : output_imag) { mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(imag.GetPointer()); image->SetVolume(imag->GetBufferPointer()); mitk::IOUtil::Save(image, outName+"_Coil-"+boost::lexical_cast(c)+"-imag.nii.gz"); ++c; } } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/Fiberfox/RandomFiberPhantom.cpp b/Modules/DiffusionCmdApps/Fiberfox/RandomFiberPhantom.cpp index 12d4d29..c931d3c 100644 --- a/Modules/DiffusionCmdApps/Fiberfox/RandomFiberPhantom.cpp +++ b/Modules/DiffusionCmdApps/Fiberfox/RandomFiberPhantom.cpp @@ -1,172 +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 -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Random Fiber Phantom"); parser.setCategory("Diffusion Simulation Tools"); parser.setContributor("MIC"); parser.setDescription("Create Random Fiber Configurations"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("num_bundles", "", mitkCommandLineParser::Int, "", "", 50); - parser.addArgument("min_density", "", mitkCommandLineParser::Int, "", "", 50); - parser.addArgument("max_density", "", mitkCommandLineParser::Int, "", "", 200); - parser.addArgument("size_x", "", mitkCommandLineParser::Int, "", "", 250); - parser.addArgument("size_y", "", mitkCommandLineParser::Int, "", "", 250); - parser.addArgument("size_z", "", mitkCommandLineParser::Int, "", "", 250); - parser.addArgument("min_stepsize", "", mitkCommandLineParser::Int, "", "", 15); - parser.addArgument("max_stepsize", "", mitkCommandLineParser::Int, "", "", 30); - parser.addArgument("min_curve", "", mitkCommandLineParser::Int, "", "", 5); - parser.addArgument("max_curve", "", mitkCommandLineParser::Int, "", "", 45); - parser.addArgument("min_radius", "", mitkCommandLineParser::Int, "", "", 5); - parser.addArgument("max_radius", "", mitkCommandLineParser::Int, "", "", 25); - parser.addArgument("min_twist", "", mitkCommandLineParser::Int, "", "", 15); - parser.addArgument("max_twist", "", mitkCommandLineParser::Int, "", "", 30); - parser.addArgument("compress", "", mitkCommandLineParser::Float, "Compress:", "compress fiber using the given error threshold (in mm)", 0.1); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output folder:", "output folder", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("fix_seed", "", mitkCommandLineParser::Int, "Fix random seed:", "if >= 0, produce same random values on each run using this seed.", -1); + parser.addArgument("num_bundles", "", mitkDiffusionCommandLineParser::Int, "", "", 50); + parser.addArgument("min_density", "", mitkDiffusionCommandLineParser::Int, "", "", 50); + parser.addArgument("max_density", "", mitkDiffusionCommandLineParser::Int, "", "", 200); + parser.addArgument("size_x", "", mitkDiffusionCommandLineParser::Int, "", "", 250); + parser.addArgument("size_y", "", mitkDiffusionCommandLineParser::Int, "", "", 250); + parser.addArgument("size_z", "", mitkDiffusionCommandLineParser::Int, "", "", 250); + parser.addArgument("min_stepsize", "", mitkDiffusionCommandLineParser::Int, "", "", 15); + parser.addArgument("max_stepsize", "", mitkDiffusionCommandLineParser::Int, "", "", 30); + parser.addArgument("min_curve", "", mitkDiffusionCommandLineParser::Int, "", "", 5); + parser.addArgument("max_curve", "", mitkDiffusionCommandLineParser::Int, "", "", 45); + parser.addArgument("min_radius", "", mitkDiffusionCommandLineParser::Int, "", "", 5); + parser.addArgument("max_radius", "", mitkDiffusionCommandLineParser::Int, "", "", 25); + parser.addArgument("min_twist", "", mitkDiffusionCommandLineParser::Int, "", "", 15); + parser.addArgument("max_twist", "", mitkDiffusionCommandLineParser::Int, "", "", 30); + parser.addArgument("compress", "", mitkDiffusionCommandLineParser::Float, "Compress:", "compress fiber using the given error threshold (in mm)", 0.1); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output folder:", "output folder", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("fix_seed", "", mitkDiffusionCommandLineParser::Int, "Fix random seed:", "if >= 0, produce same random values on each run using this seed.", -1); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string out_folder = us::any_cast(parsedArgs["o"]); float compress=0.1; if (parsedArgs.count("compress")) compress = us::any_cast(parsedArgs["compress"]); int num_bundles=50; if (parsedArgs.count("num_bundles")) num_bundles = us::any_cast(parsedArgs["num_bundles"]); int min_density=50; if (parsedArgs.count("min_density")) min_density = us::any_cast(parsedArgs["min_density"]); int max_density=200; if (parsedArgs.count("max_density")) max_density = us::any_cast(parsedArgs["max_density"]); int size_x=250; if (parsedArgs.count("size_x")) size_x = us::any_cast(parsedArgs["size_x"]); int size_y=250; if (parsedArgs.count("size_y")) size_y = us::any_cast(parsedArgs["size_y"]); int size_z=250; if (parsedArgs.count("size_z")) size_z = us::any_cast(parsedArgs["size_z"]); int min_stepsize=15; if (parsedArgs.count("min_stepsize")) min_stepsize = us::any_cast(parsedArgs["min_stepsize"]); int max_stepsize=30; if (parsedArgs.count("max_stepsize")) max_stepsize = us::any_cast(parsedArgs["max_stepsize"]); int min_curve=5; if (parsedArgs.count("min_curve")) min_curve = us::any_cast(parsedArgs["min_curve"]); int max_curve=45; if (parsedArgs.count("max_curve")) max_curve = us::any_cast(parsedArgs["max_curve"]); int min_radius=5; if (parsedArgs.count("min_radius")) min_radius = us::any_cast(parsedArgs["min_radius"]); int max_radius=25; if (parsedArgs.count("max_radius")) max_radius = us::any_cast(parsedArgs["max_radius"]); int min_twist=15; if (parsedArgs.count("min_twist")) min_twist = us::any_cast(parsedArgs["min_twist"]); int max_twist=30; if (parsedArgs.count("max_twist")) max_twist = us::any_cast(parsedArgs["max_twist"]); int fix_seed = -1; if (parsedArgs.count("fix_seed")) fix_seed = us::any_cast(parsedArgs["fix_seed"]); try { itk::RandomPhantomFilter::Pointer filter = itk::RandomPhantomFilter::New(); filter->SetNumTracts(static_cast(num_bundles)); filter->SetMinStreamlineDensity(static_cast(min_density)); filter->SetMaxStreamlineDensity(static_cast(max_density)); mitk::Vector3D vol; vol[0] = size_x; vol[1] = size_y; vol[2] = size_z; filter->SetVolumeSize(vol); filter->SetStepSizeMin(static_cast(min_stepsize)); filter->SetStepSizeMax(static_cast(max_stepsize)); filter->SetCurvynessMin(static_cast(min_curve)); filter->SetCurvynessMax(static_cast(max_curve)); filter->SetStartRadiusMin(static_cast(min_radius)); filter->SetStartRadiusMax(static_cast(max_radius)); filter->SetMinTwist(static_cast(min_twist)); filter->SetMaxTwist(static_cast(max_twist)); filter->SetFixSeed(fix_seed); filter->Update(); auto fibs = filter->GetFiberBundles(); std::vector< mitk::DataNode::Pointer > fiber_nodes; int c = 1; for (auto fib : fibs) { if (compress>0) fib->Compress(compress); mitk::IOUtil::Save(fib, out_folder + "Bundle_" + boost::lexical_cast(c) + ".fib"); ++c; } } 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/Misc/CopyGeometry.cpp b/Modules/DiffusionCmdApps/Misc/CopyGeometry.cpp index 6ea85d3..e793908 100644 --- a/Modules/DiffusionCmdApps/Misc/CopyGeometry.cpp +++ b/Modules/DiffusionCmdApps/Misc/CopyGeometry.cpp @@ -1,114 +1,114 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" /*! \brief Copies transformation matrix of one image to another */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Copy Geometry"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Copies transformation matrix of one image to another"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("ref", "r", mitkCommandLineParser::String, "Reference:", "reference image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("alignCentroid", "a", mitkCommandLineParser::Bool, "align centroids", "align centroids", us::Any(), true); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("ref", "r", mitkDiffusionCommandLineParser::String, "Reference:", "reference image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("alignCentroid", "a", mitkDiffusionCommandLineParser::Bool, "align centroids", "align centroids", us::Any(), true); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["i"]); std::string refImage = us::any_cast(parsedArgs["ref"]); std::string outImage = us::any_cast(parsedArgs["o"]); bool originOnly = false; // Show a help message if ( parsedArgs.count("alignCentroid") || parsedArgs.count("a")) { originOnly = true; } try { mitk::Image::Pointer source = mitk::IOUtil::Load(refImage); mitk::Image::Pointer target = mitk::IOUtil::Load(imageName); if (originOnly) { // Calculate correction to align centroids double c[3]; c[0] = source->GetGeometry()->GetOrigin()[0] + source->GetGeometry()->GetExtent(0)/2.0 - target->GetGeometry()->GetOrigin()[0] - target->GetGeometry()->GetExtent(0)/2.0; c[1] = source->GetGeometry()->GetOrigin()[1] + source->GetGeometry()->GetExtent(1)/2.0 - target->GetGeometry()->GetOrigin()[1] - target->GetGeometry()->GetExtent(1)/2.0; c[2] = source->GetGeometry()->GetOrigin()[2] + source->GetGeometry()->GetExtent(2)/2.0 - target->GetGeometry()->GetOrigin()[2] - target->GetGeometry()->GetExtent(2)/2.0; double newOrigin[3]; newOrigin[0] = target->GetGeometry()->GetOrigin()[0] +c[0]; newOrigin[1] = target->GetGeometry()->GetOrigin()[1] +c[1]; newOrigin[2] = target->GetGeometry()->GetOrigin()[2] +c[2]; target->GetGeometry()->SetOrigin(newOrigin); } else { mitk::BaseGeometry* s_geom = source->GetGeometry(); mitk::BaseGeometry* t_geom = target->GetGeometry(); t_geom->SetIndexToWorldTransform(s_geom->GetIndexToWorldTransform()); target->SetGeometry(t_geom); } mitk::IOUtil::Save(target, outImage); } 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/Misc/DICOMLoader.cmake b/Modules/DiffusionCmdApps/Misc/DICOMLoader.cmake index 47ba810..889f2c1 100644 --- a/Modules/DiffusionCmdApps/Misc/DICOMLoader.cmake +++ b/Modules/DiffusionCmdApps/Misc/DICOMLoader.cmake @@ -1,4 +1,4 @@ set(CPP_FILES - mitkCommandLineParser.cpp + mitkDiffusionCommandLineParser.cpp DICOMLoader.cpp ) diff --git a/Modules/DiffusionCmdApps/Misc/DImp.cpp b/Modules/DiffusionCmdApps/Misc/DImp.cpp index a8b6a06..95fe594 100644 --- a/Modules/DiffusionCmdApps/Misc/DImp.cpp +++ b/Modules/DiffusionCmdApps/Misc/DImp.cpp @@ -1,72 +1,72 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("DIMP"); parser.setCategory("Preprocessing Tools"); parser.setDescription("TEMPORARY: Converts DICOM to other image types"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["i"]); std::string outImage = us::any_cast(parsedArgs["o"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer source = mitk::IOUtil::Load(imageName, &functor); std::string ext = itksys::SystemTools::GetFilenameExtension(outImage); if (ext==".nii" || ext==".nii.gz") mitk::IOUtil::Save(source, "DWI_NIFTI", outImage); else mitk::IOUtil::Save(source, outImage); } 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/Misc/DReg.cpp b/Modules/DiffusionCmdApps/Misc/DReg.cpp index 96dc2cc..671aa72 100644 --- a/Modules/DiffusionCmdApps/Misc/DReg.cpp +++ b/Modules/DiffusionCmdApps/Misc/DReg.cpp @@ -1,222 +1,222 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include typedef mitk::DiffusionPropertyHelper DPH; mitk::Image::Pointer apply_transform(mitk::Image::Pointer moving, mitk::Image::Pointer fixed_single, mitk::MAPRegistrationWrapper::Pointer reg, bool resample) { mitk::Image::Pointer registered_image; if (!resample) { registered_image = mitk::ImageMappingHelper::refineGeometry(moving, reg, true); } else { if (!mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(moving)) { registered_image = mitk::ImageMappingHelper::map(moving, reg, false, 0, fixed_single->GetGeometry(), false, 0, mitk::ImageMappingInterpolator::BSpline_3); } else { typedef itk::Image ITKDiffusionVolumeType; typedef itk::ComposeImageFilter < ITKDiffusionVolumeType > ComposeFilterType; auto composer = ComposeFilterType::New(); auto itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(moving); for (unsigned int i=0; iGetVectorLength(); ++i) { itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(i); filter->Update(); mitk::Image::Pointer gradientVolume = mitk::Image::New(); gradientVolume->InitializeByItk( filter->GetOutput() ); gradientVolume->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); mitk::Image::Pointer registered_mitk_image = mitk::ImageMappingHelper::map(gradientVolume, reg, false, 0, fixed_single->GetGeometry(), false, 0, mitk::ImageMappingInterpolator::BSpline_3); auto registered_itk_image = ITKDiffusionVolumeType::New(); mitk::CastToItkImage(registered_mitk_image, registered_itk_image); composer->SetInput(i, registered_itk_image); } composer->Update(); registered_image = mitk::GrabItkImageMemory( composer->GetOutput() ); mitk::DiffusionPropertyHelper::CopyProperties(moving, registered_image, true); typedef mitk::DiffusionImageCorrectionFilter CorrectionFilterType; CorrectionFilterType::Pointer corrector = CorrectionFilterType::New(); corrector->SetImage( registered_image ); corrector->CorrectDirections( mitk::MITKRegistrationHelper::getAffineMatrix(reg, false)->GetMatrix().GetVnlMatrix() ); } } return registered_image; } int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("DREG"); parser.setCategory("Preprocessing Tools"); parser.setDescription("TEMPORARY: Rigid registration of two images"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "f", mitkCommandLineParser::String, "Fixed:", "fixed image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "m", mitkCommandLineParser::String, "Moving:", "moving image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("resample", "", mitkCommandLineParser::Bool, "Resample:", "resample moving image", false); - parser.addArgument("coreg", "", mitkCommandLineParser::StringList, "", "additionally apply transform to these images", us::Any(), true, false, false, mitkCommandLineParser::Input); + parser.addArgument("", "f", mitkDiffusionCommandLineParser::String, "Fixed:", "fixed image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "m", mitkDiffusionCommandLineParser::String, "Moving:", "moving image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("resample", "", mitkDiffusionCommandLineParser::Bool, "Resample:", "resample moving image", false); + parser.addArgument("coreg", "", mitkDiffusionCommandLineParser::StringList, "", "additionally apply transform to these images", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string f = us::any_cast(parsedArgs["f"]); std::string m = us::any_cast(parsedArgs["m"]); std::string o = us::any_cast(parsedArgs["o"]); bool resample = false; if (parsedArgs.count("resample")) resample = true; - mitkCommandLineParser::StringContainerType coreg; + mitkDiffusionCommandLineParser::StringContainerType coreg; if (parsedArgs.count("coreg")) - coreg = us::any_cast(parsedArgs["coreg"]); + coreg = us::any_cast(parsedArgs["coreg"]); try { typedef itk::Image< float, 3 > ItkFloatImageType; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer fixed = mitk::IOUtil::Load(f, &functor); mitk::Image::Pointer moving = mitk::IOUtil::Load(m, &functor); mitk::Image::Pointer fixed_single = fixed; mitk::Image::Pointer moving_single = moving; mitk::MultiModalRigidDefaultRegistrationAlgorithm< ItkFloatImageType >::Pointer algo = mitk::MultiModalRigidDefaultRegistrationAlgorithm< ItkFloatImageType >::New(); mitk::MITKAlgorithmHelper helper(algo); if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(fixed)) { DPH::ImageType::Pointer itkVectorImagePointer = DPH::ImageType::New(); mitk::CastToItkImage(fixed, itkVectorImagePointer); itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(0); filter->Update(); fixed_single = mitk::Image::New(); fixed_single->InitializeByItk( filter->GetOutput() ); fixed_single->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); } if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(moving)) { DPH::ImageType::Pointer itkVectorImagePointer = DPH::ImageType::New(); mitk::CastToItkImage(moving, itkVectorImagePointer); itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(0); filter->Update(); moving_single = mitk::Image::New(); moving_single->InitializeByItk( filter->GetOutput() ); moving_single->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); } helper.SetData(moving_single, fixed_single); mitk::MAPRegistrationWrapper::Pointer reg = helper.GetMITKRegistrationWrapper(); mitk::Image::Pointer registered_image = apply_transform(moving, fixed_single, reg, resample); if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(registered_image)) { mitk::DiffusionPropertyHelper::InitializeImage( registered_image ); std::string file_extension = itksys::SystemTools::GetFilenameExtension(o); if (file_extension==".nii" || file_extension==".nii.gz") mitk::IOUtil::Save(registered_image, "DWI_NIFTI", o); else mitk::IOUtil::Save(registered_image, o); } else mitk::IOUtil::Save(registered_image, o); std::string path = ist::GetFilenamePath(o) + "/"; std::vector< std::string > file_names; auto coreg_images = mitk::DiffusionDataIOHelper::load_mitk_images(coreg, &file_names); for (unsigned int i=0; i #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include "mitkDiffusionDICOMFileReader.h" #include "mitkSortByImagePositionPatient.h" #include "mitkDICOMTagBasedSorter.h" #include "mitkDICOMSortByTag.h" #include "itkMergeDiffusionImagesFilter.h" #include static mitk::StringList& GetInputFilenames() { static mitk::StringList inputs; return inputs; } // FIXME slash at the end void SetInputFileNames( std::string input_directory ) { // I. Get all files in directory itksys::Directory input; input.Load( input_directory.c_str() ); // II. Push back files mitk::StringList inputlist;//, mergedlist; for( unsigned long idx=0; idxAddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0010) ); // Number of Rows tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0011) ); // Number of Columns tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0030) ); // Pixel Spacing tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x1164) ); // Imager Pixel Spacing tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0037) ); // Image Orientation (Patient) // TODO add tolerance parameter (l. 1572 of original code) // TODO handle as real vectors! cluster with configurable errors! tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x000e) ); // Series Instance UID tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x0050) ); // Slice Thickness tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0008) ); // Number of Frames //tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0052) ); // Frame of Reference UID // gdcmReader->AddSortingElement( tagSorter ); //mitk::DICOMFileReaderTestHelper::TestOutputsContainInputs( gdcmReader ); mitk::DICOMSortCriterion::ConstPointer sorting = mitk::SortByImagePositionPatient::New( // Image Position (Patient) //mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0013), // instance number mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0012), // aqcuisition number mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0032), // aqcuisition time mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0018, 0x1060), // trigger time mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0018) // SOP instance UID (last resort, not really meaningful but decides clearly) ).GetPointer() ).GetPointer() ).GetPointer() ).GetPointer() // ).GetPointer() ).GetPointer(); tagSorter->SetSortCriterion( sorting ); // mosaic //gdcmReader->SetResolveMosaic( this->m_Controls->m_SplitMosaicCheckBox->isChecked() ); gdcmReader->AddSortingElement( tagSorter );*/ gdcmReader->SetInputFiles( input_files ); try { gdcmReader->AnalyzeInputFiles(); } catch( const itk::ExceptionObject &e) { MITK_ERROR << "Failed to analyze data. " << e.what(); } catch( const std::exception &se) { MITK_ERROR << "Std Exception " << se.what(); } gdcmReader->LoadImages(); mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(0).GetMitkImage(); return loaded_image; } typedef short DiffusionPixelType; typedef itk::VectorImage DwiImageType; typedef DwiImageType::PixelType DwiPixelType; typedef DwiImageType::RegionType DwiRegionType; typedef std::vector< DwiImageType::Pointer > DwiImageContainerType; typedef mitk::Image DiffusionImageType; typedef mitk::DiffusionPropertyHelper::GradientDirectionsContainerType GradientContainerType; typedef std::vector< GradientContainerType::Pointer > GradientListContainerType; void SearchForInputInSubdirs( std::string root_directory, std::string subdir_prefix , std::vector& output_container) { // I. Get all dirs in directory itksys::Directory rootdir; rootdir.Load( root_directory.c_str() ); MITK_INFO("dicom.loader.setinputdirs.start") << "Prefix = " << subdir_prefix; for( unsigned int idx=0; idx parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } std::string inputDirectory = us::any_cast( parsedArgs["i"] ); MITK_INFO << "Loading data from directory: " << inputDirectory; // retrieve the prefix flag (if set) bool search_for_subdirs = false; std::string subdir_prefix; if( parsedArgs.count("dwprefix")) { subdir_prefix = us::any_cast( parsedArgs["dwprefix"] ); if (subdir_prefix != "") { MITK_INFO << "Prefix specified, will search for subdirs in the input directory!"; search_for_subdirs = true; } } // retrieve the output std::string outputFile = us::any_cast< std::string >( parsedArgs["o"] ); // if the executable is called with a single directory, just parse the given folder for files and read them into a diffusion image if( !search_for_subdirs ) { SetInputFileNames( inputDirectory ); MITK_INFO << "Got " << GetInputFilenames().size() << " input files."; mitk::Image::Pointer d_img = ReadInDICOMFiles( GetInputFilenames(), outputFile ); try { mitk::IOUtil::Save(d_img, outputFile.c_str()); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Failed to write out the output file. \n\t Reason : ITK Exception " << e.what(); } } // if the --dwprefix flag is set, then we have to look for the directories, load each of them separately and afterwards merge the images else { std::vector output_container; SearchForInputInSubdirs( inputDirectory, subdir_prefix, output_container ); // final output image mitk::Image::Pointer image = mitk::Image::New(); if( output_container.size() > 1 ) { DwiImageContainerType imageContainer; GradientListContainerType gradientListContainer; std::vector< double > bValueContainer; for ( std::vector< mitk::Image::Pointer >::iterator dwi = output_container.begin(); dwi != output_container.end(); ++dwi ) { mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(*dwi, itkVectorImagePointer); imageContainer.push_back(itkVectorImagePointer); gradientListContainer.push_back( mitk::DiffusionPropertyHelper::GetGradientContainer(*dwi)); bValueContainer.push_back( mitk::DiffusionPropertyHelper::GetReferenceBValue(*dwi)); } typedef itk::MergeDiffusionImagesFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetImageVolumes(imageContainer); filter->SetGradientLists(gradientListContainer); filter->SetBValues(bValueContainer); filter->Update(); vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity(); image = mitk::GrabItkImageMemory( filter->GetOutput() ); mitk::DiffusionPropertyHelper::SetGradientContainer(image, filter->GetOutputGradients()); mitk::DiffusionPropertyHelper::SetReferenceBValue(image, filter->GetB_Value()); mitk::DiffusionPropertyHelper::SetMeasurementFrame(image, mf); mitk::DiffusionPropertyHelper::InitializeImage( image ); } // just output the image if there was only one folder found else { image = output_container.at(0); } MITK_INFO("dicom.import.writeout") << " [OutputFile] " << outputFile.c_str(); try { mitk::IOUtil::Save(image, outputFile.c_str()); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Failed to write out the output file. \n\t Reason : ITK Exception " << e.what(); } } return 1; } diff --git a/Modules/DiffusionCmdApps/Misc/DmriDenoising.cpp b/Modules/DiffusionCmdApps/Misc/DmriDenoising.cpp index 054ce3f..554e579 100644 --- a/Modules/DiffusionCmdApps/Misc/DmriDenoising.cpp +++ b/Modules/DiffusionCmdApps/Misc/DmriDenoising.cpp @@ -1,234 +1,234 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("DmriDenoising"); parser.setCategory("Preprocessing Tools"); parser.setDescription("dMRI denoising tool"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory arguments:"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("type", "", mitkCommandLineParser::Int, "Type:", "0 (TotalVariation), 1 (Gauss), 2 (NLM)", 0); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("type", "", mitkDiffusionCommandLineParser::Int, "Type:", "0 (TotalVariation), 1 (Gauss), 2 (NLM)", 0); parser.endGroup(); parser.beginGroup("2. Total variation parameters:"); - parser.addArgument("tv_iterations", "", mitkCommandLineParser::Int, "Iterations:", "", 1); - parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda:", "", 0.1); + parser.addArgument("tv_iterations", "", mitkDiffusionCommandLineParser::Int, "Iterations:", "", 1); + parser.addArgument("lambda", "", mitkDiffusionCommandLineParser::Float, "Lambda:", "", 0.1); parser.endGroup(); parser.beginGroup("3. Gauss parameters:"); - parser.addArgument("variance", "", mitkCommandLineParser::Float, "Variance:", "", 1.0); + parser.addArgument("variance", "", mitkDiffusionCommandLineParser::Float, "Variance:", "", 1.0); parser.endGroup(); parser.beginGroup("4. NLM parameters:"); - parser.addArgument("nlm_iterations", "", mitkCommandLineParser::Int, "Iterations:", "", 4); - parser.addArgument("sampling_radius", "", mitkCommandLineParser::Int, "Sampling radius:", "", 4); - parser.addArgument("patch_radius", "", mitkCommandLineParser::Int, "Patch radius:", "", 1); - parser.addArgument("num_patches", "", mitkCommandLineParser::Int, "Num. patches:", "", 10); + parser.addArgument("nlm_iterations", "", mitkDiffusionCommandLineParser::Int, "Iterations:", "", 4); + parser.addArgument("sampling_radius", "", mitkDiffusionCommandLineParser::Int, "Sampling radius:", "", 4); + parser.addArgument("patch_radius", "", mitkDiffusionCommandLineParser::Int, "Patch radius:", "", 1); + parser.addArgument("num_patches", "", mitkDiffusionCommandLineParser::Int, "Num. patches:", "", 10); parser.endGroup(); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["i"]); std::string outImage = us::any_cast(parsedArgs["o"]); int type = 0; if (parsedArgs.count("type")) type = us::any_cast(parsedArgs["type"]); int tv_iterations = 1; if (parsedArgs.count("tv_iterations")) tv_iterations = us::any_cast(parsedArgs["tv_iterations"]); float lambda = 0.1; if (parsedArgs.count("lambda")) lambda = us::any_cast(parsedArgs["lambda"]); float variance = 1.0; if (parsedArgs.count("variance")) variance = us::any_cast(parsedArgs["variance"]); int nlm_iterations = 4; if (parsedArgs.count("nlm_iterations")) nlm_iterations = us::any_cast(parsedArgs["nlm_iterations"]); int sampling_radius = 4; if (parsedArgs.count("sampling_radius")) sampling_radius = us::any_cast(parsedArgs["sampling_radius"]); int patch_radius = 1; if (parsedArgs.count("patch_radius")) patch_radius = us::any_cast(parsedArgs["patch_radius"]); int num_patches = 10; if (parsedArgs.count("num_patches")) num_patches = us::any_cast(parsedArgs["num_patches"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer input_image = mitk::IOUtil::Load(imageName, &functor); typedef short DiffusionPixelType; typedef itk::VectorImage DwiImageType; typedef itk::Image DwiVolumeType; typedef itk::DiscreteGaussianImageFilter < DwiVolumeType, DwiVolumeType > GaussianFilterType; typedef itk::PatchBasedDenoisingImageFilter < DwiVolumeType, DwiVolumeType > NlmFilterType; typedef itk::VectorImageToImageFilter < DiffusionPixelType > ExtractFilterType; typedef itk::ComposeImageFilter < itk::Image > ComposeFilterType; if (!mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(input_image)) mitkThrow() << "Input is not a diffusion-weighted image!"; DwiImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(input_image); mitk::Image::Pointer denoised_image = nullptr; switch (type) { case 0: { ComposeFilterType::Pointer composer = ComposeFilterType::New(); for (unsigned int i=0; iGetVectorLength(); ++i) { ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetInput( itkVectorImagePointer ); extractor->SetIndex( i ); extractor->Update(); DwiVolumeType::Pointer gradient_volume = extractor->GetOutput(); itk::TotalVariationDenoisingImageFilter< DwiVolumeType, DwiVolumeType >::Pointer filter = itk::TotalVariationDenoisingImageFilter< DwiVolumeType, DwiVolumeType >::New(); filter->SetInput(gradient_volume); filter->SetLambda(lambda); filter->SetNumberIterations(tv_iterations); filter->Update(); composer->SetInput(i, filter->GetOutput()); } composer->Update(); denoised_image = mitk::GrabItkImageMemory(composer->GetOutput()); break; } case 1: { ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetInput( itkVectorImagePointer ); ComposeFilterType::Pointer composer = ComposeFilterType::New(); for (unsigned int i = 0; i < itkVectorImagePointer->GetVectorLength(); ++i) { extractor->SetIndex(i); extractor->Update(); GaussianFilterType::Pointer filter = GaussianFilterType::New(); filter->SetVariance(variance); filter->SetInput(extractor->GetOutput()); filter->Update(); composer->SetInput(i, filter->GetOutput()); } composer->Update(); denoised_image = mitk::GrabItkImageMemory(composer->GetOutput()); break; } case 2: { typedef itk::Statistics::GaussianRandomSpatialNeighborSubsampler< NlmFilterType::PatchSampleType, DwiVolumeType::RegionType > SamplerType; // sampling the image to find similar patches SamplerType::Pointer sampler = SamplerType::New(); sampler->SetRadius( sampling_radius ); sampler->SetVariance( sampling_radius*sampling_radius ); sampler->SetNumberOfResultsRequested( num_patches ); MITK_INFO << "Starting NLM denoising"; ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetInput( itkVectorImagePointer ); ComposeFilterType::Pointer composer = ComposeFilterType::New(); for (unsigned int i = 0; i < itkVectorImagePointer->GetVectorLength(); ++i) { extractor->SetIndex(i); extractor->Update(); NlmFilterType::Pointer filter = NlmFilterType::New(); filter->SetInput(extractor->GetOutput()); filter->SetPatchRadius(patch_radius); filter->SetNoiseModel(NlmFilterType::RICIAN); filter->UseSmoothDiscPatchWeightsOn(); filter->UseFastTensorComputationsOn(); filter->SetNumberOfIterations(nlm_iterations); filter->SetSmoothingWeight( 1 ); filter->SetKernelBandwidthEstimation(true); filter->SetSampler( sampler ); filter->Update(); composer->SetInput(i, filter->GetOutput()); MITK_INFO << "Gradient " << i << " finished"; } composer->Update(); denoised_image = mitk::GrabItkImageMemory(composer->GetOutput()); break; } } mitk::DiffusionPropertyHelper::SetGradientContainer(denoised_image, mitk::DiffusionPropertyHelper::GetGradientContainer(input_image)); mitk::DiffusionPropertyHelper::SetReferenceBValue(denoised_image, mitk::DiffusionPropertyHelper::GetReferenceBValue(input_image)); mitk::DiffusionPropertyHelper::InitializeImage( denoised_image ); std::string ext = itksys::SystemTools::GetFilenameExtension(outImage); if (ext==".nii" || ext==".nii.gz") mitk::IOUtil::Save(denoised_image, "DWI_NIFTI", outImage); else mitk::IOUtil::Save(denoised_image, outImage); } 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/Misc/FileFormatConverter.cpp b/Modules/DiffusionCmdApps/Misc/FileFormatConverter.cpp index 2e6eea3..4263587 100644 --- a/Modules/DiffusionCmdApps/Misc/FileFormatConverter.cpp +++ b/Modules/DiffusionCmdApps/Misc/FileFormatConverter.cpp @@ -1,80 +1,80 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include /*! \brief Load image and save as specified file type. */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Format Converter"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Load image and save as specified file type."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input file", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output file", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input file", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output file", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string inName = us::any_cast(parsedArgs["i"]); std::string outName = us::any_cast(parsedArgs["o"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); std::vector baseData = mitk::IOUtil::Load(inName, &functor); if ( baseData.size()>0 && dynamic_cast(baseData[0].GetPointer()) ) { mitk::IOUtil::Save(dynamic_cast(baseData[0].GetPointer()), outName.c_str()); } else if ( baseData.size()>0 && dynamic_cast(baseData[0].GetPointer()) ) { mitk::IOUtil::Save(dynamic_cast(baseData[0].GetPointer()) ,outName.c_str()); } else std::cout << "File type currently not supported!"; } catch (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/Misc/FlipPeaks.cpp b/Modules/DiffusionCmdApps/Misc/FlipPeaks.cpp index 758265b..c8051b2 100644 --- a/Modules/DiffusionCmdApps/Misc/FlipPeaks.cpp +++ b/Modules/DiffusionCmdApps/Misc/FlipPeaks.cpp @@ -1,104 +1,104 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include /*! \brief Copies transformation matrix of one image to another */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Flip Peaks"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Flips the peaks of the input peak image along the given dimensions."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("", "x", mitkCommandLineParser::Bool, "Flip x", "flip along x-axis"); - parser.addArgument("", "y", mitkCommandLineParser::Bool, "Flip y", "flip along y-axis"); - parser.addArgument("", "z", mitkCommandLineParser::Bool, "Flip z", "flip along z-axis"); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("", "x", mitkDiffusionCommandLineParser::Bool, "Flip x", "flip along x-axis"); + parser.addArgument("", "y", mitkDiffusionCommandLineParser::Bool, "Flip y", "flip along y-axis"); + parser.addArgument("", "z", mitkDiffusionCommandLineParser::Bool, "Flip z", "flip along z-axis"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string imageName = us::any_cast(parsedArgs["i"]); std::string outImage = us::any_cast(parsedArgs["o"]); bool x = false; if (parsedArgs.count("x")) x = us::any_cast(parsedArgs["x"]); bool y = false; if (parsedArgs.count("y")) y = us::any_cast(parsedArgs["y"]); bool z = false; if (parsedArgs.count("z")) z = us::any_cast(parsedArgs["z"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image"}, {}); mitk::PeakImage::Pointer image = mitk::IOUtil::Load(imageName, &functor); typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); mitk::PeakImage::ItkPeakImageType::Pointer itkImg = caster->GetOutput(); itk::FlipPeaksFilter< float >::Pointer flipper = itk::FlipPeaksFilter< float >::New(); flipper->SetInput(itkImg); flipper->SetFlipX(x); flipper->SetFlipY(y); flipper->SetFlipZ(z); flipper->Update(); mitk::Image::Pointer resultImage = dynamic_cast(mitk::PeakImage::New().GetPointer()); mitk::CastToMitkImage(flipper->GetOutput(), resultImage); resultImage->SetVolume(flipper->GetOutput()->GetBufferPointer()); mitk::IOUtil::Save(resultImage, outImage); } 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/Misc/HeadMotionCorrection.cpp b/Modules/DiffusionCmdApps/Misc/HeadMotionCorrection.cpp index 6633946..57075d1 100644 --- a/Modules/DiffusionCmdApps/Misc/HeadMotionCorrection.cpp +++ b/Modules/DiffusionCmdApps/Misc/HeadMotionCorrection.cpp @@ -1,78 +1,78 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("HeadMotionCorrection"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Simple affine head-motion correction tool"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["i"]); std::string outImage = us::any_cast(parsedArgs["o"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer in_image = mitk::IOUtil::Load(imageName, &functor); mitk::DWIHeadMotionCorrectionFilter::Pointer registerer = mitk::DWIHeadMotionCorrectionFilter::New(); registerer->SetInput(in_image); registerer->Update(); mitk::Image::Pointer out_image = registerer->GetCorrectedImage(); std::string ext = itksys::SystemTools::GetFilenameExtension(outImage); if (ext==".nii" || ext==".nii.gz") mitk::IOUtil::Save(out_image, "DWI_NIFTI", outImage); else mitk::IOUtil::Save(out_image, outImage); } 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/Misc/ImageResampler.cpp b/Modules/DiffusionCmdApps/Misc/ImageResampler.cpp index ba2cfec..e7736b4 100644 --- a/Modules/DiffusionCmdApps/Misc/ImageResampler.cpp +++ b/Modules/DiffusionCmdApps/Misc/ImageResampler.cpp @@ -1,420 +1,420 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include // ITK #include #include #include "itkLinearInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkIdentityTransform.h" #include "itkResampleImageFilter.h" #include "itkResampleDwiImageFilter.h" typedef itk::Image InputImageType; typedef itk::Image BinaryImageType; static mitk::Image::Pointer TransformToReference(mitk::Image *reference, mitk::Image *moving, bool sincInterpol = false, bool nn = false) { // Convert to itk Images // Identify Transform typedef itk::IdentityTransform T_Transform; T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 3> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); typedef itk::LinearInterpolateImageFunction< InputImageType> LinearInterpolateImageFunctionType; LinearInterpolateImageFunctionType::Pointer lin_interpolator = LinearInterpolateImageFunctionType::New(); typedef itk::NearestNeighborInterpolateImageFunction< BinaryImageType> NearestNeighborInterpolateImageFunctionType; NearestNeighborInterpolateImageFunctionType::Pointer nn_interpolator = NearestNeighborInterpolateImageFunctionType::New(); if (!nn) { InputImageType::Pointer itkReference = InputImageType::New(); InputImageType::Pointer itkMoving = InputImageType::New(); mitk::CastToItkImage(reference,itkReference); mitk::CastToItkImage(moving,itkMoving); typedef itk::ResampleImageFilter ResampleFilterType; ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkMoving); resampler->SetReferenceImage( itkReference ); resampler->UseReferenceImageOn(); resampler->SetTransform(_pTransform); if ( sincInterpol) resampler->SetInterpolator(sinc_interpolator); else resampler->SetInterpolator(lin_interpolator); resampler->Update(); // Convert back to mitk mitk::Image::Pointer result = mitk::Image::New(); result->InitializeByItk(resampler->GetOutput()); GrabItkImageMemory( resampler->GetOutput() , result ); return result; } BinaryImageType::Pointer itkReference = BinaryImageType::New(); BinaryImageType::Pointer itkMoving = BinaryImageType::New(); mitk::CastToItkImage(reference,itkReference); mitk::CastToItkImage(moving,itkMoving); typedef itk::ResampleImageFilter ResampleFilterType; ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkMoving); resampler->SetReferenceImage( itkReference ); resampler->UseReferenceImageOn(); resampler->SetTransform(_pTransform); resampler->SetInterpolator(nn_interpolator); resampler->Update(); // Convert back to mitk mitk::Image::Pointer result = mitk::Image::New(); result->InitializeByItk(resampler->GetOutput()); GrabItkImageMemory( resampler->GetOutput() , result ); return result; } static std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } static std::vector split(const std::string &s, char delim) { std::vector < std::string > elems; return split(s, delim, elems); } static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing, bool useLinInt = true, bool useNN = false) { if (!useNN) { InputImageType::Pointer itkImage = InputImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. InputImageType::SpacingType inputSpacing = itkImage->GetSpacing(); InputImageType::SpacingType outputSpacing; const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); InputImageType::SizeType outputSize; typedef InputImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::LinearInterpolateImageFunction< InputImageType > LinearInterpolatorType; LinearInterpolatorType::Pointer lin_interpolator = LinearInterpolatorType::New(); typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); if (useLinInt) _pResizeFilter->SetInterpolator(lin_interpolator); else _pResizeFilter->SetInterpolator(sinc_interpolator); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } BinaryImageType::Pointer itkImage = BinaryImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. BinaryImageType::SpacingType inputSpacing = itkImage->GetSpacing(); BinaryImageType::SpacingType outputSpacing; const BinaryImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); BinaryImageType::SizeType outputSize; typedef BinaryImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::NearestNeighborInterpolateImageFunction< BinaryImageType> NearestNeighborInterpolateImageType; NearestNeighborInterpolateImageType::Pointer nn_interpolator = NearestNeighborInterpolateImageType::New(); _pResizeFilter->SetInterpolator(nn_interpolator); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } static mitk::Image::Pointer ResampleDWIbySpacing(mitk::Image::Pointer input, float* spacing) { itk::Vector spacingVector; spacingVector[0] = spacing[0]; spacingVector[1] = spacing[1]; spacingVector[2] = spacing[2]; typedef itk::ResampleDwiImageFilter ResampleFilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(input, itkVectorImagePointer); ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput( itkVectorImagePointer ); resampler->SetInterpolation(ResampleFilterType::Interpolate_Linear); resampler->SetNewSpacing(spacingVector); resampler->Update(); mitk::Image::Pointer output = mitk::GrabItkImageMemory( resampler->GetOutput() ); mitk::DiffusionPropertyHelper::SetGradientContainer(output, mitk::DiffusionPropertyHelper::GetGradientContainer(input)); mitk::DiffusionPropertyHelper::SetReferenceBValue(output, mitk::DiffusionPropertyHelper::GetReferenceBValue(input)); mitk::DiffusionPropertyHelper::InitializeImage( output ); return output; } int main( int argc, char* argv[] ) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setArgumentPrefix("--","-"); parser.setTitle("Image Resampler"); parser.setCategory("Preprocessing Tools"); parser.setContributor("MIC"); parser.setDescription("Resample an image to eigther a specific spacing or to a reference image."); // Add command line argument names - parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Show this help text"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "Input file",us::Any(),false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "Output file",us::Any(),false, false, false, mitkCommandLineParser::Output); - parser.addArgument("spacing", "s", mitkCommandLineParser::String, "Spacing:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); - parser.addArgument("reference", "r", mitkCommandLineParser::String, "Reference:", "Resample using supplied reference image. Also cuts image to same dimensions",us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("win-sinc", "w", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); - parser.addArgument("nearest-neigh", "n", mitkCommandLineParser::Bool, "Nearest Neighbor:", "Use Nearest Neighbor interpolation instead of linear interpolation ",us::Any()); + parser.addArgument("help", "h",mitkDiffusionCommandLineParser::Bool, "Show this help text"); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "Input file",us::Any(),false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "Output file",us::Any(),false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("spacing", "s", mitkDiffusionCommandLineParser::String, "Spacing:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); + parser.addArgument("reference", "r", mitkDiffusionCommandLineParser::String, "Reference:", "Resample using supplied reference image. Also cuts image to same dimensions",us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("win-sinc", "w", mitkDiffusionCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); + parser.addArgument("nearest-neigh", "n", mitkDiffusionCommandLineParser::Bool, "Nearest Neighbor:", "Use Nearest Neighbor interpolation instead of linear interpolation ",us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool useSpacing = false; bool useLinearInterpol = true; bool useNN= false; { if (parsedArgs.size() == 0) { return EXIT_FAILURE; } if (parsedArgs.count("sinc-int")) useLinearInterpol = false; if (parsedArgs.count("nearest-neigh")) useNN = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string outputFile = us::any_cast(parsedArgs["i"]); std::string inputFile = us::any_cast(parsedArgs["o"]); std::vector spacings; float spacing[] = { 0.0f, 0.0f, 0.0f }; if (parsedArgs.count("spacing")) { std::string arg = us::any_cast(parsedArgs["spacing"]); if (arg != "") { spacings = split(arg ,','); spacing[0] = atoi(spacings.at(0).c_str()); spacing[1] = atoi(spacings.at(1).c_str()); spacing[2] = atoi(spacings.at(2).c_str()); useSpacing = true; } } std::string refImageFile = ""; if (parsedArgs.count("reference")) { refImageFile = us::any_cast(parsedArgs["reference"]); } if (refImageFile =="" && useSpacing == false) { MITK_ERROR << "No information how to resample is supplied. Use eigther --spacing or --reference !"; return EXIT_FAILURE; } mitk::Image::Pointer refImage; if (!useSpacing) refImage = mitk::IOUtil::Load(refImageFile); mitk::Image::Pointer inputDWI = mitk::IOUtil::Load(inputFile); if ( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(inputDWI.GetPointer())) { mitk::Image::Pointer outputImage; if (useSpacing) outputImage = ResampleDWIbySpacing(inputDWI, spacing); else { MITK_WARN << "Not supported yet, to resample a DWI please set a new spacing."; return EXIT_FAILURE; } mitk::IOUtil::Save(outputImage, outputFile.c_str()); return EXIT_SUCCESS; } mitk::Image::Pointer inputImage = mitk::IOUtil::Load(inputFile); mitk::Image::Pointer resultImage; if (useSpacing) resultImage = ResampleBySpacing(inputImage,spacing,useLinearInterpol,useNN); else resultImage = TransformToReference(refImage,inputImage,useLinearInterpol,useNN); mitk::IOUtil::Save(resultImage, outputFile); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/Misc/PeakExtraction.cpp b/Modules/DiffusionCmdApps/Misc/PeakExtraction.cpp index 5f6d486..ca34ce5 100644 --- a/Modules/DiffusionCmdApps/Misc/PeakExtraction.cpp +++ b/Modules/DiffusionCmdApps/Misc/PeakExtraction.cpp @@ -1,294 +1,294 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include template int StartPeakExtraction(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input image", "sh coefficient image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output directory", "output root", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("mask", "", mitkCommandLineParser::String, "Mask", "mask image", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("normalization", "", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true); - parser.addArgument("numpeaks", "", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input image", "sh coefficient image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output directory", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("mask", "", mitkDiffusionCommandLineParser::String, "Mask", "mask image", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("normalization", "", mitkDiffusionCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true); + parser.addArgument("numpeaks", "", mitkDiffusionCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true); - parser.addArgument("rel_peakthr", "", mitkCommandLineParser::Float, "Relative peak threshold", "peak threshold relative to largest peak", 0.4, true); - parser.addArgument("abs_peakthr", "", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak magnitude threshold", 0.03, true); - parser.addArgument("angular_thr", "", mitkCommandLineParser::Float, "Angular threshold", "in degree", 15); + parser.addArgument("rel_peakthr", "", mitkDiffusionCommandLineParser::Float, "Relative peak threshold", "peak threshold relative to largest peak", 0.4, true); + parser.addArgument("abs_peakthr", "", mitkDiffusionCommandLineParser::Float, "Absolute peak threshold", "absolute peak magnitude threshold", 0.03, true); + parser.addArgument("angular_thr", "", mitkDiffusionCommandLineParser::Float, "Angular threshold", "in degree", 15); - parser.addArgument("shConvention", "", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MRtrix, FSL)", std::string("MRtrix"), true); + parser.addArgument("shConvention", "", mitkDiffusionCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MRtrix, FSL)", std::string("MRtrix"), true); - parser.addArgument("flipX", "", mitkCommandLineParser::Bool, "Flip X", "Flip peaks in x direction"); - parser.addArgument("flipY", "", mitkCommandLineParser::Bool, "Flip Y", "Flip peaks in y direction"); - parser.addArgument("flipZ", "", mitkCommandLineParser::Bool, "Flip Z", "Flip peaks in z direction"); - parser.addArgument("scale_by_gfa", "", mitkCommandLineParser::Bool, "Scale by GFA", "Scale ODF values and peaks by GFA"); + parser.addArgument("flipX", "", mitkDiffusionCommandLineParser::Bool, "Flip X", "Flip peaks in x direction"); + parser.addArgument("flipY", "", mitkDiffusionCommandLineParser::Bool, "Flip Y", "Flip peaks in y direction"); + parser.addArgument("flipZ", "", mitkDiffusionCommandLineParser::Bool, "Flip Z", "Flip peaks in z direction"); + parser.addArgument("scale_by_gfa", "", mitkDiffusionCommandLineParser::Bool, "Scale by GFA", "Scale ODF values and peaks by GFA"); parser.setCategory("Preprocessing Tools"); parser.setTitle("Peak Extraction"); parser.setDescription(""); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["i"]); std::string outRoot = us::any_cast(parsedArgs["o"]); // optional arguments std::string maskImageName(""); if (parsedArgs.count("mask")) maskImageName = us::any_cast(parsedArgs["mask"]); int normalization = 1; if (parsedArgs.count("normalization")) normalization = us::any_cast(parsedArgs["normalization"]); int numPeaks = 2; if (parsedArgs.count("numpeaks")) numPeaks = us::any_cast(parsedArgs["numpeaks"]); float rel_peakthr = 0.4; if (parsedArgs.count("rel_peakthr")) rel_peakthr = us::any_cast(parsedArgs["rel_peakthr"]); float abs_peakthr = 0.03; if (parsedArgs.count("abs_peakthr")) abs_peakthr = us::any_cast(parsedArgs["abs_peakthr"]); float angular_thr = 15; if (parsedArgs.count("angular_thr")) angular_thr = us::any_cast(parsedArgs["angular_thr"]); angular_thr = cos((float)angular_thr*itk::Math::pi / 180); bool scale_by_gfa = false; if (parsedArgs.count("scale_by_gfa")) scale_by_gfa = us::any_cast(parsedArgs["scale_by_gfa"]); bool flipX = false; if (parsedArgs.count("flipX")) flipX = us::any_cast(parsedArgs["flipX"]); bool flipY = false; if (parsedArgs.count("flipY")) flipY = us::any_cast(parsedArgs["flipY"]); bool flipZ = false; if (parsedArgs.count("flipZ")) flipZ = us::any_cast(parsedArgs["flipZ"]); std::cout << "image: " << imageName; std::cout << "outroot: " << outRoot; if (!maskImageName.empty()) std::cout << "mask: " << maskImageName; else std::cout << "no mask image selected"; std::cout << "numpeaks: " << numPeaks; std::cout << "peakthres: " << rel_peakthr; std::cout << "abspeakthres: " << abs_peakthr; std::cout << "shOrder: " << shOrder; try { mitk::Image::Pointer image = mitk::IOUtil::Load(imageName); mitk::Image::Pointer mask = mitk::IOUtil::Load(maskImageName); typedef itk::Image ItkUcharImgType; typedef itk::OdfMaximaExtractionFilter< float, shOrder, 20242 > MaximaExtractionFilterType; typename MaximaExtractionFilterType::Pointer peak_extraction_filter = MaximaExtractionFilterType::New(); ItkUcharImgType::Pointer itkMaskImage = nullptr; if (mask.IsNotNull()) { try{ itkMaskImage = ItkUcharImgType::New(); mitk::CastToItkImage(mask, itkMaskImage); peak_extraction_filter->SetMaskImage(itkMaskImage); } catch(...) { } } if (parsedArgs.count("shConvention")) { std::string convention = us::any_cast(parsedArgs["shConvention"]).c_str(); if ( convention=="FSL" ) peak_extraction_filter->SetToolkit(MaximaExtractionFilterType::FSL); else peak_extraction_filter->SetToolkit(MaximaExtractionFilterType::MRTRIX); } else peak_extraction_filter->SetToolkit(MaximaExtractionFilterType::MRTRIX); try{ typedef mitk::ImageToItk< typename MaximaExtractionFilterType::CoefficientImageType > CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); peak_extraction_filter->SetInput(caster->GetOutput()); } catch(...) { std::cout << "wrong image type"; return EXIT_FAILURE; } peak_extraction_filter->SetMaxNumPeaks(numPeaks); peak_extraction_filter->SetRelativePeakThreshold(rel_peakthr); peak_extraction_filter->SetAbsolutePeakThreshold(abs_peakthr); peak_extraction_filter->SetAngularThreshold(angular_thr); peak_extraction_filter->SetFlipX(flipX); peak_extraction_filter->SetFlipY(flipY); peak_extraction_filter->SetFlipZ(flipZ); peak_extraction_filter->SetScaleByGfa(scale_by_gfa); switch (normalization) { case 0: peak_extraction_filter->SetNormalizationMethod(MaximaExtractionFilterType::NO_NORM); break; case 1: peak_extraction_filter->SetNormalizationMethod(MaximaExtractionFilterType::MAX_VEC_NORM); break; case 2: peak_extraction_filter->SetNormalizationMethod(MaximaExtractionFilterType::SINGLE_VEC_NORM); break; } std::cout << "Starting extraction"; peak_extraction_filter->Update(); mitk::LocaleSwitch localeSwitch("C"); // write direction image { typename MaximaExtractionFilterType::PeakImageType::Pointer itkImg = peak_extraction_filter->GetPeakImage(); std::string outfilename = outRoot; outfilename.append("_PEAKS.nrrd"); typedef itk::ImageFileWriter< typename MaximaExtractionFilterType::PeakImageType > WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outfilename); writer->SetInput(itkImg); writer->Update(); } // write num directions image { ItkUcharImgType::Pointer numDirImage = peak_extraction_filter->GetNumDirectionsImage(); if (itkMaskImage.IsNotNull()) { numDirImage->SetDirection(itkMaskImage->GetDirection()); numDirImage->SetOrigin(itkMaskImage->GetOrigin()); } std::string outfilename = outRoot.c_str(); outfilename.append("_NUM_PEAKS.nrrd"); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outfilename); writer->SetInput(numDirImage); writer->Update(); } } 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; } /*! \brief Extract maxima in the input spherical harmonics image. */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input image", "sh coefficient image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output directory", "output root", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order"); - parser.addArgument("mask", "m", mitkCommandLineParser::String, "Mask", "mask image", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true); - parser.addArgument("numpeaks", "p", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true); - parser.addArgument("peakthres", "r", mitkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true); - parser.addArgument("abspeakthres", "a", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true); - parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", std::string("MITK"), true); - parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention"); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input image", "sh coefficient image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output directory", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("shOrder", "sh", mitkDiffusionCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order"); + parser.addArgument("mask", "m", mitkDiffusionCommandLineParser::String, "Mask", "mask image", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("normalization", "n", mitkDiffusionCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true); + parser.addArgument("numpeaks", "p", mitkDiffusionCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true); + parser.addArgument("peakthres", "r", mitkDiffusionCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true); + parser.addArgument("abspeakthres", "a", mitkDiffusionCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true); + parser.addArgument("shConvention", "s", mitkDiffusionCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", std::string("MITK"), true); + parser.addArgument("noFlip", "f", mitkDiffusionCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention"); parser.setCategory("Preprocessing Tools"); parser.setTitle("Peak Extraction"); parser.setDescription("Extract maxima in the input spherical harmonics image."); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; int shOrder = -1; if (parsedArgs.count("shOrder")) shOrder = us::any_cast(parsedArgs["shOrder"]); switch (shOrder) { case 4: return StartPeakExtraction<4>(argc, argv); case 6: return StartPeakExtraction<6>(argc, argv); case 8: return StartPeakExtraction<8>(argc, argv); case 10: return StartPeakExtraction<10>(argc, argv); case 12: return StartPeakExtraction<12>(argc, argv); } return EXIT_FAILURE; } diff --git a/Modules/DiffusionCmdApps/Misc/Registration.cpp b/Modules/DiffusionCmdApps/Misc/Registration.cpp index 947dcd8..7b1a1c6 100644 --- a/Modules/DiffusionCmdApps/Misc/Registration.cpp +++ b/Modules/DiffusionCmdApps/Misc/Registration.cpp @@ -1,445 +1,445 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // CTK -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include // ITK #include #include #include "itkLinearInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkIdentityTransform.h" #include "itkResampleImageFilter.h" #include "itkNrrdImageIO.h" typedef std::vector FileListType; typedef itk::Image InputImageType; static mitk::Image::Pointer ExtractFirstTS(mitk::Image* image, std::string fileType) { if (fileType == ".dwi") return image; mitk::ImageTimeSelector::Pointer selector = mitk::ImageTimeSelector::New(); selector->SetInput(image); selector->SetTimeNr(0); selector->UpdateLargestPossibleRegion(); mitk::Image::Pointer img =selector->GetOutput()->Clone(); return img; } static std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } static std::vector split(const std::string &s, char delim) { std::vector < std::string > elems; return split(s, delim, elems); } /// Create list of all files in provided folder ending with same postfix static FileListType CreateFileList(std::string folder , std::string postfix) { itk::Directory::Pointer dir = itk::Directory::New(); FileListType fileList; if( dir->Load(folder.c_str() ) ) { int n = dir->GetNumberOfFiles(); for(int r=0;rGetFile( r ); if (filename == "." || filename == "..") continue; filename = folder + filename; if (!itksys::SystemTools::FileExists( filename.c_str())) continue; if (filename.length() <= postfix.length() ) continue; if (filename.substr(filename.length() -postfix.length() ) == postfix) fileList.push_back(filename); } } return fileList; } static std::string GetSavePath(std::string outputFolder, std::string fileName) { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileName); std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(fileName); std::string savePathAndFileName = outputFolder +fileStem + fileType; return savePathAndFileName; } static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing) { InputImageType::Pointer itkImage = InputImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. InputImageType::SpacingType inputSpacing = itkImage->GetSpacing(); InputImageType::SpacingType outputSpacing; const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); InputImageType::SizeType outputSize; typedef InputImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::Function::WelchWindowFunction<4> WelchWindowFunction; typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4,WelchWindowFunction> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); _pResizeFilter->SetInterpolator(sinc_interpolator); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } /// Build a derived file name from moving images e.g. xxx_T2.nrrd becomes xxx_GTV.nrrd static FileListType CreateDerivedFileList(std::string baseFN, std::string baseSuffix, std::vector derivedPatterns) { FileListType files; for (unsigned int i=0; i < derivedPatterns.size(); i++) { std::string derResourceSuffix = derivedPatterns.at(i); std::string derivedResourceFilename = baseFN.substr(0,baseFN.length() -baseSuffix.length()) + derResourceSuffix; MITK_INFO <<" Looking for file: " << derivedResourceFilename; if (!itksys::SystemTools::FileExists(derivedResourceFilename.c_str())) { MITK_INFO << "CreateDerivedFileList: File does not exit. Skipping entry."; continue; } files.push_back(derivedResourceFilename); } return files; } /// Copy derived resources from first time step. Append _reg tag, but leave data untouched. static void CopyResources(FileListType fileList, std::string outputPath) { for (unsigned int j=0; j < fileList.size(); j++) { std::string derivedResourceFilename = fileList.at(j); std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(derivedResourceFilename); std::string savePathAndFileName = outputPath +fileStem + "." + fileType; MITK_INFO << "Copy resource " << savePathAndFileName; mitk::Image::Pointer resImage = ExtractFirstTS(mitk::IOUtil::Load(derivedResourceFilename), fileType); mitk::IOUtil::Save(resImage, savePathAndFileName); } } int main( int argc, char* argv[] ) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setArgumentPrefix("--","-"); parser.setTitle("Folder Registration"); parser.setCategory("Preprocessing Tools"); parser.setDescription("For detail description see http://docs.mitk.org/nightly/DiffusionMiniApps.html"); parser.setContributor("MIC"); // Add command line argument names - parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help", "Show this help text"); + parser.addArgument("help", "h",mitkDiffusionCommandLineParser::Bool, "Help", "Show this help text"); //parser.addArgument("usemask", "u", QVariant::Bool, "Use segmentations (derived resources) to exclude areas from registration metrics"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "Input folder",us::Any(),false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "Output folder (ending with /)",us::Any(),false, false, false, mitkCommandLineParser::Output); - parser.addArgument("fixed", "f", mitkCommandLineParser::String, "Fixed images:", "Suffix for fixed image (if none is supplied first file matching moving pattern is chosen)",us::Any(),true); - parser.addArgument("moving", "m", mitkCommandLineParser::String, "Moving images:", "Suffix for moving images",us::Any(),false); - parser.addArgument("derived", "d", mitkCommandLineParser::String, "Derived resources:", "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true); - parser.addArgument("silent", "s", mitkCommandLineParser::Bool, "Silent:", "No xml progress output."); - parser.addArgument("resample", "r", mitkCommandLineParser::String, "Resample (x,y,z)mm:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); - parser.addArgument("binary", "b", mitkCommandLineParser::Bool, "Binary:", "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any()); - parser.addArgument("correct-origin", "c", mitkCommandLineParser::Bool, "Origin correction:", "Correct for large origin displacement. Use switch when you reveive: Joint PDF summed to zero ",us::Any()); - parser.addArgument("sinc-int", "s", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "Input folder",us::Any(),false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "Output folder (ending with /)",us::Any(),false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("fixed", "f", mitkDiffusionCommandLineParser::String, "Fixed images:", "Suffix for fixed image (if none is supplied first file matching moving pattern is chosen)",us::Any(),true); + parser.addArgument("moving", "m", mitkDiffusionCommandLineParser::String, "Moving images:", "Suffix for moving images",us::Any(),false); + parser.addArgument("derived", "d", mitkDiffusionCommandLineParser::String, "Derived resources:", "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true); + parser.addArgument("silent", "s", mitkDiffusionCommandLineParser::Bool, "Silent:", "No xml progress output."); + parser.addArgument("resample", "r", mitkDiffusionCommandLineParser::String, "Resample (x,y,z)mm:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); + parser.addArgument("binary", "b", mitkDiffusionCommandLineParser::Bool, "Binary:", "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any()); + parser.addArgument("correct-origin", "c", mitkDiffusionCommandLineParser::Bool, "Origin correction:", "Correct for large origin displacement. Use switch when you reveive: Joint PDF summed to zero ",us::Any()); + parser.addArgument("sinc-int", "s", mitkDiffusionCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool silent = false; bool isBinary = false; bool alignOrigin = false; { if (parsedArgs.size() == 0) { return EXIT_FAILURE; } if (parsedArgs.count("silent")) silent = true; if (parsedArgs.count("binary")) isBinary = true; if (parsedArgs.count("correct-origin")) alignOrigin = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string refPattern = ""; bool useFirstMoving = false; std::string movingImgPattern = us::any_cast(parsedArgs["moving"]); if (parsedArgs.count("fixed")) { refPattern = us::any_cast(parsedArgs["fixed"]); } else { useFirstMoving = true; refPattern = movingImgPattern; } std::string outputPath = us::any_cast(parsedArgs["o"]); std::string inputPath = us::any_cast(parsedArgs["i"]); //QString resampleReference = parsedArgs["resample"].toString(); //bool maskTumor = parsedArgs["usemask"].toBool(); // if derived sources pattern is provided, populate QStringList with possible filename postfixes std::vector derPatterns; if (parsedArgs.count("derived") || parsedArgs.count("d") ) { std::string arg = us::any_cast(parsedArgs["derived"]); derPatterns = split(arg ,','); } std::vector spacings; float spacing[] = { 0.0f, 0.0f, 0.0f }; bool doResampling = false; if (parsedArgs.count("resample") || parsedArgs.count("d") ) { std::string arg = us::any_cast(parsedArgs["resample"]); spacings = split(arg ,','); spacing[0] = atoi(spacings.at(0).c_str()); spacing[1] = atoi(spacings.at(1).c_str()); spacing[2] = atoi(spacings.at(2).c_str()); doResampling = true; } MITK_INFO << "Input Folder : " << inputPath; MITK_INFO << "Looking for reference image ..."; FileListType referenceFileList = CreateFileList(inputPath,refPattern); if ((!useFirstMoving && referenceFileList.size() != 1) || (useFirstMoving && referenceFileList.size() == 0)) { MITK_ERROR << "None or more than one possible reference images (" << refPattern <<") found. Exiting." << referenceFileList.size(); MITK_INFO << "Choose a fixed arguement that is unique in the given folder!"; return EXIT_FAILURE; } std::string referenceFileName = referenceFileList.at(0); MITK_INFO << "Loading Reference (fixed) image: " << referenceFileName; std::string fileType = itksys::SystemTools::GetFilenameExtension(referenceFileName); mitk::Image::Pointer refImage = ExtractFirstTS(mitk::IOUtil::Load(referenceFileName), fileType); mitk::Image::Pointer resampleReference = nullptr; if (doResampling) { refImage = ResampleBySpacing(refImage,spacing); resampleReference = refImage; } if (refImage.IsNull()) MITK_ERROR << "Loaded fixed image is nullptr"; // Copy reference image to destination std::string savePathAndFileName = GetSavePath(outputPath, referenceFileName); mitk::IOUtil::Save(refImage, savePathAndFileName); // Copy all derived resources also to output folder, adding _reg suffix referenceFileList = CreateDerivedFileList(referenceFileName, movingImgPattern,derPatterns); CopyResources(referenceFileList, outputPath); std::string derivedResourceFilename; mitk::Image::Pointer referenceMask = nullptr; // union of all segmentations if (!silent) { // XML Output to report progress std::cout << ""; std::cout << "Batched Registration"; std::cout << "Starting registration ... "; std::cout << ""; } // Now iterate over all files and register them to the reference image, // also register derived resources based on file patterns // ------------------------------------------------------------------------------ // Create File list FileListType movingImagesList = CreateFileList(inputPath, movingImgPattern); for (unsigned int i =0; i < movingImagesList.size(); i++) { std::string fileMorphName = movingImagesList.at(i); if (fileMorphName == referenceFileName) { // do not process reference image again continue; } MITK_INFO << "Processing image " << fileMorphName; // 1 Register morphological file to reference image if (!itksys::SystemTools::FileExists(fileMorphName.c_str())) { MITK_WARN << "File does not exit. Skipping entry."; continue; } // Origin of images is cancelled // TODO make this optional!! double transf[6]; double offset[3]; { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileMorphName); mitk::Image::Pointer movingImage = ExtractFirstTS(mitk::IOUtil::Load(fileMorphName), fileType); if (movingImage.IsNull()) MITK_ERROR << "Loaded moving image is nullptr"; // Store transformation, apply it to morph file MITK_INFO << "----------Registering moving image to reference----------"; mitk::RegistrationWrapper::GetTransformation(refImage, movingImage, transf, offset, alignOrigin, referenceMask); mitk::RegistrationWrapper::ApplyTransformationToImage(movingImage, transf,offset, resampleReference); // , resampleImage savePathAndFileName = GetSavePath(outputPath, fileMorphName); if (fileType == ".dwi") fileType = "dwi"; { mitk::ImageReadAccessor readAccess(movingImage); if (readAccess.GetData() == nullptr) MITK_INFO <<"POST DATA is null"; } mitk::IOUtil::Save(movingImage, savePathAndFileName); } if (!silent) { std::cout << "."; } // Now parse all derived resource and apply the above calculated transformation to them // ------------------------------------------------------------------------------------ FileListType fList = CreateDerivedFileList(fileMorphName, movingImgPattern,derPatterns); if (fList.size() > 0) MITK_INFO << "----------DERIVED RESOURCES ---------"; for (unsigned int j=0; j < fList.size(); j++) { derivedResourceFilename = fList.at(j); MITK_INFO << "----Processing derived resorce " << derivedResourceFilename << " ..."; std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); mitk::Image::Pointer derivedMovingResource = ExtractFirstTS(mitk::IOUtil::Load(derivedResourceFilename), fileType); // Apply transformation to derived resource, treat derived resource as binary mitk::RegistrationWrapper::ApplyTransformationToImage(derivedMovingResource, transf,offset, resampleReference,isBinary); savePathAndFileName = GetSavePath(outputPath, derivedResourceFilename); mitk::IOUtil::Save(derivedMovingResource, savePathAndFileName); } } if (!silent) std::cout << ""; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/Misc/ResampleGradients.cpp b/Modules/DiffusionCmdApps/Misc/ResampleGradients.cpp index 8d53507..df67be8 100644 --- a/Modules/DiffusionCmdApps/Misc/ResampleGradients.cpp +++ b/Modules/DiffusionCmdApps/Misc/ResampleGradients.cpp @@ -1,230 +1,230 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include "itkDWIVoxelFunctor.h" #include typedef short DiffusionPixelType; typedef itk::VectorImage< short, 3 > ItkDwiType; // itk includes #include "itkTimeProbe.h" #include "itkB0ImageExtractionImageFilter.h" #include "itkB0ImageExtractionToSeparateImageFilter.h" #include "itkBrainMaskExtractionImageFilter.h" #include "itkCastImageFilter.h" #include "itkVectorContainer.h" #include #include #include #include #include #include // Multishell includes #include // Multishell Functors #include #include #include #include // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" //#include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include #include #include #include #include //#include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkPreferenceListReaderOptionsFunctor.h" mitk::Image::Pointer DoReduceGradientDirections(mitk::Image::Pointer image, double BValue, unsigned int numOfGradientsToKeep, bool use_first_n) { bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( !isDiffusionImage ) { std::cout << "Image is not a Diffusion Weighted Image" << std::endl; //return; } typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; typedef mitk::BValueMapProperty::BValueMap BValueMap; BValueMap shellSlectionMap; BValueMap originalShellMap = mitk::DiffusionPropertyHelper::GetBValueMap(image); std::vector newNumGradientDirections; //Keeps 1 b0 gradient double B0Value = 0; shellSlectionMap[B0Value] = originalShellMap[B0Value]; unsigned int num = 1; newNumGradientDirections.push_back(num); //BValue = 1000; shellSlectionMap[BValue] = originalShellMap[BValue]; //numOfGradientsToKeep = 32; newNumGradientDirections.push_back(numOfGradientsToKeep); if (newNumGradientDirections.empty()) { std::cout << "newNumGradientDirections is empty" << std::endl; //return; } auto gradientContainer = mitk::DiffusionPropertyHelper::GetGradientContainer(image); ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); mitk::CastToItkImage(image, itkVectorImagePointer); std::cout << "1" << std::endl; FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkVectorImagePointer ); filter->SetOriginalGradientDirections(gradientContainer); filter->SetNumGradientDirections(newNumGradientDirections); filter->SetOriginalBValueMap(originalShellMap); filter->SetShellSelectionBValueMap(shellSlectionMap); filter->SetUseFirstN(use_first_n); filter->Update(); std::cout << "2" << std::endl; if( filter->GetOutput() == nullptr) { std::cout << "filter get output is nullptr" << std::endl; } mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( filter->GetOutput() ); mitk::DiffusionPropertyHelper::CopyProperties(image, newImage, true); mitk::DiffusionPropertyHelper::SetGradientContainer(newImage, filter->GetGradientDirections()); mitk::DiffusionPropertyHelper::InitializeImage( newImage ); return newImage; } /*! \brief Resample gradients of input DWI image. */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Resample Gradients"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Resample gradients of input DWI image. You can select one b-value shell and the number of gradients within this shell you want to have. It will also keep one b0 image."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false); - parser.addArgument("b_value", "", mitkCommandLineParser::Float, "b-value:", "float", 1000, false); - parser.addArgument("num_gradients", "", mitkCommandLineParser::Int, "Nr of gradients:", "integer", 32, false); - parser.addArgument("use_first_n", "", mitkCommandLineParser::Bool, "Use first N:", "no optimization, simply use first n gradients", 0); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image", us::Any(), false); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false); + parser.addArgument("b_value", "", mitkDiffusionCommandLineParser::Float, "b-value:", "float", 1000, false); + parser.addArgument("num_gradients", "", mitkDiffusionCommandLineParser::Int, "Nr of gradients:", "integer", 32, false); + parser.addArgument("use_first_n", "", mitkDiffusionCommandLineParser::Bool, "Use first N:", "no optimization, simply use first n gradients", 0); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["i"]); std::string outFileName = us::any_cast(parsedArgs["o"]); double bValue = us::any_cast(parsedArgs["b_value"]); unsigned int nrOfGradients = us::any_cast(parsedArgs["num_gradients"]); bool use_first_n = false; if (parsedArgs.count("use_first_n")) use_first_n = true; try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({ "Diffusion Weighted Images" }, {}); mitk::Image::Pointer mitkImage = mitk::IOUtil::Load(inFileName, &functor); mitk::Image::Pointer newImage = DoReduceGradientDirections(mitkImage, bValue, nrOfGradients, use_first_n); //mitk::IOUtil::Save(newImage, outFileName); //save as dwi image mitk::IOUtil::Save(newImage, "DWI_NIFTI", outFileName); //save as nifti 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/Misc/RoundBvalues.cpp b/Modules/DiffusionCmdApps/Misc/RoundBvalues.cpp index c7170b9..d6de80f 100644 --- a/Modules/DiffusionCmdApps/Misc/RoundBvalues.cpp +++ b/Modules/DiffusionCmdApps/Misc/RoundBvalues.cpp @@ -1,106 +1,106 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("RoundBvalues"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Round b-values"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("to_nearest", "", mitkCommandLineParser::Int, "To nearest:", "integer", 1000); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("to_nearest", "", mitkDiffusionCommandLineParser::Int, "To nearest:", "integer", 1000); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["i"]); std::string outImage = us::any_cast(parsedArgs["o"]); int to_nearest = 1000; if (parsedArgs.count("to_nearest")) to_nearest = us::any_cast(parsedArgs["to_nearest"]); try { typedef mitk::DiffusionPropertyHelper PropHelper; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer in_image = mitk::IOUtil::Load(imageName, &functor); if (!PropHelper::IsDiffusionWeightedImage(in_image)) { mitkThrow() << "Input is not a diffusion weighted image: " << imageName; } typedef itk::DwiGradientLengthCorrectionFilter FilterType; auto itkVectorImagePointer = PropHelper::GetItkVectorImage(in_image); FilterType::Pointer filter = FilterType::New(); filter->SetRoundingValue(to_nearest); filter->SetReferenceBValue(PropHelper::GetReferenceBValue(in_image)); filter->SetReferenceGradientDirectionContainer(PropHelper::GetGradientContainer(in_image)); filter->Update(); mitk::Image::Pointer newImage = mitk::Image::New(); newImage->InitializeByItk( itkVectorImagePointer.GetPointer() ); newImage->SetImportVolume( itkVectorImagePointer->GetBufferPointer(), 0, 0, mitk::Image::CopyMemory); itkVectorImagePointer->GetPixelContainer()->ContainerManageMemoryOff(); PropHelper::CopyProperties(in_image, newImage, true); PropHelper::SetReferenceBValue(newImage, filter->GetNewBValue()); PropHelper::SetGradientContainer(newImage, filter->GetOutputGradientDirectionContainer()); PropHelper::InitializeImage(newImage); std::string ext = itksys::SystemTools::GetFilenameExtension(outImage); if (ext==".nii" || ext==".nii.gz") mitk::IOUtil::Save(newImage, "DWI_NIFTI", outImage); else mitk::IOUtil::Save(newImage, outImage); } 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/Misc/ShToOdfImage.cpp b/Modules/DiffusionCmdApps/Misc/ShToOdfImage.cpp index 55b2301..18cab79 100644 --- a/Modules/DiffusionCmdApps/Misc/ShToOdfImage.cpp +++ b/Modules/DiffusionCmdApps/Misc/ShToOdfImage.cpp @@ -1,72 +1,72 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("ShToOdfImage"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Calculate discrete ODF image from SH coefficient image"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["i"]); std::string outImage = us::any_cast(parsedArgs["o"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"SH Image"}, {}); mitk::ShImage::Pointer source = mitk::IOUtil::Load(imageName, &functor); mitk::Image::Pointer mitkImage = dynamic_cast(source.GetPointer()); mitk::OdfImage::Pointer out_image = mitk::convert::GetOdfFromShImage(mitkImage); if (out_image.IsNotNull()) mitk::IOUtil::Save(out_image, outImage); } 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/Python/BrainExtraction.cpp b/Modules/DiffusionCmdApps/Python/BrainExtraction.cpp index 093820c..127fdf8 100644 --- a/Modules/DiffusionCmdApps/Python/BrainExtraction.cpp +++ b/Modules/DiffusionCmdApps/Python/BrainExtraction.cpp @@ -1,179 +1,179 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include #include typedef mitk::DiffusionPropertyHelper DPH; typedef itksys::SystemTools ist; std::string GetPythonFile(std::string filename, std::string exec_dir) { std::string out = ""; for (auto dir : mitk::bet::relative_search_dirs) { if ( ist::FileExists( exec_dir + dir + filename) ) { out = exec_dir + dir + filename; return out; } if ( ist::FileExists( ist::GetCurrentWorkingDirectory() + dir + filename) ) { out = ist::GetCurrentWorkingDirectory() + dir + filename; return out; } } for (auto dir : mitk::bet::absolute_search_dirs) { if ( ist::FileExists( dir + filename) ) { out = dir + filename; return out; } } return out; } int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("BrainExtraction"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Performs brain extraction using a deep learning model"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string i = us::any_cast(parsedArgs["i"]); std::string o = us::any_cast(parsedArgs["o"]); std::string exec_dir = ist::GetFilenamePath(argv[0]); mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer mitk_image = mitk::IOUtil::Load(i, &functor); bool missing_file = false; std::string missing_file_string = ""; if ( GetPythonFile("run_mitk.py", exec_dir).empty() ) { missing_file_string += "Brain extraction script file missing: run_mitk.py\n\n"; missing_file = true; } if ( GetPythonFile("model_final.model", exec_dir).empty() ) { missing_file_string += "Brain extraction model file missing: model_final.model\n\n"; missing_file = true; } if ( GetPythonFile("basic_config_just_like_braintumor.py", exec_dir).empty() ) { missing_file_string += "Config file missing: basic_config_just_like_braintumor.py\n\n"; missing_file = true; } if (missing_file) { mitkThrow() << missing_file_string; } us::ModuleContext* context = us::GetModuleContext(); us::ServiceReference m_PythonServiceRef = context->GetServiceReference(); mitk::IPythonService* m_PythonService = dynamic_cast ( context->GetService(m_PythonServiceRef) ); mitk::IPythonService::ForceLoadModule(); m_PythonService->AddAbsoluteSearchDirs(mitk::bet::absolute_search_dirs); m_PythonService->AddRelativeSearchDirs(mitk::bet::relative_search_dirs); m_PythonService->Execute("paths=[]"); // set input files (model and config) m_PythonService->Execute("model_file=\""+GetPythonFile("model_final.model", exec_dir)+"\""); m_PythonService->Execute("config_file=\""+GetPythonFile("basic_config_just_like_braintumor.py", exec_dir)+"\""); // copy input image to python m_PythonService->CopyToPythonAsSimpleItkImage( mitk_image, "in_image"); // run segmentation script m_PythonService->ExecuteScript( GetPythonFile("run_mitk.py", exec_dir) ); // clean up after running script (better way than deleting individual variables?) if(m_PythonService->DoesVariableExist("in_image")) m_PythonService->Execute("del in_image"); // check for errors if(!m_PythonService->GetVariable("error_string").empty()) mitkThrow() << m_PythonService->GetVariable("error_string"); // get output images and add to datastorage std::string output_variables = m_PythonService->GetVariable("output_variables"); std::vector outputs; boost::split(outputs, output_variables, boost::is_any_of(",")); std::string output_types = m_PythonService->GetVariable("output_types"); std::vector types; boost::split(types, output_types, boost::is_any_of(",")); for (unsigned int i=0; iDoesVariableExist(outputs.at(i))) { mitk::Image::Pointer image = m_PythonService->CopySimpleItkImageFromPython(outputs.at(i)); if(types.at(i)=="input" && mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(mitk_image)) { mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, image, true); mitk::DiffusionPropertyHelper::InitializeImage(image); } mitk::DataNode::Pointer corrected_node = mitk::DataNode::New(); corrected_node->SetData( image ); std::string name = o + "_"; name += outputs.at(i); if(types.at(i)=="input" && mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(mitk_image)) mitk::IOUtil::Save(image, "DWI_NIFTI", name+".nii.gz"); else mitk::IOUtil::Save(image, name+".nii.gz"); } } MITK_INFO << "Finished brain extraction"; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/Quantification/DiffusionIndices.cpp b/Modules/DiffusionCmdApps/Quantification/DiffusionIndices.cpp index 600874d..e3a13f6 100644 --- a/Modules/DiffusionCmdApps/Quantification/DiffusionIndices.cpp +++ b/Modules/DiffusionCmdApps/Quantification/DiffusionIndices.cpp @@ -1,193 +1,193 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include #include /** * */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Diffusion Indices"); parser.setCategory("Diffusion Related Measures"); parser.setDescription("Computes requested diffusion related measures"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image (tensor, ODF or SH-coefficient image)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("index", "idx", mitkCommandLineParser::String, "Index:", "index (fa, gfa, ra, ad, rd, ca, l2, l3, md, adc)", us::Any(), false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image (tensor, ODF or SH-coefficient image)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("index", "idx", mitkDiffusionCommandLineParser::String, "Index:", "index (fa, gfa, ra, ad, rd, ca, l2, l3, md, adc)", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["i"]); std::string index = us::any_cast(parsedArgs["index"]); std::string outFileName = us::any_cast(parsedArgs["o"]); std::string ext = itksys::SystemTools::GetFilenameLastExtension(outFileName); if (ext.empty()) outFileName += ".nii.gz"; try { // load input image mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images", "SH Image", "ODF Image", "Tensor Image"}, {}); auto input = mitk::IOUtil::Load(inFileName, &functor); bool is_odf = (dynamic_cast(input.GetPointer()) || dynamic_cast(input.GetPointer())); bool is_dt = dynamic_cast(input.GetPointer()); bool is_dw = mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(input); if (is_odf) MITK_INFO << "Input is ODF image"; else if (is_dt) MITK_INFO << "Input is tensor image"; else if (is_dw) MITK_INFO << "Input is dMRI"; else { MITK_WARN << "Input is no ODF, SH, tensor or raw dMRI."; return EXIT_FAILURE; } mitk::LocaleSwitch localeSwitch("C"); if( is_odf && index=="gfa" ) { typedef itk::Vector OdfVectorType; typedef itk::Image OdfVectorImgType; OdfVectorImgType::Pointer itkvol; if (dynamic_cast(input.GetPointer())) itkvol = mitk::convert::GetItkOdfFromShImage(input); else itkvol = mitk::convert::GetItkOdfFromOdfImage(input); typedef itk::DiffusionOdfGeneralizedFaImageFilter GfaFilterType; GfaFilterType::Pointer gfaFilter = GfaFilterType::New(); gfaFilter->SetInput(itkvol); gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD); gfaFilter->Update(); itk::ImageFileWriter< itk::Image >::Pointer fileWriter = itk::ImageFileWriter< itk::Image >::New(); fileWriter->SetInput(gfaFilter->GetOutput()); fileWriter->SetFileName(outFileName); fileWriter->Update(); } else if( is_dt ) { typedef itk::Image< itk::DiffusionTensor3D, 3 > ItkTensorImage; mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast(input.GetPointer()); ItkTensorImage::Pointer itk_dti = ItkTensorImage::New(); mitk::CastToItkImage(mitkTensorImage, itk_dti); typedef itk::TensorDerivedMeasurementsFilter MeasurementsType; MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itk_dti.GetPointer() ); if(index=="fa") measurementsCalculator->SetMeasure(MeasurementsType::FA); else if(index=="ra") measurementsCalculator->SetMeasure(MeasurementsType::RA); else if(index=="ad") measurementsCalculator->SetMeasure(MeasurementsType::AD); else if(index=="rd") measurementsCalculator->SetMeasure(MeasurementsType::RD); else if(index=="ca") measurementsCalculator->SetMeasure(MeasurementsType::CA); else if(index=="l2") measurementsCalculator->SetMeasure(MeasurementsType::L2); else if(index=="l3") measurementsCalculator->SetMeasure(MeasurementsType::L3); else if(index=="md") measurementsCalculator->SetMeasure(MeasurementsType::MD); else { MITK_WARN << "No valid diffusion index for input image (tensor image) defined"; return EXIT_FAILURE; } measurementsCalculator->Update(); itk::ImageFileWriter< itk::Image >::Pointer fileWriter = itk::ImageFileWriter< itk::Image >::New(); fileWriter->SetInput(measurementsCalculator->GetOutput()); fileWriter->SetFileName(outFileName); fileWriter->Update(); } else if(is_dw && (index=="adc" || index=="md")) { typedef itk::AdcImageFilter< short, double > FilterType; auto itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(input); FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkVectorImagePointer ); filter->SetGradientDirections( mitk::DiffusionPropertyHelper::GetGradientContainer(input) ); filter->SetB_value( static_cast(mitk::DiffusionPropertyHelper::GetReferenceBValue(input)) ); if (index=="adc") filter->SetFitSignal(true); else filter->SetFitSignal(false); filter->Update(); itk::ImageFileWriter< itk::Image >::Pointer fileWriter = itk::ImageFileWriter< itk::Image >::New(); fileWriter->SetInput(filter->GetOutput()); fileWriter->SetFileName(outFileName); fileWriter->Update(); } else std::cout << "Diffusion index " << index << " not supported for supplied file type."; } 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/DiffusionKurtosisFit.cpp b/Modules/DiffusionCmdApps/Quantification/DiffusionKurtosisFit.cpp index d2aa6cb..fb5f5fa 100644 --- a/Modules/DiffusionCmdApps/Quantification/DiffusionKurtosisFit.cpp +++ b/Modules/DiffusionCmdApps/Quantification/DiffusionKurtosisFit.cpp @@ -1,254 +1,254 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include "mitkImage.h" #include #include #include #include "mitkIOUtil.h" #include #include //vnl_includes #include "vnl/vnl_math.h" #include "vnl/vnl_cost_function.h" #include "vnl/vnl_least_squares_function.h" #include "vnl/algo/vnl_lbfgsb.h" #include "vnl/algo/vnl_lbfgs.h" #include "vnl/algo/vnl_levenberg_marquardt.h" typedef mitk::DiffusionPropertyHelper DPH; #include #include #include #include #include #include #include DPH::ImageType::Pointer GetBlurredVectorImage( DPH::ImageType::Pointer vectorImage, double sigma) { typedef itk::DiscreteGaussianImageFilter< itk::Image, itk::Image > GaussianFilterType; typedef itk::VectorIndexSelectionCastImageFilter< DPH::ImageType, itk::Image > IndexSelectionType; IndexSelectionType::Pointer indexSelectionFilter = IndexSelectionType::New(); indexSelectionFilter->SetInput( vectorImage ); typedef itk::ComposeImageFilter< itk::Image, DPH::ImageType > ComposeFilterType; ComposeFilterType::Pointer vec_composer = ComposeFilterType::New(); for( unsigned int i=0; iGetVectorLength(); ++i) { GaussianFilterType::Pointer gaussian_filter = GaussianFilterType::New(); indexSelectionFilter->SetIndex( i ); gaussian_filter->SetInput( indexSelectionFilter->GetOutput() ); gaussian_filter->SetVariance( sigma ); vec_composer->SetInput(i, gaussian_filter->GetOutput() ); gaussian_filter->Update(); } try { vec_composer->Update(); } catch(const itk::ExceptionObject &e) { mitkThrow() << "[VectorImage.GaussianSmoothing] !! Failed with ITK Exception: " << e.what(); } DPH::ImageType::Pointer smoothed_vector = vec_composer->GetOutput(); /* itk::ImageFileWriter< DPH::ImageType >::Pointer writer = itk::ImageFileWriter< DPH::ImageType >::New(); writer->SetInput( smoothed_vector ); writer->SetFileName( "/tmp/itk_smoothed_vector.nrrd"); writer->Update();*/ return smoothed_vector; } void KurtosisMapComputation( mitk::Image::Pointer input, std::string output_prefix , std::string output_type, std::string maskPath, bool omitBZero, double lower, double upper ) { DPH::ImageType::Pointer vectorImage = DPH::ImageType::New(); mitk::CastToItkImage( input, vectorImage ); typedef itk::DiffusionKurtosisReconstructionImageFilter< short, double > KurtosisFilterType; KurtosisFilterType::Pointer kurtosis_filter = KurtosisFilterType::New(); kurtosis_filter->SetInput( GetBlurredVectorImage( vectorImage, 1.5 ) ); kurtosis_filter->SetReferenceBValue( DPH::GetReferenceBValue( input.GetPointer() ) ); kurtosis_filter->SetGradientDirections( DPH::GetGradientContainer( input.GetPointer() ) ); // kurtosis_filter->SetNumberOfThreads(1); kurtosis_filter->SetOmitUnweightedValue(omitBZero); kurtosis_filter->SetBoundariesForKurtosis(-lower,upper); // kurtosis_filter->SetInitialSolution(const vnl_vector& x0 ); if(maskPath != "") { mitk::Image::Pointer segmentation; segmentation = mitk::IOUtil::Load(maskPath); typedef itk::Image< short , 3> MaskImageType; MaskImageType::Pointer vectorSeg = MaskImageType::New() ; mitk::CastToItkImage( segmentation, vectorSeg ); kurtosis_filter->SetImageMask(vectorSeg) ; } try { kurtosis_filter->Update(); } catch( const itk::ExceptionObject& e) { mitkThrow() << "Kurtosis fit failed with an ITK Exception: " << e.what(); } mitk::Image::Pointer d_image = mitk::Image::New(); d_image->InitializeByItk( kurtosis_filter->GetOutput(0) ); d_image->SetVolume( kurtosis_filter->GetOutput(0)->GetBufferPointer() ); mitk::Image::Pointer k_image = mitk::Image::New(); k_image->InitializeByItk( kurtosis_filter->GetOutput(1) ); k_image->SetVolume( kurtosis_filter->GetOutput(1)->GetBufferPointer() ); std::string outputD_FileName = output_prefix + "_ADC_map." + output_type; std::string outputK_FileName = output_prefix + "_AKC_map." + output_type; try { mitk::IOUtil::Save( d_image, outputD_FileName ); mitk::IOUtil::Save( k_image, outputK_FileName ); } catch( const itk::ExceptionObject& e) { mitkThrow() << "Failed to save the KurtosisFit Results due to exception: " << e.what(); } } int main( int argc, char* argv[] ) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Diffusion Kurtosis Fit"); parser.setCategory("Diffusion Related Measures"); parser.setContributor("MIC"); parser.setDescription("Fitting Kurtosis"); parser.setArgumentPrefix("--","-"); // mandatory arguments - parser.addArgument("", "i", mitkCommandLineParser::String, "Input: ", "input image (DWI)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output Preifx: ", "Prefix for the output images, will append _f, _K, _D accordingly ", us::Any(), false); - parser.addArgument("output_type", "", mitkCommandLineParser::String, "Output Type: ", "choose data type of output image, e.g. '.nii' or '.nrrd' ", us::Any(), false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input: ", "input image (DWI)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output Preifx: ", "Prefix for the output images, will append _f, _K, _D accordingly ", us::Any(), false); + parser.addArgument("output_type", "", mitkDiffusionCommandLineParser::String, "Output Type: ", "choose data type of output image, e.g. '.nii' or '.nrrd' ", us::Any(), false); // optional arguments - parser.addArgument("mask", "m", mitkCommandLineParser::String, "Masking Image: ", "ROI (segmentation)", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help", "Show this help text"); - parser.addArgument("omitbzero", "om", mitkCommandLineParser::Bool, "Omit b0:", "Omit b0 value during fit (default = false)", us::Any()); - parser.addArgument("lowerkbound", "kl", mitkCommandLineParser::Float, "lower Kbound:", "Set (unsigned) lower boundary for Kurtosis parameter (default = -1000)", us::Any()); - parser.addArgument("upperkbound", "ku", mitkCommandLineParser::Float, "upper Kbound:", "Set upper boundary for Kurtosis parameter (default = 1000)", us::Any()); + parser.addArgument("mask", "m", mitkDiffusionCommandLineParser::String, "Masking Image: ", "ROI (segmentation)", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("help", "h", mitkDiffusionCommandLineParser::Bool, "Help", "Show this help text"); + parser.addArgument("omitbzero", "om", mitkDiffusionCommandLineParser::Bool, "Omit b0:", "Omit b0 value during fit (default = false)", us::Any()); + parser.addArgument("lowerkbound", "kl", mitkDiffusionCommandLineParser::Float, "lower Kbound:", "Set (unsigned) lower boundary for Kurtosis parameter (default = -1000)", us::Any()); + parser.addArgument("upperkbound", "ku", mitkDiffusionCommandLineParser::Float, "upper Kbound:", "Set upper boundary for Kurtosis parameter (default = 1000)", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")){ std::cout << parser.helpText(); return EXIT_SUCCESS; } // mandatory arguments std::string inFileName = us::any_cast(parsedArgs["input"]); std::string out_prefix = us::any_cast(parsedArgs["output"]); std::string maskPath = ""; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer inputImage = mitk::IOUtil::Load(inFileName, &functor); bool omitBZero = false; double lower = -1000; double upper = 1000; std::string out_type = "nrrd"; if (parsedArgs.count("mask") || parsedArgs.count("m")) { maskPath = us::any_cast(parsedArgs["mask"]); } if (parsedArgs.count("output_type") || parsedArgs.count("ot")) { out_type = us::any_cast(parsedArgs["output_type"]); } if (parsedArgs.count("omitbzero") || parsedArgs.count("om")) { omitBZero = us::any_cast(parsedArgs["omitbzero"]); } if (parsedArgs.count("lowerkbound") || parsedArgs.count("kl")) { lower = us::any_cast(parsedArgs["lowerkbound"]); } if (parsedArgs.count("upperkbound") || parsedArgs.count("ku")) { upper = us::any_cast(parsedArgs["upperkbound"]); } if( !DPH::IsDiffusionWeightedImage( inputImage ) ) { MITK_ERROR("DiffusionIVIMFit.Input") << "No valid diffusion-weighted image provided, failed to load " << inFileName << " as DW Image. Aborting..."; return EXIT_FAILURE; } KurtosisMapComputation( inputImage, out_prefix , out_type, maskPath, omitBZero, lower, upper); } diff --git a/Modules/DiffusionCmdApps/Quantification/MultishellMethods.cpp b/Modules/DiffusionCmdApps/Quantification/MultishellMethods.cpp index 63eb7ec..b7de557 100644 --- a/Modules/DiffusionCmdApps/Quantification/MultishellMethods.cpp +++ b/Modules/DiffusionCmdApps/Quantification/MultishellMethods.cpp @@ -1,215 +1,215 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Multishell Methods"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input file", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output file", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("adc", "D", mitkCommandLineParser::Bool, "ADC:", "ADC Average", us::Any(), false); - parser.addArgument("akc", "K", mitkCommandLineParser::Bool, "Kurtosis fit:", "Kurtosis Fit", us::Any(), false); - parser.addArgument("biexp", "B", mitkCommandLineParser::Bool, "BiExp fit:", "BiExp fit", us::Any(), false); - parser.addArgument("targetbvalue", "b", mitkCommandLineParser::String, "b Value:", "target bValue (mean, min, max)", us::Any(), false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input file", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output file", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("adc", "D", mitkDiffusionCommandLineParser::Bool, "ADC:", "ADC Average", us::Any(), false); + parser.addArgument("akc", "K", mitkDiffusionCommandLineParser::Bool, "Kurtosis fit:", "Kurtosis Fit", us::Any(), false); + parser.addArgument("biexp", "B", mitkDiffusionCommandLineParser::Bool, "BiExp fit:", "BiExp fit", us::Any(), false); + parser.addArgument("targetbvalue", "b", mitkDiffusionCommandLineParser::String, "b Value:", "target bValue (mean, min, max)", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string inName = us::any_cast(parsedArgs["i"]); std::string outName = us::any_cast(parsedArgs["o"]); bool applyADC = us::any_cast(parsedArgs["adc"]); bool applyAKC = us::any_cast(parsedArgs["akc"]); bool applyBiExp = us::any_cast(parsedArgs["biexp"]); std::string targetType = us::any_cast(parsedArgs["targetbvalue"]); try { std::cout << "Loading " << inName; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer dwi = mitk::IOUtil::Load(inName, &functor); if ( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dwi ) ) { typedef itk::RadialMultishellToSingleshellImageFilter FilterType; typedef itk::DwiGradientLengthCorrectionFilter CorrectionFilterType; CorrectionFilterType::Pointer roundfilter = CorrectionFilterType::New(); roundfilter->SetRoundingValue( 1000 ); roundfilter->SetReferenceBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi )); roundfilter->SetReferenceGradientDirectionContainer(mitk::DiffusionPropertyHelper::GetGradientContainer(dwi)); roundfilter->Update(); mitk::DiffusionPropertyHelper::SetReferenceBValue(dwi, roundfilter->GetNewBValue()); mitk::DiffusionPropertyHelper::SetGradientContainer(dwi, roundfilter->GetOutputGradientDirectionContainer()); // filter input parameter const mitk::DiffusionPropertyHelper::BValueMapType &originalShellMap = mitk::DiffusionPropertyHelper::GetBValueMap(dwi); mitk::DiffusionPropertyHelper::ImageType::Pointer vectorImage = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, vectorImage); const mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradientContainer = mitk::DiffusionPropertyHelper::GetGradientContainer(dwi); const unsigned int &bValue = mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi ); // filter call vnl_vector bValueList(originalShellMap.size()-1); double targetBValue = bValueList.mean(); mitk::DiffusionPropertyHelper::BValueMapType::const_iterator it = originalShellMap.begin(); ++it; int i = 0 ; for(; it != originalShellMap.end(); ++it) bValueList.put(i++,it->first); if( targetType == "mean" ) targetBValue = bValueList.mean(); else if( targetType == "min" ) targetBValue = bValueList.min_value(); else if( targetType == "max" ) targetBValue = bValueList.max_value(); if(applyADC) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); mitk::DiffusionPropertyHelper::SetReferenceBValue(outImage, targetBValue); mitk::DiffusionPropertyHelper::SetGradientContainer(outImage, filter->GetTargetGradientDirections()); mitk::DiffusionPropertyHelper::InitializeImage( outImage ); mitk::IOUtil::Save(outImage, (outName + "_ADC.dwi").c_str()); } if(applyAKC) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); mitk::DiffusionPropertyHelper::SetReferenceBValue(outImage, targetBValue); mitk::DiffusionPropertyHelper::SetGradientContainer(outImage, filter->GetTargetGradientDirections()); mitk::DiffusionPropertyHelper::InitializeImage( outImage ); mitk::IOUtil::Save(outImage, (std::string(outName) + "_AKC.dwi").c_str()); } if(applyBiExp) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); mitk::DiffusionPropertyHelper::SetReferenceBValue(outImage, targetBValue); mitk::DiffusionPropertyHelper::SetGradientContainer(outImage, filter->GetTargetGradientDirections()); mitk::DiffusionPropertyHelper::InitializeImage( outImage ); mitk::IOUtil::Save(outImage, (std::string(outName) + "_BiExp.dwi").c_str()); } } } 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/QballReconstruction.cpp b/Modules/DiffusionCmdApps/Quantification/QballReconstruction.cpp index 6635eb7..3268965 100644 --- a/Modules/DiffusionCmdApps/Quantification/QballReconstruction.cpp +++ b/Modules/DiffusionCmdApps/Quantification/QballReconstruction.cpp @@ -1,266 +1,266 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include "mitkImage.h" #include "itkAnalyticalDiffusionQballReconstructionImageFilter.h" #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include template void TemplatedMultishellQBallReconstruction(float lambda, mitk::Image::Pointer dwi, bool output_sampled, int threshold, std::string outfilename) { typedef itk::DiffusionMultiShellQballReconstructionImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); auto bMap = mitk::DiffusionPropertyHelper::GetBValueMap(dwi); auto it1 = bMap.rbegin(); auto it2 = bMap.rbegin(); ++it2; // Get average distance int avdistance = 0; for(; it2 != bMap.rend(); ++it1, ++it2) avdistance += static_cast(it1->first - it2->first); avdistance /= bMap.size()-1; // Check if all shells are using the same averae distance it1 = bMap.rbegin(); it2 = bMap.rbegin(); ++it2; for(; it2 != bMap.rend(); ++it1,++it2) { if(avdistance != static_cast(it1->first - it2->first)) { mitkThrow() << "Shells are not equidistant."; } } auto itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(dwi); filter->SetBValueMap(bMap); filter->SetGradientImage(mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer, mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetThreshold(static_cast(threshold)); filter->SetLambda(static_cast(lambda)); filter->Update(); mitk::OdfImage::Pointer image = mitk::OdfImage::New(); mitk::Image::Pointer coeffsImage = dynamic_cast(mitk::ShImage::New().GetPointer()); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); std::string coeffout = outfilename; coeffout += ".nii.gz"; mitk::IOUtil::Save(coeffsImage, "SH_IMAGE", coeffout); outfilename += ".odf"; if (output_sampled) mitk::IOUtil::Save(image, outfilename); } template void TemplatedCsaQBallReconstruction(float lambda, mitk::Image::Pointer dwi, bool output_sampled, int threshold, std::string outfilename) { typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; auto itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(dwi); FilterType::Pointer filter = FilterType::New(); filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetThreshold(static_cast(threshold)); filter->SetLambda(static_cast(lambda)); // filter->SetUseMrtrixBasis(mrTrix); filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); mitk::OdfImage::Pointer image = mitk::OdfImage::New(); mitk::Image::Pointer coeffsImage = dynamic_cast(mitk::ShImage::New().GetPointer()); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); std::string coeffout = outfilename; coeffout += ".nii.gz"; mitk::IOUtil::Save(coeffsImage, "SH_IMAGE", coeffout); outfilename += ".odf"; if (output_sampled) mitk::IOUtil::Save(image, outfilename); } /** * Perform Q-ball reconstruction using a spherical harmonics basis */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input image", "input raw dwi (.dwi or .nii/.nii.gz)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output image", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("sh_order", "", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order", 4); - parser.addArgument("b0_threshold", "", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0); - parser.addArgument("round_bvalues", "", mitkCommandLineParser::Int, "Round b-values", "round to specified integer", 0); - parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda", "ragularization factor lambda", 0.006); - parser.addArgument("output_sampled", "", mitkCommandLineParser::Bool, "Output sampled ODFs", "output file containing the sampled ODFs"); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input image", "input raw dwi (.dwi or .nii/.nii.gz)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output image", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("sh_order", "", mitkDiffusionCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order", 4); + parser.addArgument("b0_threshold", "", mitkDiffusionCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0); + parser.addArgument("round_bvalues", "", mitkDiffusionCommandLineParser::Int, "Round b-values", "round to specified integer", 0); + parser.addArgument("lambda", "", mitkDiffusionCommandLineParser::Float, "Lambda", "ragularization factor lambda", 0.006); + parser.addArgument("output_sampled", "", mitkDiffusionCommandLineParser::Bool, "Output sampled ODFs", "output file containing the sampled ODFs"); parser.setCategory("Signal Modelling"); parser.setTitle("Qball Reconstruction"); parser.setDescription(""); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["i"]); std::string outfilename = us::any_cast(parsedArgs["o"]); if (itksys::SystemTools::GetFilenamePath(outfilename).size()>0) outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename); else outfilename = itksys::SystemTools::GetFilenameWithoutExtension(outfilename); int threshold = 0; if (parsedArgs.count("b0_threshold")) threshold = us::any_cast(parsedArgs["b0_threshold"]); int round_bvalues = 0; if (parsedArgs.count("round_bvalues")) round_bvalues = us::any_cast(parsedArgs["round_bvalues"]); int shOrder = 4; if (parsedArgs.count("sh_order")) shOrder = us::any_cast(parsedArgs["sh_order"]); float lambda = 0.006f; if (parsedArgs.count("lambda")) lambda = us::any_cast(parsedArgs["lambda"]); bool outCoeffs = false; if (parsedArgs.count("output_coeffs")) outCoeffs = us::any_cast(parsedArgs["output_coeffs"]); // bool mrTrix = false; // if (parsedArgs.count("mrtrix")) // mrTrix = us::any_cast(parsedArgs["mrtrix"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); std::vector< mitk::BaseData::Pointer > infile = mitk::IOUtil::Load(inFileName, &functor); mitk::Image::Pointer dwi = dynamic_cast(infile.at(0).GetPointer()); if (round_bvalues>0) { MITK_INFO << "Rounding b-values"; typedef itk::DwiGradientLengthCorrectionFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetRoundingValue(round_bvalues); filter->SetReferenceBValue(static_cast(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi))); filter->SetReferenceGradientDirectionContainer(mitk::DiffusionPropertyHelper::GetGradientContainer(dwi)); filter->Update(); mitk::DiffusionPropertyHelper::SetReferenceBValue(dwi, static_cast(filter->GetNewBValue())); mitk::DiffusionPropertyHelper::CopyProperties(dwi, dwi, true); mitk::DiffusionPropertyHelper::SetGradientContainer(dwi, filter->GetOutputGradientDirectionContainer()); mitk::DiffusionPropertyHelper::InitializeImage(dwi); } auto bMap = mitk::DiffusionPropertyHelper::GetBValueMap(dwi); if(bMap.size()!=4 && bMap.size()!=2) mitkThrow() << "Only three equidistant shells or a single shell are supported. Found " << bMap.size(); MITK_INFO << "Averaging redundant gradients"; mitk::DiffusionPropertyHelper::AverageRedundantGradients(dwi, 0.001); MITK_INFO << "SH order: " << shOrder; MITK_INFO << "lambda: " << lambda; MITK_INFO << "B0 threshold: " << threshold; MITK_INFO << "Round bvalues: " << round_bvalues; switch ( shOrder ) { case 4: { if(bMap.size()==2) TemplatedCsaQBallReconstruction<4>(lambda, dwi, outCoeffs, threshold, outfilename); else if(bMap.size()==4) TemplatedMultishellQBallReconstruction<4>(lambda, dwi, outCoeffs, threshold, outfilename); break; } case 6: { if(bMap.size()==2) TemplatedCsaQBallReconstruction<6>(lambda, dwi, outCoeffs, threshold, outfilename); else if(bMap.size()==4) TemplatedMultishellQBallReconstruction<6>(lambda, dwi, outCoeffs, threshold, outfilename); break; } case 8: { if(bMap.size()==2) TemplatedCsaQBallReconstruction<8>(lambda, dwi, outCoeffs, threshold, outfilename); else if(bMap.size()==4) TemplatedMultishellQBallReconstruction<8>(lambda, dwi, outCoeffs, threshold, outfilename); break; } case 10: { if(bMap.size()==2) TemplatedCsaQBallReconstruction<10>(lambda, dwi, outCoeffs, threshold, outfilename); else if(bMap.size()==4) TemplatedMultishellQBallReconstruction<10>(lambda, dwi, outCoeffs, threshold, outfilename); break; } case 12: { if(bMap.size()==2) TemplatedCsaQBallReconstruction<12>(lambda, dwi, outCoeffs, threshold, outfilename); else if(bMap.size()==4) TemplatedMultishellQBallReconstruction<12>(lambda, dwi, outCoeffs, threshold, outfilename); break; } default: { mitkThrow() << "SH order not supported"; } } } catch ( itk::ExceptionObject &err) { std::cout << "Exception: " << err; } catch ( std::exception err) { std::cout << "Exception: " << err.what(); } catch ( ... ) { std::cout << "Exception!"; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/Quantification/TensorReconstruction.cpp b/Modules/DiffusionCmdApps/Quantification/TensorReconstruction.cpp index 63b2668..447ad81 100644 --- a/Modules/DiffusionCmdApps/Quantification/TensorReconstruction.cpp +++ b/Modules/DiffusionCmdApps/Quantification/TensorReconstruction.cpp @@ -1,135 +1,135 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkImage.h" #include #include "mitkBaseData.h" #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include /** * Convert files from one ending to the other */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input image", "input raw dwi", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output image", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("b0_threshold", "", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0); - parser.addArgument("correct_negative_eigenv", "", mitkCommandLineParser::Bool, "Correct negative eigenvalues", "correct negative eigenvalues", us::Any(false)); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input image", "input raw dwi", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output image", "output image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("b0_threshold", "", mitkDiffusionCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0); + parser.addArgument("correct_negative_eigenv", "", mitkDiffusionCommandLineParser::Bool, "Correct negative eigenvalues", "correct negative eigenvalues", us::Any(false)); parser.setCategory("Signal Modelling"); parser.setTitle("Tensor Reconstruction"); parser.setDescription(""); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["i"]); std::string outfilename = us::any_cast(parsedArgs["o"]); if (!itksys::SystemTools::GetFilenamePath(outfilename).empty()) outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename); else outfilename = itksys::SystemTools::GetFilenameWithoutExtension(outfilename); outfilename += ".dti"; int threshold = 0; if (parsedArgs.count("b0_threshold")) threshold = us::any_cast(parsedArgs["b0_threshold"]); bool correct_negative_eigenv = false; if (parsedArgs.count("correct_negative_eigenv")) correct_negative_eigenv = us::any_cast(parsedArgs["correct_negative_eigenv"]); try { mitk::Image::Pointer dwi = mitk::IOUtil::Load(inFileName); mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); if (correct_negative_eigenv) { typedef itk::TensorReconstructionWithEigenvalueCorrectionFilter< short, float > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New(); filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi)); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer); filter->SetB0Threshold(threshold); filter->Update(); // Save tensor image itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileType( itk::ImageIOBase::Binary ); io->UseCompressionOn(); mitk::LocaleSwitch localeSwitch("C"); itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New(); writer->SetInput(filter->GetOutput()); writer->SetFileName(outfilename); writer->SetImageIO(io); writer->UseCompressionOn(); writer->Update(); } else { typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue( mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi )); filter->SetThreshold(threshold); filter->Update(); // Save tensor image itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileType( itk::ImageIOBase::Binary ); io->UseCompressionOn(); mitk::LocaleSwitch localeSwitch("C"); itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New(); writer->SetInput(filter->GetOutput()); writer->SetFileName(outfilename); writer->SetImageIO(io); writer->UseCompressionOn(); writer->Update(); } } catch ( itk::ExceptionObject &err) { std::cout << "Exception: " << err; } catch ( std::exception err) { std::cout << "Exception: " << err.what(); } catch ( ... ) { std::cout << "Exception!"; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/Tractography/GlobalTractography.cpp b/Modules/DiffusionCmdApps/Tractography/GlobalTractography.cpp index 61973b7..11c8ba6 100644 --- a/Modules/DiffusionCmdApps/Tractography/GlobalTractography.cpp +++ b/Modules/DiffusionCmdApps/Tractography/GlobalTractography.cpp @@ -1,133 +1,133 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include /*! \brief Perform global fiber tractography (Gibbs tractography) */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Gibbs Tracking"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Perform global fiber tractography (Gibbs tractography)"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image (tensor, ODF or SH-coefficient image)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("parameters", "", mitkCommandLineParser::String, "Parameters:", "parameter file (.gtp)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("mask", "", mitkCommandLineParser::String, "Mask:", "binary mask image", us::Any(), false, false, false, mitkCommandLineParser::Input); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input image (tensor, ODF or SH-coefficient image)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output tractogram", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("parameters", "", mitkDiffusionCommandLineParser::String, "Parameters:", "parameter file (.gtp)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("mask", "", mitkDiffusionCommandLineParser::String, "Mask:", "binary mask image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["i"]); std::string paramFileName = us::any_cast(parsedArgs["parameters"]); std::string outFileName = us::any_cast(parsedArgs["o"]); try { // instantiate gibbs tracker typedef itk::Vector OdfVectorType; typedef itk::Image ItkOdfImageType; typedef itk::GibbsTrackingFilter GibbsTrackingFilterType; GibbsTrackingFilterType::Pointer gibbsTracker = GibbsTrackingFilterType::New(); // load input image mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"SH Image"}, {}); mitk::Image::Pointer mitkImage = mitk::IOUtil::Load(inFileName, &functor); // try to cast to Odf image if( dynamic_cast(mitkImage.GetPointer()) ) { mitk::OdfImage::Pointer mitkOdfImage = dynamic_cast(mitkImage.GetPointer()); ItkOdfImageType::Pointer itk_odf = ItkOdfImageType::New(); mitk::CastToItkImage(mitkOdfImage, itk_odf); gibbsTracker->SetOdfImage(itk_odf.GetPointer()); } else if( dynamic_cast(mitkImage.GetPointer()) ) { typedef itk::Image< itk::DiffusionTensor3D, 3 > ItkTensorImage; mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast(mitkImage.GetPointer()); ItkTensorImage::Pointer itk_dti = ItkTensorImage::New(); mitk::CastToItkImage(mitkTensorImage, itk_dti); gibbsTracker->SetTensorImage(itk_dti); } else if ( dynamic_cast(mitkImage.GetPointer()) ) { mitk::Image::Pointer shImage = dynamic_cast(mitkImage.GetPointer()); gibbsTracker->SetOdfImage(mitk::convert::GetItkOdfFromShImage(shImage)); } else return EXIT_FAILURE; // global tracking if (parsedArgs.count("mask")) { typedef itk::Image MaskImgType; mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::Load(us::any_cast(parsedArgs["mask"])); MaskImgType::Pointer itk_mask = MaskImgType::New(); mitk::CastToItkImage(mitkMaskImage, itk_mask); gibbsTracker->SetMaskImage(itk_mask); } gibbsTracker->SetDuplicateImage(false); gibbsTracker->SetLoadParameterFile( paramFileName ); // gibbsTracker->SetLutPath( "" ); gibbsTracker->Update(); mitk::FiberBundle::Pointer mitkFiberBundle = mitk::FiberBundle::New(gibbsTracker->GetFiberBundle()); mitkFiberBundle->SetReferenceGeometry(mitkImage->GetGeometry()); mitk::IOUtil::Save(mitkFiberBundle, 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/Tractography/RfTraining.cpp b/Modules/DiffusionCmdApps/Tractography/RfTraining.cpp index 138b1db..27f4d91 100644 --- a/Modules/DiffusionCmdApps/Tractography/RfTraining.cpp +++ b/Modules/DiffusionCmdApps/Tractography/RfTraining.cpp @@ -1,238 +1,238 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include /*! \brief Train random forest classifier for machine learning based streamline tractography */ int main(int argc, char* argv[]) { MITK_INFO << "RfTraining"; - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Trains Random Forests for Machine Learning Based Tractography"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Train random forest classifier for machine learning based streamline tractography"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory arguments:"); - parser.addArgument("", "i", mitkCommandLineParser::StringList, "DWIs:", "input diffusion-weighted images", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "t", mitkCommandLineParser::StringList, "Tractograms:", "input training tractograms", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Forest:", "output random forest (HDF5)", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::StringList, "DWIs:", "input diffusion-weighted images", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "t", mitkDiffusionCommandLineParser::StringList, "Tractograms:", "input training tractograms", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Forest:", "output random forest (HDF5)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); parser.endGroup(); parser.beginGroup("2. Additional input images:"); - parser.addArgument("masks", "", mitkCommandLineParser::StringList, "Masks:", "restrict training using a binary mask image", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("wm_masks", "", mitkCommandLineParser::StringList, "WM-Masks:", "if no binary white matter mask is specified, the envelope of the input tractogram is used", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("volume_modification_images", "", mitkCommandLineParser::StringList, "Volume modification images:", "specify a list of float images that modify the fiber density", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("additional_feature_images", "", mitkCommandLineParser::StringList, "Additional feature images:", "specify a list of float images that hold additional features (float)", us::Any(), true, false, false, mitkCommandLineParser::Input); + parser.addArgument("masks", "", mitkDiffusionCommandLineParser::StringList, "Masks:", "restrict training using a binary mask image", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("wm_masks", "", mitkDiffusionCommandLineParser::StringList, "WM-Masks:", "if no binary white matter mask is specified, the envelope of the input tractogram is used", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("volume_modification_images", "", mitkDiffusionCommandLineParser::StringList, "Volume modification images:", "specify a list of float images that modify the fiber density", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("additional_feature_images", "", mitkDiffusionCommandLineParser::StringList, "Additional feature images:", "specify a list of float images that hold additional features (float)", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); parser.endGroup(); parser.beginGroup("3. Forest parameters:"); - parser.addArgument("num_trees", "", mitkCommandLineParser::Int, "Number of trees:", "number of trees", 30); - parser.addArgument("max_tree_depth", "", mitkCommandLineParser::Int, "Max. tree depth:", "maximum tree depth", 25); - parser.addArgument("sample_fraction", "", mitkCommandLineParser::Float, "Sample fraction:", "fraction of samples used per tree", 0.7); + parser.addArgument("num_trees", "", mitkDiffusionCommandLineParser::Int, "Number of trees:", "number of trees", 30); + parser.addArgument("max_tree_depth", "", mitkDiffusionCommandLineParser::Int, "Max. tree depth:", "maximum tree depth", 25); + parser.addArgument("sample_fraction", "", mitkDiffusionCommandLineParser::Float, "Sample fraction:", "fraction of samples used per tree", 0.7); parser.endGroup(); parser.beginGroup("4. Feature parameters:"); - parser.addArgument("use_sh_features", "", mitkCommandLineParser::Bool, "Use SH features:", "use SH features", false); - parser.addArgument("sampling_distance", "", mitkCommandLineParser::Float, "Sampling distance:", "resampling parameter for the input tractogram in mm (determines number of white-matter samples)", us::Any()); - parser.addArgument("max_wm_samples", "", mitkCommandLineParser::Int, "Max. num. WM samples:", "upper limit for the number of WM samples"); - parser.addArgument("num_gm_samples", "", mitkCommandLineParser::Int, "Number of gray matter samples per voxel:", "Number of gray matter samples per voxel", us::Any()); + parser.addArgument("use_sh_features", "", mitkDiffusionCommandLineParser::Bool, "Use SH features:", "use SH features", false); + parser.addArgument("sampling_distance", "", mitkDiffusionCommandLineParser::Float, "Sampling distance:", "resampling parameter for the input tractogram in mm (determines number of white-matter samples)", us::Any()); + parser.addArgument("max_wm_samples", "", mitkDiffusionCommandLineParser::Int, "Max. num. WM samples:", "upper limit for the number of WM samples"); + parser.addArgument("num_gm_samples", "", mitkDiffusionCommandLineParser::Int, "Number of gray matter samples per voxel:", "Number of gray matter samples per voxel", us::Any()); parser.endGroup(); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; bool shfeatures = false; if (parsedArgs.count("use_sh_features")) shfeatures = us::any_cast(parsedArgs["use_sh_features"]); - mitkCommandLineParser::StringContainerType imageFiles = us::any_cast(parsedArgs["i"]); - mitkCommandLineParser::StringContainerType wmMaskFiles; + mitkDiffusionCommandLineParser::StringContainerType imageFiles = us::any_cast(parsedArgs["i"]); + mitkDiffusionCommandLineParser::StringContainerType wmMaskFiles; if (parsedArgs.count("wm_masks")) - wmMaskFiles = us::any_cast(parsedArgs["wm_masks"]); + wmMaskFiles = us::any_cast(parsedArgs["wm_masks"]); - mitkCommandLineParser::StringContainerType volModFiles; + mitkDiffusionCommandLineParser::StringContainerType volModFiles; if (parsedArgs.count("volume_modification_images")) - volModFiles = us::any_cast(parsedArgs["volume_modification_images"]); + volModFiles = us::any_cast(parsedArgs["volume_modification_images"]); - mitkCommandLineParser::StringContainerType addFeatFiles; + mitkDiffusionCommandLineParser::StringContainerType addFeatFiles; if (parsedArgs.count("additional_feature_images")) - addFeatFiles = us::any_cast(parsedArgs["additional_feature_images"]); + addFeatFiles = us::any_cast(parsedArgs["additional_feature_images"]); - mitkCommandLineParser::StringContainerType maskFiles; + mitkDiffusionCommandLineParser::StringContainerType maskFiles; if (parsedArgs.count("masks")) - maskFiles = us::any_cast(parsedArgs["masks"]); + maskFiles = us::any_cast(parsedArgs["masks"]); std::string forestFile = us::any_cast(parsedArgs["o"]); - mitkCommandLineParser::StringContainerType tractogramFiles; + mitkDiffusionCommandLineParser::StringContainerType tractogramFiles; if (parsedArgs.count("t")) - tractogramFiles = us::any_cast(parsedArgs["t"]); + tractogramFiles = us::any_cast(parsedArgs["t"]); int num_trees = 30; if (parsedArgs.count("num_trees")) num_trees = us::any_cast(parsedArgs["num_trees"]); int gm_samples = -1; if (parsedArgs.count("num_gm_samples")) gm_samples = us::any_cast(parsedArgs["num_gm_samples"]); float sampling_distance = -1; if (parsedArgs.count("sampling_distance")) sampling_distance = us::any_cast(parsedArgs["sampling_distance"]); int max_tree_depth = 25; if (parsedArgs.count("max_tree_depth")) max_tree_depth = us::any_cast(parsedArgs["max_tree_depth"]); double sample_fraction = 0.7; if (parsedArgs.count("sample_fraction")) sample_fraction = us::any_cast(parsedArgs["sample_fraction"]); int maxWmSamples = -1; if (parsedArgs.count("max_wm_samples")) maxWmSamples = us::any_cast(parsedArgs["max_wm_samples"]); MITK_INFO << "loading diffusion-weighted images"; std::vector< mitk::Image::Pointer > rawData; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); for (auto imgFile : imageFiles) { auto dwi = mitk::IOUtil::Load(imgFile, &functor); rawData.push_back(dwi); } typedef itk::Image ItkFloatImgType; typedef itk::Image ItkUcharImgType; MITK_INFO << "loading mask images"; std::vector< ItkUcharImgType::Pointer > maskImageVector; for (auto maskFile : maskFiles) { mitk::Image::Pointer img = mitk::IOUtil::Load(maskFile); ItkUcharImgType::Pointer mask = ItkUcharImgType::New(); mitk::CastToItkImage(img, mask); maskImageVector.push_back(mask); } MITK_INFO << "loading white matter mask images"; std::vector< ItkUcharImgType::Pointer > wmMaskImageVector; for (auto wmFile : wmMaskFiles) { mitk::Image::Pointer img = mitk::IOUtil::Load(wmFile); ItkUcharImgType::Pointer wmmask = ItkUcharImgType::New(); mitk::CastToItkImage(img, wmmask); wmMaskImageVector.push_back(wmmask); } MITK_INFO << "loading tractograms"; std::vector< mitk::FiberBundle::Pointer > tractograms; for (auto tractFile : tractogramFiles) { mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(tractFile); tractograms.push_back(fib); } MITK_INFO << "loading white volume modification images"; std::vector< ItkFloatImgType::Pointer > volumeModImages; for (auto file : volModFiles) { mitk::Image::Pointer img = mitk::IOUtil::Load(file); ItkFloatImgType::Pointer itkimg = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkimg); volumeModImages.push_back(itkimg); } MITK_INFO << "loading additional feature images"; std::vector< std::vector< ItkFloatImgType::Pointer > > addFeatImages; for (std::size_t i=0; i()); int c = 0; for (auto file : addFeatFiles) { mitk::Image::Pointer img = mitk::IOUtil::Load(file); ItkFloatImgType::Pointer itkimg = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkimg); addFeatImages.at(c%addFeatImages.size()).push_back(itkimg); c++; } mitk::TractographyForest::Pointer forest = nullptr; if (shfeatures) { mitk::TrackingHandlerRandomForest<6,28> forestHandler; forestHandler.SetDwis(rawData); forestHandler.SetMaskImages(maskImageVector); forestHandler.SetWhiteMatterImages(wmMaskImageVector); forestHandler.SetFiberVolumeModImages(volumeModImages); forestHandler.SetAdditionalFeatureImages(addFeatImages); forestHandler.SetTractograms(tractograms); forestHandler.SetNumTrees(num_trees); forestHandler.SetMaxTreeDepth(max_tree_depth); forestHandler.SetGrayMatterSamplesPerVoxel(gm_samples); forestHandler.SetSampleFraction(sample_fraction); forestHandler.SetFiberSamplingStep(sampling_distance); forestHandler.SetMaxNumWmSamples(maxWmSamples); forestHandler.StartTraining(); forest = forestHandler.GetForest(); } else { mitk::TrackingHandlerRandomForest<6,100> forestHandler; forestHandler.SetDwis(rawData); forestHandler.SetMaskImages(maskImageVector); forestHandler.SetWhiteMatterImages(wmMaskImageVector); forestHandler.SetFiberVolumeModImages(volumeModImages); forestHandler.SetAdditionalFeatureImages(addFeatImages); forestHandler.SetTractograms(tractograms); forestHandler.SetNumTrees(num_trees); forestHandler.SetMaxTreeDepth(max_tree_depth); forestHandler.SetGrayMatterSamplesPerVoxel(gm_samples); forestHandler.SetSampleFraction(sample_fraction); forestHandler.SetFiberSamplingStep(sampling_distance); forestHandler.SetMaxNumWmSamples(maxWmSamples); forestHandler.StartTraining(); forest = forestHandler.GetForest(); } mitk::IOUtil::Save(forest, forestFile); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/Tractography/StreamlineTractography.cpp b/Modules/DiffusionCmdApps/Tractography/StreamlineTractography.cpp index e5f986b..996fc2c 100644 --- a/Modules/DiffusionCmdApps/Tractography/StreamlineTractography.cpp +++ b/Modules/DiffusionCmdApps/Tractography/StreamlineTractography.cpp @@ -1,566 +1,566 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include const int numOdfSamples = 200; typedef itk::Image< itk::Vector< float, numOdfSamples > , 3 > SampledShImageType; /*! \brief */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Streamline Tractography"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Perform streamline tractography"); parser.setContributor("MIC"); // parameters fo all methods parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory arguments:"); - parser.addArgument("", "i", mitkCommandLineParser::StringList, "Input:", "input image (multiple possible for 'DetTensor' algorithm)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output fiberbundle/probability map", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("type", "", mitkCommandLineParser::String, "Type:", "which tracker to use (Peaks; Tensor; ODF; RF)", us::Any(), false); - parser.addArgument("probabilistic", "", mitkCommandLineParser::Bool, "Probabilistic:", "Probabilistic tractography", us::Any(false)); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::StringList, "Input:", "input image (multiple possible for 'DetTensor' algorithm)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output fiberbundle/probability map", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("type", "", mitkDiffusionCommandLineParser::String, "Type:", "which tracker to use (Peaks; Tensor; ODF; RF)", us::Any(), false); + parser.addArgument("probabilistic", "", mitkDiffusionCommandLineParser::Bool, "Probabilistic:", "Probabilistic tractography", us::Any(false)); parser.endGroup(); parser.beginGroup("2. Seeding:"); - parser.addArgument("seeds", "", mitkCommandLineParser::Int, "Seeds per voxel:", "number of seed points per voxel", 1); - parser.addArgument("seed_image", "", mitkCommandLineParser::String, "Seed image:", "mask image defining seed voxels", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("trials_per_seed", "", mitkCommandLineParser::Int, "Max. trials per seed:", "try each seed N times until a valid streamline is obtained (only for probabilistic tractography)", 10); - parser.addArgument("max_tracts", "", mitkCommandLineParser::Int, "Max. number of tracts:", "tractography is stopped if the reconstructed number of tracts is exceeded", -1); + parser.addArgument("seeds", "", mitkDiffusionCommandLineParser::Int, "Seeds per voxel:", "number of seed points per voxel", 1); + parser.addArgument("seed_image", "", mitkDiffusionCommandLineParser::String, "Seed image:", "mask image defining seed voxels", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("trials_per_seed", "", mitkDiffusionCommandLineParser::Int, "Max. trials per seed:", "try each seed N times until a valid streamline is obtained (only for probabilistic tractography)", 10); + parser.addArgument("max_tracts", "", mitkDiffusionCommandLineParser::Int, "Max. number of tracts:", "tractography is stopped if the reconstructed number of tracts is exceeded", -1); parser.endGroup(); parser.beginGroup("3. Tractography constraints:"); - parser.addArgument("tracking_mask", "", mitkCommandLineParser::String, "Mask image:", "streamlines leaving the mask will stop immediately", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("stop_image", "", mitkCommandLineParser::String, "Stop ROI image:", "streamlines entering the mask will stop immediately", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("exclusion_image", "", mitkCommandLineParser::String, "Exclusion ROI image:", "streamlines entering the mask will be discarded", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("ep_constraint", "", mitkCommandLineParser::String, "Endpoint constraint:", "determines which fibers are accepted based on their endpoint location - options are NONE, EPS_IN_TARGET, EPS_IN_TARGET_LABELDIFF, EPS_IN_SEED_AND_TARGET, MIN_ONE_EP_IN_TARGET, ONE_EP_IN_TARGET and NO_EP_IN_TARGET", us::Any()); - parser.addArgument("target_image", "", mitkCommandLineParser::String, "Target ROI image:", "effact depends on the chosen endpoint constraint (option ep_constraint)", us::Any(), true, false, false, mitkCommandLineParser::Input); + parser.addArgument("tracking_mask", "", mitkDiffusionCommandLineParser::String, "Mask image:", "streamlines leaving the mask will stop immediately", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("stop_image", "", mitkDiffusionCommandLineParser::String, "Stop ROI image:", "streamlines entering the mask will stop immediately", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("exclusion_image", "", mitkDiffusionCommandLineParser::String, "Exclusion ROI image:", "streamlines entering the mask will be discarded", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("ep_constraint", "", mitkDiffusionCommandLineParser::String, "Endpoint constraint:", "determines which fibers are accepted based on their endpoint location - options are NONE, EPS_IN_TARGET, EPS_IN_TARGET_LABELDIFF, EPS_IN_SEED_AND_TARGET, MIN_ONE_EP_IN_TARGET, ONE_EP_IN_TARGET and NO_EP_IN_TARGET", us::Any()); + parser.addArgument("target_image", "", mitkDiffusionCommandLineParser::String, "Target ROI image:", "effact depends on the chosen endpoint constraint (option ep_constraint)", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); parser.endGroup(); parser.beginGroup("4. Streamline integration parameters:"); - parser.addArgument("sharpen_odfs", "", mitkCommandLineParser::Bool, "SHarpen ODFs:", "if you are using dODF images as input, it is advisable to sharpen the ODFs (min-max normalize and raise to the power of 4). this is not necessary for CSD fODFs, since they are narurally much sharper."); - parser.addArgument("cutoff", "", mitkCommandLineParser::Float, "Cutoff:", "set the FA, GFA or Peak amplitude cutoff for terminating tracks", 0.1); - parser.addArgument("odf_cutoff", "", mitkCommandLineParser::Float, "ODF Cutoff:", "threshold on the ODF magnitude. this is useful in case of CSD fODF tractography.", 0.0); - parser.addArgument("step_size", "", mitkCommandLineParser::Float, "Step size:", "step size (in voxels)", 0.5); - parser.addArgument("min_tract_length", "", mitkCommandLineParser::Float, "Min. tract length:", "minimum fiber length (in mm)", 20); - parser.addArgument("angular_threshold", "", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold between two successive steps, (default: 90° * step_size, minimum 15°)"); - parser.addArgument("loop_check", "", mitkCommandLineParser::Float, "Check for loops:", "threshold on angular stdev over the last 4 voxel lengths"); - parser.addArgument("peak_jitter", "", mitkCommandLineParser::Float, "Peak jitter:", "important for probabilistic peak tractography and peak prior. actual jitter is drawn from a normal distribution with peak_jitter*fabs(direction_value) as standard deviation.", 0.01); + parser.addArgument("sharpen_odfs", "", mitkDiffusionCommandLineParser::Bool, "SHarpen ODFs:", "if you are using dODF images as input, it is advisable to sharpen the ODFs (min-max normalize and raise to the power of 4). this is not necessary for CSD fODFs, since they are narurally much sharper."); + parser.addArgument("cutoff", "", mitkDiffusionCommandLineParser::Float, "Cutoff:", "set the FA, GFA or Peak amplitude cutoff for terminating tracks", 0.1); + parser.addArgument("odf_cutoff", "", mitkDiffusionCommandLineParser::Float, "ODF Cutoff:", "threshold on the ODF magnitude. this is useful in case of CSD fODF tractography.", 0.0); + parser.addArgument("step_size", "", mitkDiffusionCommandLineParser::Float, "Step size:", "step size (in voxels)", 0.5); + parser.addArgument("min_tract_length", "", mitkDiffusionCommandLineParser::Float, "Min. tract length:", "minimum fiber length (in mm)", 20); + parser.addArgument("angular_threshold", "", mitkDiffusionCommandLineParser::Float, "Angular threshold:", "angular threshold between two successive steps, (default: 90° * step_size, minimum 15°)"); + parser.addArgument("loop_check", "", mitkDiffusionCommandLineParser::Float, "Check for loops:", "threshold on angular stdev over the last 4 voxel lengths"); + parser.addArgument("peak_jitter", "", mitkDiffusionCommandLineParser::Float, "Peak jitter:", "important for probabilistic peak tractography and peak prior. actual jitter is drawn from a normal distribution with peak_jitter*fabs(direction_value) as standard deviation.", 0.01); parser.endGroup(); parser.beginGroup("5. Tractography prior:"); - parser.addArgument("prior_image", "", mitkCommandLineParser::String, "Peak prior:", "tractography prior in thr for of a peak image", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("prior_weight", "", mitkCommandLineParser::Float, "Prior weight", "weighting factor between prior and data.", 0.5); - parser.addArgument("dont_restrict_to_prior", "", mitkCommandLineParser::Bool, "Don't restrict to prior:", "don't restrict tractography to regions where the prior is valid.", us::Any(false)); - parser.addArgument("no_new_directions_from_prior", "", mitkCommandLineParser::Bool, "No new directios from prior:", "the prior cannot create directions where there are none in the data.", us::Any(false)); - parser.addArgument("prior_flip_x", "", mitkCommandLineParser::Bool, "Prior Flip X:", "multiply x-coordinate of prior direction by -1"); - parser.addArgument("prior_flip_y", "", mitkCommandLineParser::Bool, "Prior Flip Y:", "multiply y-coordinate of prior direction by -1"); - parser.addArgument("prior_flip_z", "", mitkCommandLineParser::Bool, "Prior Flip Z:", "multiply z-coordinate of prior direction by -1"); + parser.addArgument("prior_image", "", mitkDiffusionCommandLineParser::String, "Peak prior:", "tractography prior in thr for of a peak image", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("prior_weight", "", mitkDiffusionCommandLineParser::Float, "Prior weight", "weighting factor between prior and data.", 0.5); + parser.addArgument("dont_restrict_to_prior", "", mitkDiffusionCommandLineParser::Bool, "Don't restrict to prior:", "don't restrict tractography to regions where the prior is valid.", us::Any(false)); + parser.addArgument("no_new_directions_from_prior", "", mitkDiffusionCommandLineParser::Bool, "No new directios from prior:", "the prior cannot create directions where there are none in the data.", us::Any(false)); + parser.addArgument("prior_flip_x", "", mitkDiffusionCommandLineParser::Bool, "Prior Flip X:", "multiply x-coordinate of prior direction by -1"); + parser.addArgument("prior_flip_y", "", mitkDiffusionCommandLineParser::Bool, "Prior Flip Y:", "multiply y-coordinate of prior direction by -1"); + parser.addArgument("prior_flip_z", "", mitkDiffusionCommandLineParser::Bool, "Prior Flip Z:", "multiply z-coordinate of prior direction by -1"); parser.endGroup(); parser.beginGroup("6. Neighborhood sampling:"); - parser.addArgument("num_samples", "", mitkCommandLineParser::Int, "Num. neighborhood samples:", "number of neighborhood samples that are use to determine the next progression direction", 0); - parser.addArgument("sampling_distance", "", mitkCommandLineParser::Float, "Sampling distance:", "distance of neighborhood sampling points (in voxels)", 0.25); - parser.addArgument("use_stop_votes", "", mitkCommandLineParser::Bool, "Use stop votes:", "use stop votes"); - parser.addArgument("use_only_forward_samples", "", mitkCommandLineParser::Bool, "Use only forward samples:", "use only forward samples"); + parser.addArgument("num_samples", "", mitkDiffusionCommandLineParser::Int, "Num. neighborhood samples:", "number of neighborhood samples that are use to determine the next progression direction", 0); + parser.addArgument("sampling_distance", "", mitkDiffusionCommandLineParser::Float, "Sampling distance:", "distance of neighborhood sampling points (in voxels)", 0.25); + parser.addArgument("use_stop_votes", "", mitkDiffusionCommandLineParser::Bool, "Use stop votes:", "use stop votes"); + parser.addArgument("use_only_forward_samples", "", mitkDiffusionCommandLineParser::Bool, "Use only forward samples:", "use only forward samples"); parser.endGroup(); parser.beginGroup("7. Tensor tractography specific:"); - parser.addArgument("tend_f", "", mitkCommandLineParser::Float, "Weight f", "weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0).", 1.0); - parser.addArgument("tend_g", "", mitkCommandLineParser::Float, "Weight g", "weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking)", 0.0); + parser.addArgument("tend_f", "", mitkDiffusionCommandLineParser::Float, "Weight f", "weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0).", 1.0); + parser.addArgument("tend_g", "", mitkDiffusionCommandLineParser::Float, "Weight g", "weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking)", 0.0); parser.endGroup(); parser.beginGroup("8. Random forest tractography specific:"); - parser.addArgument("forest", "", mitkCommandLineParser::String, "Forest:", "input random forest (HDF5 file)", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("use_sh_features", "", mitkCommandLineParser::Bool, "Use SH features:", "use SH features"); + parser.addArgument("forest", "", mitkDiffusionCommandLineParser::String, "Forest:", "input random forest (HDF5 file)", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("use_sh_features", "", mitkDiffusionCommandLineParser::Bool, "Use SH features:", "use SH features"); parser.endGroup(); parser.beginGroup("9. Additional input:"); - parser.addArgument("additional_images", "", mitkCommandLineParser::StringList, "Additional images:", "specify a list of float images that hold additional information (FA, GFA, additional features for RF tractography)", us::Any(), true, false, false, mitkCommandLineParser::Input); + parser.addArgument("additional_images", "", mitkDiffusionCommandLineParser::StringList, "Additional images:", "specify a list of float images that hold additional information (FA, GFA, additional features for RF tractography)", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); parser.endGroup(); parser.beginGroup("10. Misc:"); - parser.addArgument("flip_x", "", mitkCommandLineParser::Bool, "Flip X:", "multiply x-coordinate of direction proposal by -1"); - parser.addArgument("flip_y", "", mitkCommandLineParser::Bool, "Flip Y:", "multiply y-coordinate of direction proposal by -1"); - parser.addArgument("flip_z", "", mitkCommandLineParser::Bool, "Flip Z:", "multiply z-coordinate of direction proposal by -1"); - parser.addArgument("no_data_interpolation", "", mitkCommandLineParser::Bool, "Don't interpolate input data:", "don't interpolate input image values"); - parser.addArgument("no_mask_interpolation", "", mitkCommandLineParser::Bool, "Don't interpolate masks:", "don't interpolate mask image values"); - parser.addArgument("compress", "", mitkCommandLineParser::Float, "Compress:", "compress output fibers using the given error threshold (in mm)"); - parser.addArgument("fix_seed", "", mitkCommandLineParser::Bool, "Fix Random Seed:", "always use the same random numbers"); - parser.addArgument("parameter_file", "", mitkCommandLineParser::String, "Parameter File:", "load parameters from json file (svae using MITK Diffusion GUI). the parameters loaded form this file are overwritten by the manually set parameters.", us::Any(), true, false, false, mitkCommandLineParser::Input); + parser.addArgument("flip_x", "", mitkDiffusionCommandLineParser::Bool, "Flip X:", "multiply x-coordinate of direction proposal by -1"); + parser.addArgument("flip_y", "", mitkDiffusionCommandLineParser::Bool, "Flip Y:", "multiply y-coordinate of direction proposal by -1"); + parser.addArgument("flip_z", "", mitkDiffusionCommandLineParser::Bool, "Flip Z:", "multiply z-coordinate of direction proposal by -1"); + parser.addArgument("no_data_interpolation", "", mitkDiffusionCommandLineParser::Bool, "Don't interpolate input data:", "don't interpolate input image values"); + parser.addArgument("no_mask_interpolation", "", mitkDiffusionCommandLineParser::Bool, "Don't interpolate masks:", "don't interpolate mask image values"); + parser.addArgument("compress", "", mitkDiffusionCommandLineParser::Float, "Compress:", "compress output fibers using the given error threshold (in mm)"); + parser.addArgument("fix_seed", "", mitkDiffusionCommandLineParser::Bool, "Fix Random Seed:", "always use the same random numbers"); + parser.addArgument("parameter_file", "", mitkDiffusionCommandLineParser::String, "Parameter File:", "load parameters from json file (svae using MITK Diffusion GUI). the parameters loaded form this file are overwritten by the manually set parameters.", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); parser.endGroup(); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; - mitkCommandLineParser::StringContainerType input_files = us::any_cast(parsedArgs["i"]); + mitkDiffusionCommandLineParser::StringContainerType input_files = us::any_cast(parsedArgs["i"]); std::string outFile = us::any_cast(parsedArgs["o"]); std::string type = us::any_cast(parsedArgs["type"]); std::shared_ptr< mitk::StreamlineTractographyParameters > params = std::make_shared(); if (parsedArgs.count("parameter_file")) { auto parameter_file = us::any_cast(parsedArgs["parameter_file"]); params->LoadParameters(parameter_file); } if (parsedArgs.count("probabilistic")) params->m_Mode = mitk::StreamlineTractographyParameters::MODE::PROBABILISTIC; else { params->m_Mode = mitk::StreamlineTractographyParameters::MODE::DETERMINISTIC; } std::string prior_image = ""; if (parsedArgs.count("prior_image")) prior_image = us::any_cast(parsedArgs["prior_image"]); if (parsedArgs.count("prior_weight")) params->m_Weight = us::any_cast(parsedArgs["prior_weight"]); if (parsedArgs.count("fix_seed")) params->m_FixRandomSeed = us::any_cast(parsedArgs["fix_seed"]); params->m_RestrictToPrior = true; if (parsedArgs.count("dont_restrict_to_prior")) params->m_RestrictToPrior = !us::any_cast(parsedArgs["dont_restrict_to_prior"]); params->m_NewDirectionsFromPrior = true; if (parsedArgs.count("no_new_directions_from_prior")) params->m_NewDirectionsFromPrior = !us::any_cast(parsedArgs["no_new_directions_from_prior"]); params->m_SharpenOdfs = false; if (parsedArgs.count("sharpen_odfs")) params->m_SharpenOdfs = us::any_cast(parsedArgs["sharpen_odfs"]); params->m_InterpolateTractographyData = true; if (parsedArgs.count("no_data_interpolation")) params->m_InterpolateTractographyData = !us::any_cast(parsedArgs["no_data_interpolation"]); params->m_InterpolateRoiImages = true; if (parsedArgs.count("no_mask_interpolation")) params->m_InterpolateRoiImages = !us::any_cast(parsedArgs["no_mask_interpolation"]); bool use_sh_features = false; if (parsedArgs.count("use_sh_features")) use_sh_features = us::any_cast(parsedArgs["use_sh_features"]); params->m_StopVotes = false; if (parsedArgs.count("use_stop_votes")) params->m_StopVotes = us::any_cast(parsedArgs["use_stop_votes"]); params->m_OnlyForwardSamples = false; if (parsedArgs.count("use_only_forward_samples")) params->m_OnlyForwardSamples = us::any_cast(parsedArgs["use_only_forward_samples"]); params->m_FlipX = false; if (parsedArgs.count("flip_x")) params->m_FlipX = us::any_cast(parsedArgs["flip_x"]); params->m_FlipY = false; if (parsedArgs.count("flip_y")) params->m_FlipY = us::any_cast(parsedArgs["flip_y"]); params->m_FlipZ = false; if (parsedArgs.count("flip_z")) params->m_FlipZ = us::any_cast(parsedArgs["flip_z"]); bool prior_flip_x = false; if (parsedArgs.count("prior_flip_x")) prior_flip_x = us::any_cast(parsedArgs["prior_flip_x"]); bool prior_flip_y = false; if (parsedArgs.count("prior_flip_y")) prior_flip_y = us::any_cast(parsedArgs["prior_flip_y"]); bool prior_flip_z = false; if (parsedArgs.count("prior_flip_z")) prior_flip_z = us::any_cast(parsedArgs["prior_flip_z"]); params->m_ApplyDirectionMatrix = false; if (parsedArgs.count("apply_image_rotation")) params->m_ApplyDirectionMatrix = us::any_cast(parsedArgs["apply_image_rotation"]); float compress = -1; if (parsedArgs.count("compress")) compress = us::any_cast(parsedArgs["compress"]); params->m_MinTractLengthMm = 20; if (parsedArgs.count("min_tract_length")) params->m_MinTractLengthMm = us::any_cast(parsedArgs["min_tract_length"]); params->SetLoopCheckDeg(-1); if (parsedArgs.count("loop_check")) params->SetLoopCheckDeg(us::any_cast(parsedArgs["loop_check"])); std::string forestFile; if (parsedArgs.count("forest")) forestFile = us::any_cast(parsedArgs["forest"]); std::string maskFile = ""; if (parsedArgs.count("tracking_mask")) maskFile = us::any_cast(parsedArgs["tracking_mask"]); std::string seedFile = ""; if (parsedArgs.count("seed_image")) seedFile = us::any_cast(parsedArgs["seed_image"]); std::string targetFile = ""; if (parsedArgs.count("target_image")) targetFile = us::any_cast(parsedArgs["target_image"]); std::string exclusionFile = ""; if (parsedArgs.count("exclusion_image")) exclusionFile = us::any_cast(parsedArgs["exclusion_image"]); std::string stopFile = ""; if (parsedArgs.count("stop_image")) stopFile = us::any_cast(parsedArgs["stop_image"]); std::string ep_constraint = "NONE"; if (parsedArgs.count("ep_constraint")) ep_constraint = us::any_cast(parsedArgs["ep_constraint"]); params->m_Cutoff = 0.1f; if (parsedArgs.count("cutoff")) params->m_Cutoff = us::any_cast(parsedArgs["cutoff"]); params->m_OdfCutoff = 0.0; if (parsedArgs.count("odf_cutoff")) params->m_OdfCutoff = us::any_cast(parsedArgs["odf_cutoff"]); params->m_PeakJitter = 0.01; if (parsedArgs.count("peak_jitter")) params->m_PeakJitter = us::any_cast(parsedArgs["peak_jitter"]); params->SetStepSizeVox(-1); if (parsedArgs.count("step_size")) params->SetStepSizeVox(us::any_cast(parsedArgs["step_size"])); params->SetSamplingDistanceVox(-1); if (parsedArgs.count("sampling_distance")) params->SetSamplingDistanceVox(us::any_cast(parsedArgs["sampling_distance"])); params->m_NumSamples = 0; if (parsedArgs.count("num_samples")) params->m_NumSamples = static_cast(us::any_cast(parsedArgs["num_samples"])); params->m_SeedsPerVoxel = 1; if (parsedArgs.count("seeds")) params->m_SeedsPerVoxel = us::any_cast(parsedArgs["seeds"]); params->m_TrialsPerSeed = 10; if (parsedArgs.count("trials_per_seed")) params->m_TrialsPerSeed = static_cast(us::any_cast(parsedArgs["trials_per_seed"])); params->m_F = 1; if (parsedArgs.count("tend_f")) params->m_F = us::any_cast(parsedArgs["tend_f"]); params->m_G = 0; if (parsedArgs.count("tend_g")) params->m_G = us::any_cast(parsedArgs["tend_g"]); params->SetAngularThresholdDeg(-1); if (parsedArgs.count("angular_threshold")) params->SetAngularThresholdDeg(us::any_cast(parsedArgs["angular_threshold"])); params->m_MaxNumFibers = -1; if (parsedArgs.count("max_tracts")) params->m_MaxNumFibers = us::any_cast(parsedArgs["max_tracts"]); std::string ext = itksys::SystemTools::GetFilenameExtension(outFile); if (ext != ".fib" && ext != ".trk") { MITK_INFO << "Output file format not supported. Use one of .fib, .trk, .nii, .nii.gz, .nrrd"; return EXIT_FAILURE; } // LOAD DATASETS - mitkCommandLineParser::StringContainerType addFiles; + mitkDiffusionCommandLineParser::StringContainerType addFiles; if (parsedArgs.count("additional_images")) - addFiles = us::any_cast(parsedArgs["additional_images"]); + addFiles = us::any_cast(parsedArgs["additional_images"]); typedef itk::Image ItkFloatImgType; ItkFloatImgType::Pointer mask = nullptr; if (!maskFile.empty()) { MITK_INFO << "loading mask image"; mitk::Image::Pointer img = mitk::IOUtil::Load(maskFile); mask = ItkFloatImgType::New(); mitk::CastToItkImage(img, mask); } ItkFloatImgType::Pointer seed = nullptr; if (!seedFile.empty()) { MITK_INFO << "loading seed ROI image"; mitk::Image::Pointer img = mitk::IOUtil::Load(seedFile); seed = ItkFloatImgType::New(); mitk::CastToItkImage(img, seed); } ItkFloatImgType::Pointer stop = nullptr; if (!stopFile.empty()) { MITK_INFO << "loading stop ROI image"; mitk::Image::Pointer img = mitk::IOUtil::Load(stopFile); stop = ItkFloatImgType::New(); mitk::CastToItkImage(img, stop); } ItkFloatImgType::Pointer target = nullptr; if (!targetFile.empty()) { MITK_INFO << "loading target ROI image"; mitk::Image::Pointer img = mitk::IOUtil::Load(targetFile); target = ItkFloatImgType::New(); mitk::CastToItkImage(img, target); } ItkFloatImgType::Pointer exclusion = nullptr; if (!exclusionFile.empty()) { MITK_INFO << "loading exclusion ROI image"; mitk::Image::Pointer img = mitk::IOUtil::Load(exclusionFile); exclusion = ItkFloatImgType::New(); mitk::CastToItkImage(img, exclusion); } MITK_INFO << "loading additional images"; std::vector< std::vector< ItkFloatImgType::Pointer > > addImages; addImages.push_back(std::vector< ItkFloatImgType::Pointer >()); for (auto file : addFiles) { mitk::Image::Pointer img = mitk::IOUtil::Load(file); ItkFloatImgType::Pointer itkimg = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkimg); addImages.at(0).push_back(itkimg); } // ////////////////////////////////////////////////////////////////// // omp_set_num_threads(1); typedef itk::StreamlineTrackingFilter TrackerType; TrackerType::Pointer tracker = TrackerType::New(); if (!prior_image.empty()) { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image"}, {}); mitk::PeakImage::Pointer priorImage = mitk::IOUtil::Load(prior_image, &functor); if (priorImage.IsNull()) { MITK_INFO << "Only peak images are supported as prior at the moment!"; return EXIT_FAILURE; } mitk::TrackingDataHandler* priorhandler = new mitk::TrackingHandlerPeaks(); typedef mitk::ImageToItk< mitk::TrackingHandlerPeaks::PeakImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(priorImage); caster->Update(); mitk::TrackingHandlerPeaks::PeakImgType::Pointer itkImg = caster->GetOutput(); std::shared_ptr< mitk::StreamlineTractographyParameters > prior_params = std::make_shared< mitk::StreamlineTractographyParameters >(*params); prior_params->m_FlipX = prior_flip_x; prior_params->m_FlipY = prior_flip_y; prior_params->m_FlipZ = prior_flip_z; prior_params->m_Cutoff = 0.0; dynamic_cast(priorhandler)->SetPeakImage(itkImg); priorhandler->SetParameters(prior_params); tracker->SetTrackingPriorHandler(priorhandler); } mitk::TrackingDataHandler* handler; if (type == "RF") { mitk::TractographyForest::Pointer forest = mitk::IOUtil::Load(forestFile); if (forest.IsNull()) mitkThrow() << "Forest file " << forestFile << " could not be read."; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); auto input = mitk::IOUtil::Load(input_files.at(0), &functor); if (use_sh_features) { handler = new mitk::TrackingHandlerRandomForest<6,28>(); dynamic_cast*>(handler)->SetForest(forest); dynamic_cast*>(handler)->AddDwi(input); dynamic_cast*>(handler)->SetAdditionalFeatureImages(addImages); } else { handler = new mitk::TrackingHandlerRandomForest<6,100>(); dynamic_cast*>(handler)->SetForest(forest); dynamic_cast*>(handler)->AddDwi(input); dynamic_cast*>(handler)->SetAdditionalFeatureImages(addImages); } } else if (type == "Peaks") { handler = new mitk::TrackingHandlerPeaks(); MITK_INFO << "loading input peak image"; mitk::Image::Pointer mitkImage = mitk::IOUtil::Load(input_files.at(0)); mitk::TrackingHandlerPeaks::PeakImgType::Pointer itkImg = mitk::convert::GetItkPeakFromPeakImage(mitkImage); dynamic_cast(handler)->SetPeakImage(itkImg); } else if (type == "Tensor" && params->m_Mode == mitk::StreamlineTractographyParameters::MODE::DETERMINISTIC) { handler = new mitk::TrackingHandlerTensor(); MITK_INFO << "loading input tensor images"; std::vector< mitk::Image::Pointer > input_images; for (unsigned int i=0; i(input_files.at(i)); mitk::TensorImage::ItkTensorImageType::Pointer itkImg = mitk::convert::GetItkTensorFromTensorImage(mitkImage); dynamic_cast(handler)->AddTensorImage(itkImg.GetPointer()); } if (addImages.at(0).size()>0) dynamic_cast(handler)->SetFaImage(addImages.at(0).at(0)); } else if (type == "ODF" || (type == "Tensor" && params->m_Mode == mitk::StreamlineTractographyParameters::MODE::PROBABILISTIC)) { handler = new mitk::TrackingHandlerOdf(); mitk::OdfImage::ItkOdfImageType::Pointer itkImg = nullptr; if (type == "Tensor") { MITK_INFO << "Converting Tensor to ODF image"; auto input = mitk::IOUtil::Load(input_files.at(0)); itkImg = mitk::convert::GetItkOdfFromTensorImage(input); dynamic_cast(handler)->SetIsOdfFromTensor(true); } else { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"SH Image", "ODF Image"}, {}); auto input = mitk::IOUtil::Load(input_files.at(0), &functor)[0]; if (dynamic_cast(input.GetPointer())) { MITK_INFO << "Converting SH to ODF image"; mitk::Image::Pointer mitkImg = dynamic_cast(input.GetPointer()); itkImg = mitk::convert::GetItkOdfFromShImage(mitkImg); } else if (dynamic_cast(input.GetPointer())) { mitk::Image::Pointer mitkImg = dynamic_cast(input.GetPointer()); itkImg = mitk::convert::GetItkOdfFromOdfImage(mitkImg); } else mitkThrow() << ""; } dynamic_cast(handler)->SetOdfImage(itkImg); if (addImages.at(0).size()>0) dynamic_cast(handler)->SetGfaImage(addImages.at(0).at(0)); } else { MITK_INFO << "Unknown tractography algorithm (" + type+"). Known types are Peaks, DetTensor, ProbTensor, DetODF, ProbODF, DetRF, ProbRF."; return EXIT_FAILURE; } if (ep_constraint=="NONE") params->m_EpConstraints = itk::StreamlineTrackingFilter::EndpointConstraints::NONE; else if (ep_constraint=="EPS_IN_TARGET") params->m_EpConstraints = itk::StreamlineTrackingFilter::EndpointConstraints::EPS_IN_TARGET; else if (ep_constraint=="EPS_IN_TARGET_LABELDIFF") params->m_EpConstraints = itk::StreamlineTrackingFilter::EndpointConstraints::EPS_IN_TARGET_LABELDIFF; else if (ep_constraint=="EPS_IN_SEED_AND_TARGET") params->m_EpConstraints = itk::StreamlineTrackingFilter::EndpointConstraints::EPS_IN_SEED_AND_TARGET; else if (ep_constraint=="MIN_ONE_EP_IN_TARGET") params->m_EpConstraints = itk::StreamlineTrackingFilter::EndpointConstraints::MIN_ONE_EP_IN_TARGET; else if (ep_constraint=="ONE_EP_IN_TARGET") params->m_EpConstraints = itk::StreamlineTrackingFilter::EndpointConstraints::ONE_EP_IN_TARGET; else if (ep_constraint=="NO_EP_IN_TARGET") params->m_EpConstraints = itk::StreamlineTrackingFilter::EndpointConstraints::NO_EP_IN_TARGET; MITK_INFO << "Tractography algorithm: " << type; tracker->SetMaskImage(mask); tracker->SetSeedImage(seed); tracker->SetStoppingRegions(stop); tracker->SetTargetRegions(target); tracker->SetExclusionRegions(exclusion); tracker->SetTrackingHandler(handler); if (ext != ".fib" && ext != ".trk") params->m_OutputProbMap = true; tracker->SetParameters(params); tracker->Update(); if (ext == ".fib" || ext == ".trk") { vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); if (compress > 0) outFib->Compress(compress); mitk::IOUtil::Save(outFib, outFile); } else { TrackerType::ItkDoubleImgType::Pointer outImg = tracker->GetOutputProbabilityMap(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); if (ext != ".nii" && ext != ".nii.gz" && ext != ".nrrd") outFile += ".nii.gz"; mitk::IOUtil::Save(img, outFile); } delete handler; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionCmdApps/TractographyEvaluation/AnchorConstrainedPlausibility.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/AnchorConstrainedPlausibility.cpp index e8fa990..fe3cb40 100644 --- a/Modules/DiffusionCmdApps/TractographyEvaluation/AnchorConstrainedPlausibility.cpp +++ b/Modules/DiffusionCmdApps/TractographyEvaluation/AnchorConstrainedPlausibility.cpp @@ -1,447 +1,447 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef itk::Point PointType4; typedef mitk::PeakImage::ItkPeakImageType PeakImgType; typedef itk::Image< unsigned char, 3 > ItkUcharImageType; /*! \brief Score input candidate tracts using ACP analysis */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Anchor Constrained Plausibility"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription("Score input candidate tracts using ACP analysis"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "a", mitkCommandLineParser::String, "Anchor tractogram:", "anchor tracts in one tractogram file", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "p", mitkCommandLineParser::String, "Input peaks:", "input peak image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "c", mitkCommandLineParser::StringList, "Candidates:", "Folder(s) or file list of candidate tracts", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output folder:", "output folder", us::Any(), false, false, false, mitkCommandLineParser::Output); + parser.addArgument("", "a", mitkDiffusionCommandLineParser::String, "Anchor tractogram:", "anchor tracts in one tractogram file", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "p", mitkDiffusionCommandLineParser::String, "Input peaks:", "input peak image", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "c", mitkDiffusionCommandLineParser::StringList, "Candidates:", "Folder(s) or file list of candidate tracts", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output folder:", "output folder", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); - parser.addArgument("reference_mask_folders", "", mitkCommandLineParser::StringList, "Reference Mask Folder(s):", "Folder(s) or file list containing reference tract masks for accuracy evaluation", true, false, false, mitkCommandLineParser::Input); - parser.addArgument("reference_peaks_folders", "", mitkCommandLineParser::StringList, "Reference Peaks Folder(s):", "Folder(s) or file list containing reference peak images for accuracy evaluation", true, false, false, mitkCommandLineParser::Input); + parser.addArgument("reference_mask_folders", "", mitkDiffusionCommandLineParser::StringList, "Reference Mask Folder(s):", "Folder(s) or file list containing reference tract masks for accuracy evaluation", true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("reference_peaks_folders", "", mitkDiffusionCommandLineParser::StringList, "Reference Peaks Folder(s):", "Folder(s) or file list containing reference peak images for accuracy evaluation", true, false, false, mitkDiffusionCommandLineParser::Input); - parser.addArgument("mask", "", mitkCommandLineParser::String, "Mask image:", "scoring is only performed inside the mask image", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("greedy_add", "", mitkCommandLineParser::Bool, "Greedy:", "if enabled, the candidate tracts are not jointly fitted to the residual image but one after the other employing a greedy scheme", false); - parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda:", "modifier for regularization", 0.1); - parser.addArgument("filter_outliers", "", mitkCommandLineParser::Bool, "Filter outliers:", "perform second optimization run with an upper weight bound based on the first weight estimation (99% quantile)", false); - parser.addArgument("regu", "", mitkCommandLineParser::String, "Regularization:", "MSM; Variance; VoxelVariance; Lasso; GroupLasso; GroupVariance; NONE", std::string("NONE")); - parser.addArgument("use_num_streamlines", "", mitkCommandLineParser::Bool, "Use number of streamlines as score:", "Don't fit candidates, simply use number of streamlines per candidate as score", false); - parser.addArgument("use_weights", "", mitkCommandLineParser::Bool, "Use input weights as score:", "Don't fit candidates, simply use first input streamline weight per candidate as score", false); - parser.addArgument("filter_zero_weights", "", mitkCommandLineParser::Bool, "Filter zero-weights", "Remove streamlines with weight 0 from candidates", false); - parser.addArgument("flipx", "", mitkCommandLineParser::Bool, "Flip x", "flip along x-axis", false); - parser.addArgument("flipy", "", mitkCommandLineParser::Bool, "Flip y", "flip along y-axis", false); - parser.addArgument("flipz", "", mitkCommandLineParser::Bool, "Flip z", "flip along z-axis", false); + parser.addArgument("mask", "", mitkDiffusionCommandLineParser::String, "Mask image:", "scoring is only performed inside the mask image", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("greedy_add", "", mitkDiffusionCommandLineParser::Bool, "Greedy:", "if enabled, the candidate tracts are not jointly fitted to the residual image but one after the other employing a greedy scheme", false); + parser.addArgument("lambda", "", mitkDiffusionCommandLineParser::Float, "Lambda:", "modifier for regularization", 0.1); + parser.addArgument("filter_outliers", "", mitkDiffusionCommandLineParser::Bool, "Filter outliers:", "perform second optimization run with an upper weight bound based on the first weight estimation (99% quantile)", false); + parser.addArgument("regu", "", mitkDiffusionCommandLineParser::String, "Regularization:", "MSM; Variance; VoxelVariance; Lasso; GroupLasso; GroupVariance; NONE", std::string("NONE")); + parser.addArgument("use_num_streamlines", "", mitkDiffusionCommandLineParser::Bool, "Use number of streamlines as score:", "Don't fit candidates, simply use number of streamlines per candidate as score", false); + parser.addArgument("use_weights", "", mitkDiffusionCommandLineParser::Bool, "Use input weights as score:", "Don't fit candidates, simply use first input streamline weight per candidate as score", false); + parser.addArgument("filter_zero_weights", "", mitkDiffusionCommandLineParser::Bool, "Filter zero-weights", "Remove streamlines with weight 0 from candidates", false); + parser.addArgument("flipx", "", mitkDiffusionCommandLineParser::Bool, "Flip x", "flip along x-axis", false); + parser.addArgument("flipy", "", mitkDiffusionCommandLineParser::Bool, "Flip y", "flip along y-axis", false); + parser.addArgument("flipz", "", mitkDiffusionCommandLineParser::Bool, "Flip z", "flip along z-axis", false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string peak_file_name = us::any_cast(parsedArgs["p"]); std::string out_folder = us::any_cast(parsedArgs["o"]); - mitkCommandLineParser::StringContainerType candidate_tract_folders = us::any_cast(parsedArgs["c"]); + mitkDiffusionCommandLineParser::StringContainerType candidate_tract_folders = us::any_cast(parsedArgs["c"]); if (!out_folder.empty() && out_folder.back() != '/') out_folder += "/"; bool greedy_add = false; if (parsedArgs.count("greedy_add")) greedy_add = us::any_cast(parsedArgs["greedy_add"]); float lambda = 0.1f; if (parsedArgs.count("lambda")) lambda = us::any_cast(parsedArgs["lambda"]); bool filter_outliers = false; if (parsedArgs.count("filter_outliers")) filter_outliers = us::any_cast(parsedArgs["filter_outliers"]); bool filter_zero_weights = false; if (parsedArgs.count("filter_zero_weights")) filter_zero_weights = us::any_cast(parsedArgs["filter_zero_weights"]); std::string mask_file = ""; if (parsedArgs.count("mask")) mask_file = us::any_cast(parsedArgs["mask"]); - mitkCommandLineParser::StringContainerType reference_mask_files_folders; + mitkDiffusionCommandLineParser::StringContainerType reference_mask_files_folders; if (parsedArgs.count("reference_mask_folders")) - reference_mask_files_folders = us::any_cast(parsedArgs["reference_mask_folders"]); + reference_mask_files_folders = us::any_cast(parsedArgs["reference_mask_folders"]); - mitkCommandLineParser::StringContainerType reference_peaks_files_folders; + mitkDiffusionCommandLineParser::StringContainerType reference_peaks_files_folders; if (parsedArgs.count("reference_peaks_folders")) - reference_peaks_files_folders = us::any_cast(parsedArgs["reference_peaks_folders"]); + reference_peaks_files_folders = us::any_cast(parsedArgs["reference_peaks_folders"]); std::string regu = "NONE"; if (parsedArgs.count("regu")) regu = us::any_cast(parsedArgs["regu"]); bool use_weights = false; if (parsedArgs.count("use_weights")) use_weights = us::any_cast(parsedArgs["use_weights"]); bool use_num_streamlines = false; if (parsedArgs.count("use_num_streamlines")) use_num_streamlines = us::any_cast(parsedArgs["use_num_streamlines"]); bool flipx = false; if (parsedArgs.count("flipx")) flipx = us::any_cast(parsedArgs["flipx"]); bool flipy = false; if (parsedArgs.count("flipy")) flipy = us::any_cast(parsedArgs["flipy"]); bool flipz = false; if (parsedArgs.count("flipz")) flipz = us::any_cast(parsedArgs["flipz"]); try { itk::TimeProbe clock; clock.Start(); if (!ist::PathExists(out_folder)) { MITK_INFO << "Creating output directory"; ist::MakeDirectory(out_folder); } MITK_INFO << "Loading data"; // Load mask file. Fit is only performed inside the mask MITK_INFO << "Loading mask image"; auto mask = mitk::DiffusionDataIOHelper::load_itk_image(mask_file); // Load masks covering the true positives for evaluation purposes MITK_INFO << "Loading reference peaks and masks"; std::vector< std::string > anchor_mask_files; auto reference_masks = mitk::DiffusionDataIOHelper::load_itk_images(reference_mask_files_folders, &anchor_mask_files); auto reference_peaks = mitk::DiffusionDataIOHelper::load_itk_images(reference_peaks_files_folders); // Load peak image MITK_INFO << "Loading peak image"; auto peak_image = mitk::DiffusionDataIOHelper::load_itk_image(peak_file_name); // Load all candidate tracts MITK_INFO << "Loading candidate tracts"; std::vector< std::string > candidate_tract_files; auto input_candidates = mitk::DiffusionDataIOHelper::load_fibs(candidate_tract_folders, &candidate_tract_files); if (flipx || flipy || flipz) { itk::FlipPeaksFilter< float >::Pointer flipper = itk::FlipPeaksFilter< float >::New(); flipper->SetInput(peak_image); flipper->SetFlipX(flipx); flipper->SetFlipY(flipy); flipper->SetFlipZ(flipz); flipper->Update(); peak_image = flipper->GetOutput(); } mitk::LocaleSwitch localeSwitch("C"); itk::ImageFileWriter< PeakImgType >::Pointer peak_image_writer = itk::ImageFileWriter< PeakImgType >::New(); ofstream logfile; logfile.open (out_folder + "scores.txt"); double rmse = 0.0; int iteration = 0; std::string name = "NOANCHOR"; if (parsedArgs.count("a")) { // Load reference tractogram consisting of all known tracts std::string anchors_file = us::any_cast(parsedArgs["a"]); mitk::FiberBundle::Pointer anchor_tractogram = mitk::IOUtil::Load(anchors_file); if ( !(anchor_tractogram.IsNull() || anchor_tractogram->GetNumFibers()==0) ) { // Fit known tracts to peak image to obtain underexplained image MITK_INFO << "Fit anchor tracts"; itk::FitFibersToImageFilter::Pointer fitter = itk::FitFibersToImageFilter::New(); fitter->SetTractograms({anchor_tractogram}); fitter->SetLambda(static_cast(lambda)); fitter->SetFilterOutliers(filter_outliers); fitter->SetPeakImage(peak_image); fitter->SetVerbose(true); fitter->SetMaskImage(mask); fitter->SetRegularization(VnlCostFunction::REGU::NONE); fitter->Update(); rmse = fitter->GetRMSE(); vnl_vector rms_diff = fitter->GetRmsDiffPerBundle(); name = ist::GetFilenameWithoutExtension(anchors_file); mitk::FiberBundle::Pointer anchor_tracts = fitter->GetTractograms().at(0); anchor_tracts->SetFiberColors(255,255,255); mitk::IOUtil::Save(anchor_tracts, out_folder + boost::lexical_cast(static_cast(100000*rms_diff[0])) + "_" + name + ".fib"); logfile << name << " " << setprecision(5) << rms_diff[0] << "\n"; peak_image = fitter->GetUnderexplainedImage(); peak_image_writer->SetInput(peak_image); peak_image_writer->SetFileName(out_folder + "Residual_" + name + ".nii.gz"); peak_image_writer->Update(); } } if (use_weights || use_num_streamlines) { MITK_INFO << "Using tract weights as scores"; unsigned int c = 0; for (auto fib : input_candidates) { int mod = 1; float score = 0; if (use_weights) { score = fib->GetFiberWeight(0); mod = 100000; } else if (use_num_streamlines) score = fib->GetNumFibers(); fib->ColorFibersByOrientation(); std::string bundle_name = ist::GetFilenameWithoutExtension(candidate_tract_files.at(c)); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect mitk::IOUtil::Save(fib, out_folder + boost::lexical_cast(static_cast(mod*score)) + "_" + bundle_name + ".fib"); unsigned int num_voxels = 0; { itk::TractDensityImageFilter< ItkUcharImageType >::Pointer masks_filter = itk::TractDensityImageFilter< ItkUcharImageType >::New(); masks_filter->SetInputImage(mask); masks_filter->SetBinaryOutput(true); masks_filter->SetFiberBundle(fib); masks_filter->SetUseImageGeometry(true); masks_filter->Update(); num_voxels = masks_filter->GetNumCoveredVoxels(); } float weight_sum = 0; for (unsigned int i=0; iGetNumFibers(); i++) weight_sum += fib->GetFiberWeight(i); std::cout.rdbuf (old); // <-- restore logfile << bundle_name << " " << setprecision(5) << score << " " << num_voxels << " " << fib->GetNumFibers() << " " << weight_sum << "\n"; ++c; } } else if (!greedy_add) { MITK_INFO << "Fit candidate tracts"; itk::FitFibersToImageFilter::Pointer fitter = itk::FitFibersToImageFilter::New(); fitter->SetLambda(static_cast(lambda)); fitter->SetFilterOutliers(filter_outliers); fitter->SetVerbose(true); fitter->SetPeakImage(peak_image); fitter->SetMaskImage(mask); fitter->SetTractograms(input_candidates); fitter->SetFitIndividualFibers(true); if (regu=="MSM") fitter->SetRegularization(VnlCostFunction::REGU::MSM); else if (regu=="Variance") fitter->SetRegularization(VnlCostFunction::REGU::VARIANCE); else if (regu=="Lasso") fitter->SetRegularization(VnlCostFunction::REGU::LASSO); else if (regu=="VoxelVariance") fitter->SetRegularization(VnlCostFunction::REGU::VOXEL_VARIANCE); else if (regu=="GroupLasso") fitter->SetRegularization(VnlCostFunction::REGU::GROUP_LASSO); else if (regu=="GroupVariance") fitter->SetRegularization(VnlCostFunction::REGU::GROUP_VARIANCE); else if (regu=="NONE") fitter->SetRegularization(VnlCostFunction::REGU::NONE); fitter->Update(); vnl_vector rms_diff = fitter->GetRmsDiffPerBundle(); unsigned int c = 0; for (auto fib : input_candidates) { std::string bundle_name = ist::GetFilenameWithoutExtension(candidate_tract_files.at(c)); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect if (filter_zero_weights) fib = fib->FilterByWeights(0); mitk::IOUtil::Save(fib, out_folder + boost::lexical_cast((int)(100000*rms_diff[c])) + "_" + bundle_name + ".fib"); unsigned int num_voxels = 0; { itk::TractDensityImageFilter< ItkUcharImageType >::Pointer masks_filter = itk::TractDensityImageFilter< ItkUcharImageType >::New(); masks_filter->SetInputImage(mask); masks_filter->SetBinaryOutput(true); masks_filter->SetFiberBundle(fib); masks_filter->SetUseImageGeometry(true); masks_filter->Update(); num_voxels = masks_filter->GetNumCoveredVoxels(); } float weight_sum = 0; for (unsigned int i=0; iGetNumFibers(); i++) weight_sum += fib->GetFiberWeight(i); std::cout.rdbuf (old); // <-- restore logfile << bundle_name << " " << setprecision(5) << rms_diff[c] << " " << num_voxels << " " << fib->GetNumFibers() << " " << weight_sum << "\n"; ++c; } mitk::FiberBundle::Pointer out_fib = mitk::FiberBundle::New(); out_fib = out_fib->AddBundles(input_candidates); out_fib->ColorFibersByFiberWeights(false, true); mitk::IOUtil::Save(out_fib, out_folder + "AllCandidates.fib"); peak_image = fitter->GetUnderexplainedImage(); peak_image_writer->SetInput(peak_image); peak_image_writer->SetFileName(out_folder + "Residual_AllCandidates.nii.gz"); peak_image_writer->Update(); } else { MITK_INFO << "RMSE: " << setprecision(5) << rmse; // fitter->SetPeakImage(peak_image); // Iteratively add candidate bundles in a greedy manner while (!input_candidates.empty()) { double next_rmse = rmse; mitk::FiberBundle::Pointer best_candidate = nullptr; PeakImgType::Pointer best_candidate_peak_image = nullptr; for (unsigned int i=0; iSetLambda(static_cast(lambda)); fitter->SetFilterOutliers(filter_outliers); fitter->SetVerbose(false); fitter->SetPeakImage(peak_image); fitter->SetMaskImage(mask); // ****************************** fitter->SetTractograms({input_candidates.at(i)}); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect fitter->Update(); std::cout.rdbuf (old); // <-- restore double candidate_rmse = fitter->GetRMSE(); if (candidate_rmseGetTractograms().at(0); best_candidate_peak_image = fitter->GetUnderexplainedImage(); } } if (best_candidate.IsNull()) break; // fitter->SetPeakImage(peak_image); peak_image = best_candidate_peak_image; unsigned int i=0; std::vector< mitk::FiberBundle::Pointer > remaining_candidates; std::vector< std::string > remaining_candidate_files; for (auto fib : input_candidates) { if (fib!=best_candidate) { remaining_candidates.push_back(fib); remaining_candidate_files.push_back(candidate_tract_files.at(i)); } else name = ist::GetFilenameWithoutExtension(candidate_tract_files.at(i)); ++i; } input_candidates = remaining_candidates; candidate_tract_files = remaining_candidate_files; iteration++; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect // Save winning candidate if (filter_zero_weights) best_candidate = best_candidate->FilterByWeights(0); mitk::IOUtil::Save(best_candidate, out_folder + boost::lexical_cast(iteration) + "_" + name + ".fib"); peak_image_writer->SetInput(peak_image); peak_image_writer->SetFileName(out_folder + boost::lexical_cast(iteration) + "_" + name + ".nrrd"); peak_image_writer->Update(); std::cout.rdbuf (old); // <-- restore // logfile << name << " " << setprecision(5) << score << " " << num_voxels << " " << fib->GetNumFibers() << " " << weight_sum << "\n"; } } clock.Stop(); int h = static_cast(clock.GetTotal()/3600); int m = (static_cast(clock.GetTotal())%3600)/60; int s = static_cast(clock.GetTotal())%60; MITK_INFO << "Plausibility estimation took " << h << "h, " << m << "m and " << s << "s"; logfile.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/TractographyEvaluation/CalculateOverlap.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/CalculateOverlap.cpp index 1c223eb..48dfdc2 100644 --- a/Modules/DiffusionCmdApps/TractographyEvaluation/CalculateOverlap.cpp +++ b/Modules/DiffusionCmdApps/TractographyEvaluation/CalculateOverlap.cpp @@ -1,108 +1,108 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; typedef itk::Image ItkUIntImgType; /*! \brief */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Calculate Overlap"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("tractogram", "", mitkCommandLineParser::String, "", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("mask", "", mitkCommandLineParser::String, "", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("peaks", "", mitkCommandLineParser::String, "", "", us::Any(), true, false, false, mitkCommandLineParser::Input); + parser.addArgument("tractogram", "", mitkDiffusionCommandLineParser::String, "", "", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("mask", "", mitkDiffusionCommandLineParser::String, "", "", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("peaks", "", mitkDiffusionCommandLineParser::String, "", "", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string input_tractogram = us::any_cast(parsedArgs["tractogram"]); std::string mask_file = us::any_cast(parsedArgs["mask"]); try { mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(input_tractogram); mitk::Image::Pointer mask = mitk::IOUtil::Load(mask_file); ItkFloatImgType::Pointer itk_mask; mitk::CastToItkImage(mask, itk_mask); mitk::PeakImage::ItkPeakImageType::Pointer peaks = nullptr; if (parsedArgs.count("peaks")) { mitk::Image::Pointer mitk_peaks = mitk::IOUtil::Load(us::any_cast(parsedArgs["peaks"])); typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(mitk_peaks); caster->Update(); peaks = caster->GetOutput(); float overlap = 0; float directional_overlap = 0; std::tie(directional_overlap, overlap) = fib->GetDirectionalOverlap(itk_mask, peaks); MITK_INFO << "Overlap<<" << overlap; MITK_INFO << "DirectionalOverlap<<" << directional_overlap; } else MITK_INFO << "Overlap<<" << fib->GetOverlap(itk_mask); } 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/TractographyEvaluation/CheckEpsAndOverlap.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/CheckEpsAndOverlap.cpp index 8f0bb5d..6a28787 100644 --- a/Modules/DiffusionCmdApps/TractographyEvaluation/CheckEpsAndOverlap.cpp +++ b/Modules/DiffusionCmdApps/TractographyEvaluation/CheckEpsAndOverlap.cpp @@ -1,98 +1,98 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; typedef itk::Image ItkUcharImgType; typedef itk::Image ItkUIntImgType; /*! \brief */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Calculate Overlap"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("tractogram", "", mitkCommandLineParser::String, "", "file", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("overlap_image", "", mitkCommandLineParser::String, "", "file", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("ep_image", "", mitkCommandLineParser::String, "", "file", us::Any(), false, false, false, mitkCommandLineParser::Input); + parser.addArgument("tractogram", "", mitkDiffusionCommandLineParser::String, "", "file", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("overlap_image", "", mitkDiffusionCommandLineParser::String, "", "file", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("ep_image", "", mitkDiffusionCommandLineParser::String, "", "file", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string input_tractogram = us::any_cast(parsedArgs["tractogram"]); std::string mask_file = us::any_cast(parsedArgs["overlap_image"]); std::string mask_file2 = us::any_cast(parsedArgs["ep_image"]); try { mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(input_tractogram); mitk::Image::Pointer mask = mitk::IOUtil::Load(mask_file); mitk::Image::Pointer mask2 = mitk::IOUtil::Load(mask_file2); ItkUcharImgType::Pointer itk_mask; mitk::CastToItkImage(mask, itk_mask); ItkUcharImgType::Pointer itk_mask2; mitk::CastToItkImage(mask2, itk_mask2); float ol = fib->GetOverlap(itk_mask); float ep = fib->GetNumEpFractionInMask(itk_mask2, true); MITK_INFO << "Overlap<<" << ol; MITK_INFO << "EP-Fraction<<" << ep; } 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/TractographyEvaluation/ExtractSimilarTracts.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/ExtractSimilarTracts.cpp index d04dcb3..4c1952c 100644 --- a/Modules/DiffusionCmdApps/TractographyEvaluation/ExtractSimilarTracts.cpp +++ b/Modules/DiffusionCmdApps/TractographyEvaluation/ExtractSimilarTracts.cpp @@ -1,199 +1,199 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include -#include +#include #include #include #include #include #include #include #include #include #include typedef itk::Image ItkFloatImgType; /*! \brief Spatially cluster fibers */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Extract Similar Tracts"); parser.setCategory("Fiber Tracking Evaluation"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input fiber bundle (.fib, .trk, .tck)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("ref_tracts", "", mitkCommandLineParser::StringList, "Ref. Tracts:", "reference tracts (.fib, .trk, .tck)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("ref_masks", "", mitkCommandLineParser::StringList, "Ref. Masks:", "reference bundle masks", us::Any(), true, false, false, mitkCommandLineParser::Input); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input fiber bundle (.fib, .trk, .tck)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("ref_tracts", "", mitkDiffusionCommandLineParser::StringList, "Ref. Tracts:", "reference tracts (.fib, .trk, .tck)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("ref_masks", "", mitkDiffusionCommandLineParser::StringList, "Ref. Masks:", "reference bundle masks", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("distance", "", mitkCommandLineParser::Int, "Distance:", "", 10); - parser.addArgument("metric", "", mitkCommandLineParser::String, "Metric:", "EU_MEAN (default), EU_STD, EU_MAX"); - parser.addArgument("subsample", "", mitkCommandLineParser::Float, "Subsampling factor:", "Only use specified fraction of input fibers", 1.0); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("distance", "", mitkDiffusionCommandLineParser::Int, "Distance:", "", 10); + parser.addArgument("metric", "", mitkDiffusionCommandLineParser::String, "Metric:", "EU_MEAN (default), EU_STD, EU_MAX"); + parser.addArgument("subsample", "", mitkDiffusionCommandLineParser::Float, "Subsampling factor:", "Only use specified fraction of input fibers", 1.0); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string in_fib = us::any_cast(parsedArgs["i"]); std::string out_root = us::any_cast(parsedArgs["o"]); - mitkCommandLineParser::StringContainerType ref_bundle_files = us::any_cast(parsedArgs["ref_tracts"]); - mitkCommandLineParser::StringContainerType ref_mask_files; + mitkDiffusionCommandLineParser::StringContainerType ref_bundle_files = us::any_cast(parsedArgs["ref_tracts"]); + mitkDiffusionCommandLineParser::StringContainerType ref_mask_files; if (parsedArgs.count("ref_masks")) - ref_mask_files = us::any_cast(parsedArgs["ref_masks"]); + ref_mask_files = us::any_cast(parsedArgs["ref_masks"]); if (ref_mask_files.size()>0 && ref_mask_files.size()!=ref_bundle_files.size()) { MITK_INFO << "If reference masks are used, there has to be one mask per reference tract."; return EXIT_FAILURE; } int distance = 10; if (parsedArgs.count("distance")) distance = us::any_cast(parsedArgs["distance"]); std::string metric = "EU_MEAN"; if (parsedArgs.count("metric")) metric = us::any_cast(parsedArgs["metric"]); float subsample = 1.0; if (parsedArgs.count("subsample")) subsample = us::any_cast(parsedArgs["subsample"]); try { mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(in_fib); std::srand(0); if (subsample<1.0f) fib = fib->SubsampleFibers(subsample, true); mitk::FiberBundle::Pointer resampled_fib = fib->GetDeepCopy(); resampled_fib->ResampleToNumPoints(12); auto ref_fibs = mitk::DiffusionDataIOHelper::load_fibs(ref_bundle_files); auto ref_masks = mitk::DiffusionDataIOHelper::load_itk_images(ref_mask_files); std::vector< float > distances; distances.push_back(distance); mitk::FiberBundle::Pointer extracted = mitk::FiberBundle::New(nullptr); unsigned int c = 0; for (auto ref_fib : ref_fibs) { MITK_INFO << "Extracting " << ist::GetFilenameName(ref_bundle_files.at(c)); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect try { itk::TractClusteringFilter::Pointer segmenter = itk::TractClusteringFilter::New(); // calculate centroids from reference bundle { itk::TractClusteringFilter::Pointer clusterer = itk::TractClusteringFilter::New(); clusterer->SetDistances({10,20,30}); clusterer->SetTractogram(ref_fib); clusterer->SetMetrics({new mitk::ClusteringMetricEuclideanStd()}); clusterer->SetMergeDuplicateThreshold(0.0); clusterer->Update(); std::vector tracts = clusterer->GetOutCentroids(); ref_fib = mitk::FiberBundle::New(nullptr); ref_fib = ref_fib->AddBundles(tracts); mitk::IOUtil::Save(ref_fib, out_root + "centroids_" + ist::GetFilenameName(ref_bundle_files.at(c))); segmenter->SetInCentroids(ref_fib); } // segment tract if (cSetFilterMask(ref_masks.at(c)); segmenter->SetOverlapThreshold(0.8f); } segmenter->SetDistances(distances); segmenter->SetTractogram(resampled_fib); segmenter->SetMergeDuplicateThreshold(0.0); segmenter->SetDoResampling(false); if (metric=="EU_MEAN") segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanMean()}); else if (metric=="EU_STD") segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanStd()}); else if (metric=="EU_MAX") segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanMax()}); segmenter->Update(); std::vector< std::vector< unsigned int > > clusters = segmenter->GetOutFiberIndices(); if (clusters.size()>0) { vtkSmartPointer weights = vtkSmartPointer::New(); mitk::FiberBundle::Pointer result = mitk::FiberBundle::New(nullptr); std::vector< mitk::FiberBundle::Pointer > result_fibs; for (unsigned int cluster_index=0; cluster_indexGeneratePolyDataByIds(clusters.at(cluster_index), weights))); result = result->AddBundles(result_fibs); extracted = extracted->AddBundle(result); mitk::IOUtil::Save(result, out_root + "extracted_" + ist::GetFilenameName(ref_bundle_files.at(c))); fib = mitk::FiberBundle::New(fib->GeneratePolyDataByIds(clusters.back(), weights)); resampled_fib = mitk::FiberBundle::New(resampled_fib->GeneratePolyDataByIds(clusters.back(), weights)); } } catch(itk::ExceptionObject& excpt) { MITK_INFO << "Exception while processing " << ist::GetFilenameName(ref_bundle_files.at(c)); MITK_INFO << excpt.GetDescription(); } catch(std::exception& excpt) { MITK_INFO << "Exception while processing " << ist::GetFilenameName(ref_bundle_files.at(c)); MITK_INFO << excpt.what(); } std::cout.rdbuf (old); // <-- restore if (fib->GetNumFibers()==0) break; ++c; } MITK_INFO << "Extracted streamlines: " << extracted->GetNumFibers(); mitk::IOUtil::Save(extracted, out_root + "extracted_streamlines.trk"); MITK_INFO << "Residual streamlines: " << fib->GetNumFibers(); mitk::IOUtil::Save(fib, out_root + "residual_streamlines.trk"); } 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/TractographyEvaluation/GetOverlappingTracts.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/GetOverlappingTracts.cpp index 67bad8e..a095bab 100644 --- a/Modules/DiffusionCmdApps/TractographyEvaluation/GetOverlappingTracts.cpp +++ b/Modules/DiffusionCmdApps/TractographyEvaluation/GetOverlappingTracts.cpp @@ -1,167 +1,167 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; /*! \brief Extract fibers from a tractogram using binary image ROIs */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Get Overlapping Tracts"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setDescription("Find tracts that overlap with the reference masks or tracts"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::StringList, "Input:", "input tractograms (.fib/.trk/.tck/.dcm)", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output Folder:", "move input tracts that do/don't overlap here", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("reference", "", mitkCommandLineParser::StringList, "Reference:", "reference tractograms or mask images", us::Any(), false, false, false, mitkCommandLineParser::Input); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::StringList, "Input:", "input tractograms (.fib/.trk/.tck/.dcm)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output Folder:", "move input tracts that do/don't overlap here", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("reference", "", mitkDiffusionCommandLineParser::StringList, "Reference:", "reference tractograms or mask images", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); - parser.addArgument("overlap_fraction", "", mitkCommandLineParser::Float, "Overlap fraction:", "", 0.9); - parser.addArgument("use_any_overlap", "", mitkCommandLineParser::Bool, "Use any overlap:", "Don't find maximum overlap but use first overlap larger threshold"); - parser.addArgument("dont_save_tracts", "", mitkCommandLineParser::Bool, "Don't save tracts:", "if true, only text files documenting the overlaps are saved and no tract files are copied"); + parser.addArgument("overlap_fraction", "", mitkDiffusionCommandLineParser::Float, "Overlap fraction:", "", 0.9); + parser.addArgument("use_any_overlap", "", mitkDiffusionCommandLineParser::Bool, "Use any overlap:", "Don't find maximum overlap but use first overlap larger threshold"); + parser.addArgument("dont_save_tracts", "", mitkDiffusionCommandLineParser::Bool, "Don't save tracts:", "if true, only text files documenting the overlaps are saved and no tract files are copied"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; - mitkCommandLineParser::StringContainerType input = us::any_cast(parsedArgs["i"]); - mitkCommandLineParser::StringContainerType reference = us::any_cast(parsedArgs["reference"]); + mitkDiffusionCommandLineParser::StringContainerType input = us::any_cast(parsedArgs["i"]); + mitkDiffusionCommandLineParser::StringContainerType reference = us::any_cast(parsedArgs["reference"]); std::string out_folder = us::any_cast(parsedArgs["o"]); bool use_any_overlap = false; if (parsedArgs.count("use_any_overlap")) use_any_overlap = us::any_cast(parsedArgs["use_any_overlap"]); bool dont_save_tracts = false; if (parsedArgs.count("dont_save_tracts")) dont_save_tracts = us::any_cast(parsedArgs["dont_save_tracts"]); float overlap_threshold = 0.9; if (parsedArgs.count("overlap_fraction")) overlap_threshold = us::any_cast(parsedArgs["overlap_fraction"]); try { MITK_INFO << "Loading references"; std::vector< std::string > reference_names; auto masks = mitk::DiffusionDataIOHelper::load_itk_images(reference, &reference_names); auto reference_fibs = mitk::DiffusionDataIOHelper::load_fibs(reference, &reference_names); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect itk::TractDensityImageFilter< ItkFloatImgType >::Pointer filter = itk::TractDensityImageFilter< ItkFloatImgType >::New(); filter->SetUpsamplingFactor(0.25); filter->SetBinaryOutput(true); for (auto fib : reference_fibs) { filter->SetFiberBundle(fib); filter->Update(); masks.push_back(filter->GetOutput()); } std::cout.rdbuf (old); // <-- restore MITK_INFO << "Loading input tractograms"; std::vector< std::string > input_names; auto input_fibs = mitk::DiffusionDataIOHelper::load_fibs(input, &input_names); MITK_INFO << "Finding overlaps"; ofstream logfile; logfile.open (out_folder + "Overlaps.txt"); ofstream logfile2; logfile2.open (out_folder + "AllOverlaps.txt"); boost::progress_display disp(input.size()); unsigned int c = 0; for (auto fib : input_fibs) { ++disp; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect bool is_overlapping = false; float overlap = 0; float max_overlap = 0; std::string max_ref = "-"; int i = 0; std::string overlap_string = ist::GetFilenameWithoutExtension(input_names.at(c)); for (auto m : masks) { overlap = fib->GetOverlap(m); if (overlap>max_overlap) { max_overlap = overlap; max_ref = ist::GetFilenameWithoutExtension(reference_names.at(i)); } if (use_any_overlap && overlap>=overlap_threshold) break; overlap_string += " " + ist::GetFilenameWithoutExtension(reference_names.at(i)) + " " + boost::lexical_cast(overlap); ++i; } if (overlap>=overlap_threshold) is_overlapping = true; logfile << ist::GetFilenameWithoutExtension(input_names.at(c)) << " - " << max_ref << ": " << boost::lexical_cast(max_overlap) << "\n"; logfile2 << overlap_string << "\n"; if (!dont_save_tracts && is_overlapping) ist::CopyAFile(input_names.at(c), out_folder + ist::GetFilenameName(input_names.at(c))); std::cout.rdbuf (old); // <-- restore ++c; } logfile.close(); logfile2.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/TractographyEvaluation/MergeOverlappingTracts.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/MergeOverlappingTracts.cpp index 93042bb..bda677d 100644 --- a/Modules/DiffusionCmdApps/TractographyEvaluation/MergeOverlappingTracts.cpp +++ b/Modules/DiffusionCmdApps/TractographyEvaluation/MergeOverlappingTracts.cpp @@ -1,214 +1,214 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include typedef itk::Image ItkFloatImgType; typedef itk::Image ItkUIntImgType; /*! \brief */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Merge Overlapping Tracts"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::StringList, "Input:", "input tracts", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output Folder:", "output folder", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("overlap", "", mitkCommandLineParser::Float, "Overlap threshold:", "Tracts with overlap larger than this threshold are merged", 0.8, false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::StringList, "Input:", "input tracts", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output Folder:", "output folder", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("overlap", "", mitkDiffusionCommandLineParser::Float, "Overlap threshold:", "Tracts with overlap larger than this threshold are merged", 0.8, false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; - mitkCommandLineParser::StringContainerType input_folder = us::any_cast(parsedArgs["i"]); + mitkDiffusionCommandLineParser::StringContainerType input_folder = us::any_cast(parsedArgs["i"]); std::string out_folder = us::any_cast(parsedArgs["o"]); float overlap = 0.8; if (parsedArgs.count("overlap")) overlap = us::any_cast(parsedArgs["overlap"]); try { if (!ist::PathExists(out_folder)) ist::MakeDirectory(out_folder); std::vector< mitk::FiberBundle::Pointer > fibs = mitk::DiffusionDataIOHelper::load_fibs(input_folder); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect mitk::FiberBundle::Pointer combined = mitk::FiberBundle::New(); combined = combined->AddBundles(fibs); itk::TractsToFiberEndingsImageFilter< ItkFloatImgType >::Pointer endings = itk::TractsToFiberEndingsImageFilter< ItkFloatImgType >::New(); endings->SetFiberBundle(combined); endings->SetUpsamplingFactor(0.25); endings->Update(); ItkFloatImgType::Pointer ref_image = endings->GetOutput(); std::cout.rdbuf (old); // <-- restore for (int its = 0; its<3; its++) { std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect std::vector< ItkFloatImgType::Pointer > mask_images; for (auto fib : fibs) { itk::TractDensityImageFilter< ItkFloatImgType >::Pointer masks = itk::TractDensityImageFilter< ItkFloatImgType >::New(); masks->SetInputImage(ref_image); masks->SetBinaryOutput(true); masks->SetFiberBundle(fib); masks->SetUseImageGeometry(true); masks->Update(); mask_images.push_back(masks->GetOutput()); } int r=0; vnl_matrix< int > mat; mat.set_size(mask_images.size(), mask_images.size()); mat.fill(0); for (auto m1 : mask_images) { float max_overlap = overlap; int c = 0; for (auto m2 : mask_images) { if (c<=r) { ++c; continue; } itk::ImageRegionConstIterator it1(m1, m1->GetLargestPossibleRegion()); itk::ImageRegionConstIterator it2(m2, m2->GetLargestPossibleRegion()); unsigned int c1 = 0; unsigned int c2 = 0; unsigned int intersect = 0; while( !it1.IsAtEnd() ) { if( it1.Get()>0 && it2.Get()>0) ++intersect; if(it1.Get()>0) ++c1; if(it2.Get()>0) ++c2; ++it1; ++it2; } if ( (float)intersect/c1>max_overlap ) { max_overlap = (float)intersect/c1; mat.put(r,c, 1); } if ( (float)intersect/c2>max_overlap ) { max_overlap = (float)intersect/c2; mat.put(r,c, 1); } ++c; } ++r; } std::vector< mitk::FiberBundle::Pointer > out_fibs; std::vector< bool > used; for (unsigned int i=0; i0) { fib = fib->AddBundle(fibs.at(c)); used[c] = true; } } out_fibs.push_back(fib); } std::cout.rdbuf (old); // <-- restore MITK_INFO << fibs.size() << " --> " << out_fibs.size(); if (fibs.size()==out_fibs.size()) break; fibs = out_fibs; } int c = 0; for (auto fib : fibs) { std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect mitk::IOUtil::Save(fib, out_folder + "/bundle_" + boost::lexical_cast(c) + ".trk"); std::cout.rdbuf (old); // <-- restore ++c; } } 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/TractographyEvaluation/PeaksAngularError.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/PeaksAngularError.cpp index 57a3081..741d24a 100644 --- a/Modules/DiffusionCmdApps/TractographyEvaluation/PeaksAngularError.cpp +++ b/Modules/DiffusionCmdApps/TractographyEvaluation/PeaksAngularError.cpp @@ -1,190 +1,190 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include -#include "mitkCommandLineParser.h" +#include "mitkDiffusionCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include typedef itk::Image< unsigned char, 3 > ItkUcharImageType; /*! \brief Calculate angular error between two sets of directions stored in multiple 3D vector images where each pixel corresponds to a vector (itk::Image< itk::Vector< float, 3>, 3 >) */ int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setArgumentPrefix("--", "-"); - parser.addArgument("test", "", mitkCommandLineParser::StringList, "Test images", "test direction images", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("reference", "", mitkCommandLineParser::StringList, "Reference images", "reference direction images", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output folder", "output folder", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("masks", "", mitkCommandLineParser::StringList, "Mask(s)", "mask image(s)", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("verbose", "", mitkCommandLineParser::Bool, "Verbose", "output error images"); - parser.addArgument("ignore_test", "", mitkCommandLineParser::Bool, "Ignore missing test", "don't increase error if no test directions are found"); - parser.addArgument("ignore_ref", "", mitkCommandLineParser::Bool, "Ignore ignore missing ref", "don't increase error if no ref directions are found"); + parser.addArgument("test", "", mitkDiffusionCommandLineParser::StringList, "Test images", "test direction images", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("reference", "", mitkDiffusionCommandLineParser::StringList, "Reference images", "reference direction images", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output folder", "output folder", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output); + parser.addArgument("masks", "", mitkDiffusionCommandLineParser::StringList, "Mask(s)", "mask image(s)", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input); + parser.addArgument("verbose", "", mitkDiffusionCommandLineParser::Bool, "Verbose", "output error images"); + parser.addArgument("ignore_test", "", mitkDiffusionCommandLineParser::Bool, "Ignore missing test", "don't increase error if no test directions are found"); + parser.addArgument("ignore_ref", "", mitkDiffusionCommandLineParser::Bool, "Ignore ignore missing ref", "don't increase error if no ref directions are found"); parser.setCategory("Fiber Tracking Evaluation"); parser.setTitle("Peaks Angular Error"); parser.setDescription("Calculate angular error between two sets of peak images (1-1 correspondence)"); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; - mitkCommandLineParser::StringContainerType testImages = us::any_cast(parsedArgs["test"]); - mitkCommandLineParser::StringContainerType referenceImages = us::any_cast(parsedArgs["reference"]); + mitkDiffusionCommandLineParser::StringContainerType testImages = us::any_cast(parsedArgs["test"]); + mitkDiffusionCommandLineParser::StringContainerType referenceImages = us::any_cast(parsedArgs["reference"]); - mitkCommandLineParser::StringContainerType maskImages; + mitkDiffusionCommandLineParser::StringContainerType maskImages; if (parsedArgs.count("masks")) - maskImages = us::any_cast(parsedArgs["masks"]); + maskImages = us::any_cast(parsedArgs["masks"]); std::string outRoot = us::any_cast(parsedArgs["o"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); bool ignore_test = false; if (parsedArgs.count("ignore_test")) ignore_test = us::any_cast(parsedArgs["ignore_test"]); bool ignore_ref = false; if (parsedArgs.count("ignore_ref")) ignore_ref = us::any_cast(parsedArgs["ignore_ref"]); try { typedef itk::ComparePeakImagesFilter< float > EvaluationFilterType; std::vector test_names; auto test_images = mitk::DiffusionDataIOHelper::load_itk_images(testImages, &test_names); // load reference directions std::vector ref_names; auto ref_images = mitk::DiffusionDataIOHelper::load_itk_images(referenceImages, &ref_names); // load/create mask image auto itkMaskImages = mitk::DiffusionDataIOHelper::load_itk_images(maskImages); if (test_images.size()!=ref_images.size()) mitkThrow() << "Matching number of test and reference image required!"; for (unsigned int i=0; iSetTestImage(test_images.at(i)); evaluationFilter->SetReferenceImage(ref_images.at(i)); if (iSetMaskImage(itkMaskImages.at(i)); evaluationFilter->SetIgnoreMissingTestDirections(ignore_test); evaluationFilter->SetIgnoreMissingRefDirections(ignore_ref); evaluationFilter->Update(); std::string ref_name = ist::GetFilenameWithoutExtension(ref_names.at(i)); std::string test_name = ist::GetFilenameWithoutExtension(test_names.at(i)); if (verbose) { mitk::LocaleSwitch localeSwitch("C"); EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); EvaluationFilterType::OutputImageType::Pointer lengthErrorImage = evaluationFilter->GetOutput(1); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; { WriterType::Pointer writer = WriterType::New(); std::string outfilename = outRoot; outfilename.append(ref_name + "_" + test_name + "_AngularError.nii.gz"); writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } { WriterType::Pointer writer = WriterType::New(); std::string outfilename = outRoot; outfilename.append(ref_name + "_" + test_name + "_LengthError.nii.gz"); writer->SetFileName(outfilename.c_str()); writer->SetInput(lengthErrorImage); writer->Update(); } } std::string logFile = outRoot; logFile.append("AngularErrors.csv"); bool add_header = true; if (ist::FileExists(logFile, true)) add_header = false; ofstream file; file.open (logFile.c_str(), std::fstream::app); std::string sens; if (add_header) sens.append("Test,Reference,Mean,Median,Maximum,Minimum,Stdev\n"); sens.append(test_name); sens.append(","); sens.append(ref_name); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append("\n"); std::cout << sens; file << sens; 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/TractographyEvaluation/ReferenceSimilarity.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/ReferenceSimilarity.cpp index 37e07f8..d4dd8c5 100644 --- a/Modules/DiffusionCmdApps/TractographyEvaluation/ReferenceSimilarity.cpp +++ b/Modules/DiffusionCmdApps/TractographyEvaluation/ReferenceSimilarity.cpp @@ -1,149 +1,149 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include -#include +#include #include #include #include #include #include #include #include typedef itk::Image< unsigned char, 3 > ItkUcharImageType; typedef itk::Image< float, 4 > ItkPeakImgType; int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Reference Similarity"); parser.setCategory("Fiber Tracking Evaluation"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i", mitkCommandLineParser::StringList, "Input Tracts:", "input tracts folder", us::Any(), false); - parser.addArgument("reference_tracts", "", mitkCommandLineParser::StringList, "", "", us::Any(), false); - parser.addArgument("reference_masks", "", mitkCommandLineParser::StringList, "", "", us::Any(), false); - parser.addArgument("reference_peaks", "", mitkCommandLineParser::StringList, "", "", us::Any(), false); + parser.addArgument("", "i", mitkDiffusionCommandLineParser::StringList, "Input Tracts:", "input tracts folder", us::Any(), false); + parser.addArgument("reference_tracts", "", mitkDiffusionCommandLineParser::StringList, "", "", us::Any(), false); + parser.addArgument("reference_masks", "", mitkDiffusionCommandLineParser::StringList, "", "", us::Any(), false); + parser.addArgument("reference_peaks", "", mitkDiffusionCommandLineParser::StringList, "", "", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "", "", us::Any(), false); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "", "", us::Any(), false); - parser.addArgument("fiber_points", "", mitkCommandLineParser::Int, "Fiber points:", "", 20); + parser.addArgument("fiber_points", "", mitkDiffusionCommandLineParser::Int, "Fiber points:", "", 20); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string out_folder = us::any_cast(parsedArgs["o"]); - mitkCommandLineParser::StringContainerType input_tract_files = us::any_cast(parsedArgs["i"]); - mitkCommandLineParser::StringContainerType reference_tract_files = us::any_cast(parsedArgs["reference_tracts"]); - mitkCommandLineParser::StringContainerType reference_mask_files = us::any_cast(parsedArgs["reference_masks"]); - mitkCommandLineParser::StringContainerType reference_peak_files = us::any_cast(parsedArgs["reference_peaks"]); + mitkDiffusionCommandLineParser::StringContainerType input_tract_files = us::any_cast(parsedArgs["i"]); + mitkDiffusionCommandLineParser::StringContainerType reference_tract_files = us::any_cast(parsedArgs["reference_tracts"]); + mitkDiffusionCommandLineParser::StringContainerType reference_mask_files = us::any_cast(parsedArgs["reference_masks"]); + mitkDiffusionCommandLineParser::StringContainerType reference_peak_files = us::any_cast(parsedArgs["reference_peaks"]); int fiber_points = 20; if (parsedArgs.count("fiber_points")) fiber_points = us::any_cast(parsedArgs["fiber_points"]); try { std::vector input_tract_names; std::vector ref_tract_names; std::vector< mitk::FiberBundle::Pointer > input_tracts = mitk::DiffusionDataIOHelper::load_fibs(input_tract_files, &input_tract_names); std::vector< mitk::FiberBundle::Pointer > reference_tracts = mitk::DiffusionDataIOHelper::load_fibs(reference_tract_files, &ref_tract_names); std::vector< ItkUcharImageType::Pointer > reference_masks = mitk::DiffusionDataIOHelper::load_itk_images(reference_mask_files); std::vector< ItkPeakImgType::Pointer > reference_peaks = mitk::DiffusionDataIOHelper::load_itk_images(reference_peak_files); MITK_INFO << "Calculating distances"; itk::TractDistanceFilter::Pointer distance_calculator = itk::TractDistanceFilter::New(); distance_calculator->SetNumPoints(fiber_points); distance_calculator->SetTracts1(input_tracts); distance_calculator->SetTracts2(reference_tracts); distance_calculator->SetMetrics({new mitk::ClusteringMetricEuclideanMean()}); distance_calculator->Update(); auto distances = distance_calculator->GetAllDistances(); vnl_matrix voxel_overlap; voxel_overlap.set_size(input_tracts.size(), reference_tracts.size()); vnl_matrix dir_overlap; dir_overlap.set_size(input_tracts.size(), reference_tracts.size()); MITK_INFO << "Calculating overlap"; boost::progress_display disp(input_tracts.size()*reference_tracts.size()); int r=0; for (auto fib : input_tracts) { int c=0; for (auto ref_mask : reference_masks) { // ++disp; // std::streambuf *old = cout.rdbuf(); // <-- save // std::stringstream ss; // std::cout.rdbuf (ss.rdbuf()); // <-- redirect float overlap = 0; float directional_overlap = 0; std::tie(directional_overlap, overlap) = fib->GetDirectionalOverlap(ref_mask, reference_peaks.at(c)); voxel_overlap[r][c] = overlap; dir_overlap[r][c] = directional_overlap; // std::cout.rdbuf (old); // <-- restore ++c; } ++r; } ofstream logfile; logfile.open(out_folder + "ref_tract_names.txt"); for (unsigned int i=0; i -#include +#include #include #include #include #include #include #include #include int main(int argc, char* argv[]) { - mitkCommandLineParser parser; + mitkDiffusionCommandLineParser parser; parser.setTitle("Tract Distance"); parser.setCategory("Fiber Processing"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); - parser.addArgument("", "i1", mitkCommandLineParser::StringList, "Input tracts 1:", "input tracts 1", us::Any(), false); - parser.addArgument("", "i2", mitkCommandLineParser::StringList, "Input tracts 2:", "input tracts 2", us::Any(), false); - parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output logfile", us::Any(), false); + parser.addArgument("", "i1", mitkDiffusionCommandLineParser::StringList, "Input tracts 1:", "input tracts 1", us::Any(), false); + parser.addArgument("", "i2", mitkDiffusionCommandLineParser::StringList, "Input tracts 2:", "input tracts 2", us::Any(), false); + parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output logfile", us::Any(), false); - parser.addArgument("fiber_points", "", mitkCommandLineParser::Int, "Fiber points:", "", 12); - parser.addArgument("metrics", "", mitkCommandLineParser::StringList, "Metrics:", "EU_MEAN (default), EU_STD, EU_MAX"); - parser.addArgument("metric_weights", "", mitkCommandLineParser::StringList, "Metric weights:", "add one float weight for each used metric"); + parser.addArgument("fiber_points", "", mitkDiffusionCommandLineParser::Int, "Fiber points:", "", 12); + parser.addArgument("metrics", "", mitkDiffusionCommandLineParser::StringList, "Metrics:", "EU_MEAN (default), EU_STD, EU_MAX"); + parser.addArgument("metric_weights", "", mitkDiffusionCommandLineParser::StringList, "Metric weights:", "add one float weight for each used metric"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; - mitkCommandLineParser::StringContainerType t1_folder = us::any_cast(parsedArgs["i1"]); - mitkCommandLineParser::StringContainerType t2_folder = us::any_cast(parsedArgs["i2"]); + mitkDiffusionCommandLineParser::StringContainerType t1_folder = us::any_cast(parsedArgs["i1"]); + mitkDiffusionCommandLineParser::StringContainerType t2_folder = us::any_cast(parsedArgs["i2"]); std::string out_file = us::any_cast(parsedArgs["o"]); int fiber_points = 12; if (parsedArgs.count("fiber_points")) fiber_points = us::any_cast(parsedArgs["fiber_points"]); std::vector< std::string > metric_strings = {"EU_MEAN"}; if (parsedArgs.count("metrics")) - metric_strings = us::any_cast(parsedArgs["metrics"]); + metric_strings = us::any_cast(parsedArgs["metrics"]); std::vector< std::string > metric_weights = {"1.0"}; if (parsedArgs.count("metric_weights")) - metric_weights = us::any_cast(parsedArgs["metric_weights"]); + metric_weights = us::any_cast(parsedArgs["metric_weights"]); if (metric_strings.size()!=metric_weights.size()) { MITK_INFO << "Each metric needs an associated metric weight!"; return EXIT_FAILURE; } try { std::vector t1_files; std::vector< mitk::FiberBundle::Pointer > tractograms1 = mitk::DiffusionDataIOHelper::load_fibs(t1_folder, &t1_files); std::vector t2_files; std::vector< mitk::FiberBundle::Pointer > tractograms2 = mitk::DiffusionDataIOHelper::load_fibs(t2_folder, &t2_files); MITK_INFO << "Loaded " << tractograms1.size() << " source tractograms."; MITK_INFO << "Loaded " << tractograms2.size() << " target tractograms."; itk::TractDistanceFilter::Pointer distance_calculator = itk::TractDistanceFilter::New(); distance_calculator->SetNumPoints(fiber_points); distance_calculator->SetTracts1(tractograms1); distance_calculator->SetTracts2(tractograms2); std::vector< mitk::ClusteringMetric* > metrics; int mc = 0; for (auto m : metric_strings) { float w = boost::lexical_cast(metric_weights.at(mc)); MITK_INFO << "Metric: " << m << " (w=" << w << ")"; if (m=="EU_MEAN") metrics.push_back({new mitk::ClusteringMetricEuclideanMean()}); else if (m=="EU_STD") metrics.push_back({new mitk::ClusteringMetricEuclideanStd()}); else if (m=="EU_MAX") metrics.push_back({new mitk::ClusteringMetricEuclideanMax()}); metrics.back()->SetScale(w); mc++; } if (metrics.empty()) { MITK_INFO << "No metric selected!"; return EXIT_FAILURE; } distance_calculator->SetMetrics(metrics); distance_calculator->Update(); MITK_INFO << "Distances:"; auto distances = distance_calculator->GetMinDistances(); auto indices = distance_calculator->GetMinIndices(); ofstream logfile; logfile.open (out_file); for (unsigned int i=0; i +#include +#include "mitkDiffusionCommandLineParser.h" + +mitkDiffusionCommandLineParser::mitkDiffusionCommandLineParser() : mitkCommandLineParser::mitkCommandLineParser() +{ + +} + +std::map mitkDiffusionCommandLineParser::parseArguments(const StringContainerType &arguments, bool *ok) +{ + for (unsigned int i = 1; i < arguments.size(); ++i) + { + std::string argument = arguments.at(i); + + if (!argument.compare("--version")) + { + std::cout << "MITK Diffusion git commit hash: " << MITKDIFFUSION_REVISION << std::endl; + std::cout << "MITK Diffusion branch name: " << MITKDIFFUSION_REVISION_NAME << std::endl; + } + } + + return mitkCommandLineParser::parseArguments(arguments, ok); +} + +std::map mitkDiffusionCommandLineParser::parseArguments(int argc, char **argv, bool *ok) +{ + std::cout << "Running Command Line Utility *" << Title << "*" << std::endl; + StringContainerType arguments; + + // Create a StringContainerType of arguments + for (int i = 0; i < argc; ++i) + arguments.push_back(argv[i]); + + return this->parseArguments(arguments, ok); +} diff --git a/Modules/DiffusionCmdApps/mitkDiffusionCommandLineParser.h b/Modules/DiffusionCmdApps/mitkDiffusionCommandLineParser.h new file mode 100644 index 0000000..09af541 --- /dev/null +++ b/Modules/DiffusionCmdApps/mitkDiffusionCommandLineParser.h @@ -0,0 +1,37 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef __mitkDiffusionCommandLineParser_h +#define __mitkDiffusionCommandLineParser_h + +#include +#include + +class MITKDIFFUSIONCMDAPPS_EXPORT mitkDiffusionCommandLineParser : public mitkCommandLineParser +{ +public: + mitkDiffusionCommandLineParser(); + + std::map parseArguments(const StringContainerType &arguments, bool *ok = nullptr); + std::map parseArguments(int argc, char **argv, bool *ok = nullptr); + +private: + +}; + + + +#endif diff --git a/Modules/DiffusionCore/CMakeLists.txt b/Modules/DiffusionCore/CMakeLists.txt index f633eb1..c9815c0 100644 --- a/Modules/DiffusionCore/CMakeLists.txt +++ b/Modules/DiffusionCore/CMakeLists.txt @@ -1,24 +1,28 @@ # With apple gcc 4.2.1 the following waring leads to an build error if boost is enabled if(APPLE) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=empty-body" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() MITK_CREATE_MODULE( SUBPROJECTS MITK-Diffusion INCLUDE_DIRS Algorithms Algorithms/Reconstruction Algorithms/Registration Algorithms/Reconstruction/MultishellProcessing Algorithms/Reconstruction/FittingFunctions DicomImport IODataStructures/DiffusionWeightedImages IODataStructures/Properties IODataStructures Rendering ${CMAKE_CURRENT_BINARY_DIR} DEPENDS MitkMapperExt MitkPlanarFigure MitkImageExtraction MitkDICOMReader MitkMatchPointRegistration PACKAGE_DEPENDS PUBLIC VTK|vtkFiltersProgrammable Vigra HDF5 ) if(MSVC) mitkFunctionCheckCAndCXXCompilerFlags("/wd4005" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() add_subdirectory(Testing) if(MITK_USE_Python) MITK_INSTALL(FILES PythonRequirements.txt) endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/mitkDiffusionImagingConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/mitkDiffusionImagingConfigure.h) + +mitkFunctionGetVersion(${CMAKE_CURRENT_SOURCE_DIR} MITKDIFFUSION) +mitkFunctionGetVersionDescription(${CMAKE_CURRENT_SOURCE_DIR} MITKDIFFUSION) +configure_file(mitkDiffusionVersion.h.in ${MITK_BINARY_DIR}/mitkDiffusionVersion.h) diff --git a/Modules/DiffusionCore/mitkDiffusionVersion.h.in b/Modules/DiffusionCore/mitkDiffusionVersion.h.in new file mode 100644 index 0000000..84de9ca --- /dev/null +++ b/Modules/DiffusionCore/mitkDiffusionVersion.h.in @@ -0,0 +1,8 @@ +/* + mitkDiffusionVersion.h + this file is generated. Do not change! +*/ + +#define MITKDIFFUSION_REVISION "@MITKDIFFUSION_REVISION_ID@" +#define MITKDIFFUSION_REVISION_NAME "@MITKDIFFUSION_REVISION_NAME@" +#define MITKDIFFUSION_REVISION_DESC "@MITKDIFFUSION_REVISION_DESC@"