diff --git a/Modules/DiffusionImaging/MiniApps/BatchedFolderRegistration.cpp b/Modules/DiffusionImaging/MiniApps/BatchedFolderRegistration.cpp index 9a7d9f325d..5f6427c54b 100644 --- a/Modules/DiffusionImaging/MiniApps/BatchedFolderRegistration.cpp +++ b/Modules/DiffusionImaging/MiniApps/BatchedFolderRegistration.cpp @@ -1,482 +1,487 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" // CTK #include "ctkCommandLineParser.h" #include #include #include #include #include #include #include "mitkNrrdDiffusionImageWriter.h" #include // ITK #include #include #include "itkLinearInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkIdentityTransform.h" #include "itkResampleImageFilter.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.substr(filename.length() -postfix.length() ) == postfix) fileList.push_back(filename); } } return fileList; } static std::string GetSavePath(std::string outputFolder, std::string fileName) { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileName); std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(fileName); std::string savePathAndFileName = outputFolder +fileStem + fileType; return savePathAndFileName; } static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing, bool useLinInt = false) { InputImageType::Pointer itkImage = InputImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. InputImageType::SpacingType inputSpacing = itkImage->GetSpacing(); InputImageType::SpacingType outputSpacing; const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); InputImageType::SizeType outputSize; typedef InputImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::LinearInterpolateImageFunction< InputImageType > LinearInterpolatorType; LinearInterpolatorType::Pointer lin_interpolator = LinearInterpolatorType::New(); typedef itk::Function::WelchWindowFunction<4> WelchWindowFunction; typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4,WelchWindowFunction> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); if (useLinInt) _pResizeFilter->SetInterpolator(lin_interpolator); else _pResizeFilter->SetInterpolator(sinc_interpolator); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } /// Build a derived file name from moving images e.g. xxx_T2.nrrd becomes xxx_GTV.nrrd static FileListType CreateDerivedFileList(std::string baseFN, std::string baseSuffix, std::vector derivedPatterns) { FileListType files; for (unsigned int i=0; i < derivedPatterns.size(); i++) { std::string derResourceSuffix = derivedPatterns.at(i); std::string derivedResourceFilename = baseFN.substr(0,baseFN.length() -baseSuffix.length()) + derResourceSuffix; MITK_INFO <<" Looking for file: " << derivedResourceFilename; if (!itksys::SystemTools::FileExists(derivedResourceFilename.c_str())) { MITK_INFO << "CreateDerivedFileList: File does not exit. Skipping entry."; continue; } files.push_back(derivedResourceFilename); } return files; } /// Save images according to file type static void SaveImage(std::string fileName, mitk::Image* image, std::string fileType ) { MITK_INFO << "----Save to " << fileName; if (fileType == "dwi") // IOUtil does not handle dwi files properly Bug 15772 { mitk::NrrdDiffusionImageWriter< short >::Pointer dwiwriter = mitk::NrrdDiffusionImageWriter< short >::New(); dwiwriter->SetInput( dynamic_cast* > (image)); dwiwriter->SetFileName( fileName ); try { dwiwriter->Update(); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Caught exception: " << e.what(); mitkThrow() << "Failed with exception from subprocess!"; } } else { mitk::IOUtil::SaveImage(image, fileName); } } /// Copy derived resources from first time step. Append _reg tag, but leave data untouched. static void CopyResources(FileListType fileList, std::string outputPath) { for (unsigned int j=0; j < fileList.size(); j++) { std::string derivedResourceFilename = fileList.at(j); std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(derivedResourceFilename); std::string savePathAndFileName = outputPath +fileStem + "." + fileType; MITK_INFO << "Copy resource " << savePathAndFileName; mitk::Image::Pointer resImage = ExtractFirstTS(mitk::IOUtil::LoadImage(derivedResourceFilename), fileType); mitk::IOUtil::SaveImage(resImage, savePathAndFileName); } } int BatchedFolderRegistration( int argc, char* argv[] ) { ctkCommandLineParser parser; parser.setArgumentPrefix("--","-"); + + parser.setTitle("Batched Folder Registraton"); + parser.setCategory("Preprocessing Tools"); + parser.setDescription(""); + parser.setContributor("MBI"); + // Add command line argument names - parser.addArgument("help", "h",ctkCommandLineParser::Bool, "Show this help text"); - parser.addArgument("xml", "x",ctkCommandLineParser::Bool, "Print a XML description of this modules command line interface"); + parser.addArgument("help", "h",ctkCommandLineParser::Bool, "Help", "Show this help text"); //parser.addArgument("usemask", "u", QVariant::Bool, "Use segmentations (derived resources) to exclude areas from registration metrics"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "Input folder",us::Any(),false); - parser.addArgument("output", "o", ctkCommandLineParser::String, "Output folder (ending with /)",us::Any(),false); - parser.addArgument("fixed", "f", ctkCommandLineParser::String, "Suffix for fixed image (if none is supplied first file matching moving pattern is chosen)",us::Any(),true); - parser.addArgument("moving", "m", ctkCommandLineParser::String, "Suffix for moving images",us::Any(),false); - parser.addArgument("derived", "d", ctkCommandLineParser::String, "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true); - parser.addArgument("silent", "s", ctkCommandLineParser::Bool, "No xml progress output."); - parser.addArgument("resample", "r", ctkCommandLineParser::String, "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", ctkCommandLineParser::Bool, "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any()); - parser.addArgument("correct-origin", "c", ctkCommandLineParser::Bool, "Correct for large origin displacement. Switch when you reveive: Joint PDF summed to zero ",us::Any()); - parser.addArgument("sinc-int", "s", ctkCommandLineParser::Bool, "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); + parser.addArgument("input", "i", ctkCommandLineParser::Directory, "Input:", "Input folder",us::Any(),false); + parser.addArgument("output", "o", ctkCommandLineParser::Directory, "Output:", "Output folder (ending with /)",us::Any(),false); + parser.addArgument("fixed", "f", ctkCommandLineParser::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", ctkCommandLineParser::String, "Moving images:", "Suffix for moving images",us::Any(),false); + parser.addArgument("derived", "d", ctkCommandLineParser::String, "Derived resources:", "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true); + parser.addArgument("silent", "s", ctkCommandLineParser::Bool, "Silent:" "No xml progress output."); + parser.addArgument("resample", "r", ctkCommandLineParser::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", ctkCommandLineParser::Bool, "Binary:", "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any()); + parser.addArgument("correct-origin", "c", ctkCommandLineParser::Bool, "Origin correction:", "Correct for large origin displacement. Switch when you reveive: Joint PDF summed to zero ",us::Any()); + parser.addArgument("sinc-int", "s", ctkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); map parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool silent = false; bool isBinary = false; bool alignOrigin = false; bool useLinearInterpol = true; { if (parsedArgs.size() == 0) { MITK_ERROR << "Missig arguements" ; return EXIT_FAILURE; } if (parsedArgs.count("xml")) { MITK_ERROR << "This is to be handled by shell script"; return EXIT_SUCCESS; } if (parsedArgs.count("sinc-int")) useLinearInterpol = false; if (parsedArgs.count("silent")) silent = true; if (parsedArgs.count("binary")) isBinary = true; if (parsedArgs.count("correct-origin")) alignOrigin = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string refPattern = ""; bool useFirstMoving = false; std::string movingImgPattern = us::any_cast(parsedArgs["moving"]); if (parsedArgs.count("fixed")) { refPattern = us::any_cast(parsedArgs["fixed"]); } else { useFirstMoving = true; refPattern = movingImgPattern; } std::string outputPath = us::any_cast(parsedArgs["output"]); std::string inputPath = us::any_cast(parsedArgs["input"]); //QString resampleReference = parsedArgs["resample"].toString(); //bool maskTumor = parsedArgs["usemask"].toBool(); // if derived sources pattern is provided, populate QStringList with possible filename postfixes std::vector derPatterns; if (parsedArgs.count("derived") || parsedArgs.count("d") ) { std::string arg = us::any_cast(parsedArgs["derived"]); derPatterns = split(arg ,','); } std::vector spacings; float spacing[3]; bool doResampling = false; if (parsedArgs.count("resample") || parsedArgs.count("d") ) { std::string arg = us::any_cast(parsedArgs["resample"]); spacings = split(arg ,','); spacing[0] = atoi(spacings.at(0).c_str()); spacing[1] = atoi(spacings.at(1).c_str()); spacing[2] = atoi(spacings.at(2).c_str()); doResampling = true; } MITK_INFO << "Input Folder : " << inputPath; MITK_INFO << "Looking for reference image ..."; FileListType referenceFileList = CreateFileList(inputPath,refPattern); if ((!useFirstMoving && referenceFileList.size() != 1) || (useFirstMoving && referenceFileList.size() == 0)) { MITK_ERROR << "None or more than one possible reference images (" << refPattern <<") found. Exiting." << referenceFileList.size(); MITK_INFO << "Choose a fixed arguement that is unique in the given folder!"; return EXIT_FAILURE; } std::string referenceFileName = referenceFileList.at(0); MITK_INFO << "Loading Reference (fixed) image: " << referenceFileName; std::string fileType = itksys::SystemTools::GetFilenameExtension(referenceFileName); mitk::Image::Pointer refImage = ExtractFirstTS(mitk::IOUtil::LoadImage(referenceFileName), fileType); mitk::Image::Pointer resampleReference = NULL; if (doResampling) { refImage = ResampleBySpacing(refImage,spacing); resampleReference = refImage; } if (refImage.IsNull()) MITK_ERROR << "Loaded fixed image is NULL"; // Copy reference image to destination std::string savePathAndFileName = GetSavePath(outputPath, referenceFileName); mitk::IOUtil::SaveImage(refImage, savePathAndFileName); // Copy all derived resources also to output folder, adding _reg suffix referenceFileList = CreateDerivedFileList(referenceFileName, movingImgPattern,derPatterns); CopyResources(referenceFileList, outputPath); std::string derivedResourceFilename; mitk::Image::Pointer referenceMask = NULL; // union of all segmentations if (!silent) { // XML Output to report progress std::cout << ""; std::cout << "Batched Registration"; std::cout << "Starting registration ... "; std::cout << ""; } // Now iterate over all files and register them to the reference image, // also register derived resources based on file patterns // ------------------------------------------------------------------------------ // Create File list FileListType movingImagesList = CreateFileList(inputPath, movingImgPattern); // TODO Reactivate Resampling Feature // mitk::Image::Pointer resampleImage = NULL; // if (QFileInfo(resampleReference).isFile()) // { // resampleImage = mitk::IOUtil::LoadImage(resampleReference.toStdString()); // } for (unsigned int i =0; i < movingImagesList.size(); i++) { std::string fileMorphName = movingImagesList.at(i); if (fileMorphName == referenceFileName) { // do not process reference image again continue; } MITK_INFO << "Processing image " << fileMorphName; // 1 Register morphological file to reference image if (!itksys::SystemTools::FileExists(fileMorphName.c_str())) { MITK_WARN << "File does not exit. Skipping entry."; continue; } // Origin of images is cancelled // TODO make this optional!! double transf[6]; double offset[3]; { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileMorphName); mitk::Image::Pointer movingImage = ExtractFirstTS(mitk::IOUtil::LoadImage(fileMorphName), fileType); if (movingImage.IsNull()) MITK_ERROR << "Loaded moving image is NULL"; // 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"; SaveImage(savePathAndFileName,movingImage,fileType ); } if (!silent) { std::cout << "."; } // Now parse all derived resource and apply the above calculated transformation to them // ------------------------------------------------------------------------------------ FileListType fList = CreateDerivedFileList(fileMorphName, movingImgPattern,derPatterns); if (fList.size() > 0) MITK_INFO << "----------DERIVED RESOURCES ---------"; for (unsigned int j=0; j < fList.size(); j++) { derivedResourceFilename = fList.at(j); MITK_INFO << "----Processing derived resorce " << derivedResourceFilename << " ..."; std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); mitk::Image::Pointer derivedMovingResource = ExtractFirstTS(mitk::IOUtil::LoadImage(derivedResourceFilename), fileType); // Apply transformation to derived resource, treat derived resource as binary mitk::RegistrationWrapper::ApplyTransformationToImage(derivedMovingResource, transf,offset, resampleReference,isBinary); savePathAndFileName = GetSavePath(outputPath, derivedResourceFilename); SaveImage(savePathAndFileName,derivedMovingResource,fileType ); } } if (!silent) std::cout << ""; return EXIT_SUCCESS; } RegisterDiffusionMiniApp(BatchedFolderRegistration); diff --git a/Modules/DiffusionImaging/MiniApps/CopyGeometry.cpp b/Modules/DiffusionImaging/MiniApps/CopyGeometry.cpp index db0770bfe4..2a1f009230 100755 --- a/Modules/DiffusionImaging/MiniApps/CopyGeometry.cpp +++ b/Modules/DiffusionImaging/MiniApps/CopyGeometry.cpp @@ -1,91 +1,97 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include #include #include #include #include #include "ctkCommandLineParser.h" using namespace mitk; #include "ctkCommandLineParser.h" int CopyGeometry(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Copy Geometry"); + parser.setCategory("Preprocessing Tools"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("in", "i", ctkCommandLineParser::String, "input image", us::Any(), false); - parser.addArgument("ref", "r", ctkCommandLineParser::String, "reference image", us::Any(), false); - parser.addArgument("out", "o", ctkCommandLineParser::String, "output image", us::Any(), false); + parser.addArgument("in", "i", ctkCommandLineParser::File, "Input:", "input image", us::Any(), false); + parser.addArgument("ref", "r", ctkCommandLineParser::File, "Reference:", "reference image", us::Any(), false); + parser.addArgument("out", "o", ctkCommandLineParser::File, "Output:", "output image", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments string imageName = us::any_cast(parsedArgs["in"]); string refImage = us::any_cast(parsedArgs["ref"]); string outImage = us::any_cast(parsedArgs["out"]); try { MITK_INFO << "Loading image " << imageName; const std::string s1="", s2=""; std::vector infile = BaseDataIO::LoadBaseDataFromFile( refImage, s1, s2, false ); Image::Pointer source = dynamic_cast(infile.at(0).GetPointer()); infile = BaseDataIO::LoadBaseDataFromFile( imageName, s1, s2, false ); Image::Pointer target = dynamic_cast(infile.at(0).GetPointer()); mitk::BaseGeometry* s_geom = source->GetGeometry(); mitk::BaseGeometry* t_geom = target->GetGeometry(); t_geom->SetIndexToWorldTransform(s_geom->GetIndexToWorldTransform()); target->SetGeometry(t_geom); if ( dynamic_cast*>(target.GetPointer()) ) { MITK_INFO << "Writing " << outImage; DiffusionImage::Pointer dwi = dynamic_cast*>(target.GetPointer()); NrrdDiffusionImageWriter::Pointer writer = NrrdDiffusionImageWriter::New(); writer->SetFileName(outImage); writer->SetInput(dwi); writer->Update(); } else mitk::IOUtil::SaveImage(target, outImage); } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } MITK_INFO << "DONE"; return EXIT_SUCCESS; } RegisterDiffusionMiniApp(CopyGeometry); diff --git a/Modules/DiffusionImaging/MiniApps/DicomFolderDump.cpp b/Modules/DiffusionImaging/MiniApps/DicomFolderDump.cpp index de7b606c92..6779165e7a 100644 --- a/Modules/DiffusionImaging/MiniApps/DicomFolderDump.cpp +++ b/Modules/DiffusionImaging/MiniApps/DicomFolderDump.cpp @@ -1,85 +1,91 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include "mitkDicomSeriesReader.h" #include "mitkProperties.h" // CTK #include "ctkCommandLineParser.h" #include "mitkIOUtil.h" int DicomFolderDump(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Dicom Loader"); + parser.setCategory("Preprocessing Tools"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--","-"); // Add command line argument names - parser.addArgument("help", "h",ctkCommandLineParser::Bool, "Show this help text"); - parser.addArgument("xml", "x",ctkCommandLineParser::Bool, "Print a XML description of this modules command line interface"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "Input folder",us::Any(),false); - parser.addArgument("output", "o", ctkCommandLineParser::String, "Output folder (ending with /)",us::Any(),false); - parser.addArgument("filename", "f", ctkCommandLineParser::String, "Output filename (incl. .nrrd)",us::Any(),false); + parser.addArgument("help", "h",ctkCommandLineParser::Bool, "Help:", "Show this help text"); +// parser.addArgument("xml", "x",ctkCommandLineParser::Bool, "Print a XML description of this modules command line interface"); + parser.addArgument("input", "i", ctkCommandLineParser::Directory, "Input folder:", "Input folder",us::Any(),false); + parser.addArgument("output", "o", ctkCommandLineParser::Directory, "Output folder:", "Output folder (ending with /)",us::Any(),false); + parser.addArgument("filename", "f", ctkCommandLineParser::String, "Output name:", "Output filename (incl. .nrrd)",us::Any(),false); map parsedArgs = parser.parseArguments(argc, argv); // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputFolder = us::any_cast(parsedArgs["input"]); std::string outputFolder = us::any_cast(parsedArgs["output"]); std::string outFileName = us::any_cast(parsedArgs["filename"]); //check if DICOMTags have been set as property for mitk::Image mitk::DicomSeriesReader::FileNamesGrouping seriesInFiles = mitk::DicomSeriesReader::GetSeries( inputFolder, true ); std::list images; std::map fileMap; // TODO sort series UIDs, implementation of map iterator might differ on different platforms (or verify this is a standard topic??) for (mitk::DicomSeriesReader::FileNamesGrouping::const_iterator seriesIter = seriesInFiles.begin(); seriesIter != seriesInFiles.end(); ++seriesIter) { mitk::DicomSeriesReader::StringContainer files = seriesIter->second.GetFilenames(); mitk::DataNode::Pointer node = mitk::DicomSeriesReader::LoadDicomSeries( files ); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); images.push_back( image ); fileMap.insert( std::pair(image,files)); } } // WARN: EXPECT ONLY ONE ITEM PER FOLDER for ( std::list::const_iterator imageIter = images.begin(); imageIter != images.end(); ++imageIter ) { const mitk::Image::Pointer image = *imageIter; mitk::IOUtil::SaveImage(image,outputFolder + outFileName); } return EXIT_SUCCESS; } RegisterDiffusionMiniApp(DicomFolderDump); diff --git a/Modules/DiffusionImaging/MiniApps/DiffusionIndices.cpp b/Modules/DiffusionImaging/MiniApps/DiffusionIndices.cpp index d454c85308..4eaf1233e1 100644 --- a/Modules/DiffusionImaging/MiniApps/DiffusionIndices.cpp +++ b/Modules/DiffusionImaging/MiniApps/DiffusionIndices.cpp @@ -1,146 +1,152 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include #include #include #include #include #include #include #include #include "ctkCommandLineParser.h" #include #include #include /** * Calculate indices derived from Qball or tensor images */ int DiffusionIndices(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Diffusion Indices"); + parser.setCategory("Diffusion Related Measures"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false); - parser.addArgument("index", "idx", ctkCommandLineParser::String, "index (fa, gfa, ra, ad, rd, ca, l2, l3, md)", us::Any(), false); - parser.addArgument("outFile", "o", ctkCommandLineParser::String, "output file", us::Any(), false); + parser.addArgument("input", "i", ctkCommandLineParser::File, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false); + parser.addArgument("index", "idx", ctkCommandLineParser::String, "Index:", "index (fa, gfa, ra, ad, rd, ca, l2, l3, md)", us::Any(), false); + parser.addArgument("outFile", "o", ctkCommandLineParser::File, "Output:", "output file", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFileName = us::any_cast(parsedArgs["input"]); string index = us::any_cast(parsedArgs["index"]); string outFileName = us::any_cast(parsedArgs["outFile"]); string ext = itksys::SystemTools::GetFilenameLastExtension(outFileName); if (ext.empty()) outFileName += ".nrrd"; try { // load input image const std::string s1="", s2=""; std::vector infile = mitk::BaseDataIO::LoadBaseDataFromFile( inFileName, s1, s2, false ); if( boost::algorithm::ends_with(inFileName, ".qbi") && index=="gfa" ) { typedef itk::Vector OdfVectorType; typedef itk::Image ItkQballImageType; mitk::QBallImage::Pointer mitkQballImage = dynamic_cast(infile.at(0).GetPointer()); ItkQballImageType::Pointer itk_qbi = ItkQballImageType::New(); mitk::CastToItkImage(mitkQballImage, itk_qbi); typedef itk::DiffusionQballGeneralizedFaImageFilter GfaFilterType; GfaFilterType::Pointer gfaFilter = GfaFilterType::New(); gfaFilter->SetInput(itk_qbi); gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD); gfaFilter->Update(); MITK_INFO << "Writing " << outFileName; itk::ImageFileWriter< itk::Image >::Pointer fileWriter = itk::ImageFileWriter< itk::Image >::New(); fileWriter->SetInput(gfaFilter->GetOutput()); fileWriter->SetFileName(outFileName); fileWriter->Update(); } else if( boost::algorithm::ends_with(inFileName, ".dti") ) { typedef itk::Image< itk::DiffusionTensor3D, 3 > ItkTensorImage; mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast(infile.at(0).GetPointer()); ItkTensorImage::Pointer itk_dti = ItkTensorImage::New(); mitk::CastToItkImage(mitkTensorImage, itk_dti); typedef itk::TensorDerivedMeasurementsFilter MeasurementsType; MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itk_dti.GetPointer() ); if(index=="fa") measurementsCalculator->SetMeasure(MeasurementsType::FA); else if(index=="ra") measurementsCalculator->SetMeasure(MeasurementsType::RA); else if(index=="ad") measurementsCalculator->SetMeasure(MeasurementsType::AD); else if(index=="rd") measurementsCalculator->SetMeasure(MeasurementsType::RD); else if(index=="ca") measurementsCalculator->SetMeasure(MeasurementsType::CA); else if(index=="l2") measurementsCalculator->SetMeasure(MeasurementsType::L2); else if(index=="l3") measurementsCalculator->SetMeasure(MeasurementsType::L3); else if(index=="md") measurementsCalculator->SetMeasure(MeasurementsType::MD); else { MITK_WARN << "No valid diffusion index for input image (tensor image) defined"; return EXIT_FAILURE; } measurementsCalculator->Update(); MITK_INFO << "Writing " << outFileName; itk::ImageFileWriter< itk::Image >::Pointer fileWriter = itk::ImageFileWriter< itk::Image >::New(); fileWriter->SetInput(measurementsCalculator->GetOutput()); fileWriter->SetFileName(outFileName); fileWriter->Update(); } else MITK_INFO << "Diffusion index " << index << " not supported for supplied file type."; } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } RegisterDiffusionMiniApp(DiffusionIndices); diff --git a/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp b/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp index a1e689d64a..76dfc7c19a 100644 --- a/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp +++ b/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp @@ -1,166 +1,169 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include #include #include "ctkCommandLineParser.h" #include #include #include #include #include typedef mitk::DiffusionImage DiffusionImageType; typedef itk::Image ImageType; mitk::BaseData::Pointer LoadFile(std::string filename) { if( filename.empty() ) return NULL; const std::string s1="", s2=""; std::vector infile = mitk::BaseDataIO::LoadBaseDataFromFile( filename, s1, s2, false ); if( infile.empty() ) { MITK_INFO << "File " << filename << " could not be read!"; return NULL; } mitk::BaseData::Pointer baseData = infile.at(0); return baseData; } /** * Denoises DWI using the Nonlocal - Means algorithm */ int DwiDenoising(int argc, char* argv[]) { ctkCommandLineParser parser; - parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", ctkCommandLineParser::File, "input image (DWI)", us::Any(), false); - parser.addArgument("variance", "v", ctkCommandLineParser::Float, "noise variance", us::Any(), false); - parser.addArgument("mask", "m", ctkCommandLineParser::String, "brainmask for input image", us::Any(), true); - parser.addArgument("search", "s", ctkCommandLineParser::Int, "search radius", us::Any(), true); - parser.addArgument("compare", "c", ctkCommandLineParser::Int, "compare radius", us::Any(), true); - parser.addArgument("joint", "j", ctkCommandLineParser::Bool, "use joint information"); - parser.addArgument("rician", "r", ctkCommandLineParser::Bool, "use rician adaption"); parser.setTitle("DWI Denoising"); - parser.setCategory("Denoising"); + parser.setCategory("Preprocessing Tools"); parser.setContributor("MBI"); - parser.setDescription("Denoising for diffusion weighted images."); + parser.setDescription("Denoising for diffusion weighted images using a non-local means algorithm."); + + parser.setArgumentPrefix("--", "-"); + parser.addArgument("input", "i", ctkCommandLineParser::File, "Input:", "input image (DWI)", us::Any(), false); + parser.addArgument("variance", "v", ctkCommandLineParser::Float, "Variance:", "noise variance", us::Any(), false); + parser.addArgument("mask", "m", ctkCommandLineParser::File, "Mask:", "brainmask for input image", us::Any(), true); + parser.addArgument("search", "s", ctkCommandLineParser::Int, "Search radius:", "search radius", us::Any(), true); + parser.addArgument("compare", "c", ctkCommandLineParser::Int, "Comparison radius:", "comparison radius", us::Any(), true); + parser.addArgument("joint", "j", ctkCommandLineParser::Bool, "Joint information:", "use joint information"); + parser.addArgument("rician", "r", ctkCommandLineParser::Bool, "Rician adaption:", "use rician adaption"); + + map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFileName = us::any_cast(parsedArgs["input"]); double variance = static_cast(us::any_cast(parsedArgs["variance"])); string maskName; if (parsedArgs.count("mask")) maskName = us::any_cast(parsedArgs["mask"]); string outFileName = inFileName; boost::algorithm::erase_all(outFileName, ".dwi"); int search = 4; if (parsedArgs.count("search")) search = us::any_cast(parsedArgs["search"]); int compare = 1; if (parsedArgs.count("compare")) compare = us::any_cast(parsedArgs["compare"]); bool joint = false; if (parsedArgs.count("joint")) joint = true; bool rician = false; if (parsedArgs.count("rician")) rician = true; try { if( boost::algorithm::ends_with(inFileName, ".dwi")) { DiffusionImageType::Pointer dwi = dynamic_cast(LoadFile(inFileName).GetPointer()); itk::NonLocalMeansDenoisingFilter::Pointer filter = itk::NonLocalMeansDenoisingFilter::New(); filter->SetNumberOfThreads(12); filter->SetInputImage(dwi->GetVectorImage()); if (!maskName.empty()) { mitk::Image::Pointer mask = dynamic_cast(LoadFile(maskName).GetPointer()); ImageType::Pointer itkMask = ImageType::New(); mitk::CastToItkImage(mask, itkMask); filter->SetInputMask(itkMask); } filter->SetUseJointInformation(joint); filter->SetUseRicianAdaption(rician); filter->SetSearchRadius(search); filter->SetComparisonRadius(compare); filter->SetVariance(variance); filter->Update(); DiffusionImageType::Pointer output = DiffusionImageType::New(); output->SetVectorImage(filter->GetOutput()); output->SetReferenceBValue(dwi->GetReferenceBValue()); output->SetDirections(dwi->GetDirections()); output->InitializeFromVectorImage(); std::stringstream name; name << outFileName << "_NLM_" << search << "-" << compare << "-" << variance << ".dwi"; MITK_INFO << "Writing: " << name.str(); mitk::NrrdDiffusionImageWriter::Pointer writer = mitk::NrrdDiffusionImageWriter::New(); writer->SetInput(output); writer->SetFileName(name.str()); writer->Update(); MITK_INFO << "Finish!"; } else { MITK_INFO << "Only supported for .dwi!"; } } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } RegisterDiffusionMiniApp(DwiDenoising); diff --git a/Modules/DiffusionImaging/MiniApps/ExportShImage.cpp b/Modules/DiffusionImaging/MiniApps/ExportShImage.cpp index 3d3a1d9027..c3c8a22181 100755 --- a/Modules/DiffusionImaging/MiniApps/ExportShImage.cpp +++ b/Modules/DiffusionImaging/MiniApps/ExportShImage.cpp @@ -1,129 +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 "MiniAppManager.h" #include #include #include #include #include #include "ctkCommandLineParser.h" #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include template int StartShConversion(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Export SH Image"); + parser.setCategory("Preprocessing Tools"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "MITK SH image", us::Any(), false); - parser.addArgument("output", "o", ctkCommandLineParser::String, "MRtrix SH image", us::Any(), false); - parser.addArgument("shOrder", "sh", ctkCommandLineParser::Int, "spherical harmonics order"); + parser.addArgument("input", "i", ctkCommandLineParser::File, "Input:", "MITK SH image", us::Any(), false); + parser.addArgument("output", "o", ctkCommandLineParser::File, "Output", "MRtrix SH image", us::Any(), false); + parser.addArgument("shOrder", "sh", ctkCommandLineParser::Int, "SH order:", "spherical harmonics order"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFile = us::any_cast(parsedArgs["input"]); string outFile = us::any_cast(parsedArgs["output"]); try { typedef itk::Image< float, 4 > OutImageType; typedef itk::Image< itk::Vector< float, (shOrder*shOrder + shOrder + 2)/2 + shOrder >, 3 > InputImageType; typename InputImageType::Pointer itkInImage = InputImageType::New(); typedef itk::ImageFileReader< InputImageType > ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); MITK_INFO << "reading " << inFile; reader->SetFileName(inFile.c_str()); reader->Update(); itkInImage = reader->GetOutput(); // extract directions from fiber bundle typename itk::ShCoefficientImageExporter::Pointer filter = itk::ShCoefficientImageExporter::New(); filter->SetInputImage(itkInImage); filter->GenerateData(); OutImageType::Pointer outImage = filter->GetOutputImage(); typedef itk::ImageFileWriter< OutImageType > WriterType; WriterType::Pointer writer = WriterType::New(); MITK_INFO << "writing " << outFile; writer->SetFileName(outFile.c_str()); writer->SetInput(outImage); writer->Update(); MITK_INFO << "DONE"; } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } int ExportShImage(int argc, char* argv[]) { ctkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", ctkCommandLineParser::String, "MITK SH image", us::Any(), false); parser.addArgument("output", "o", ctkCommandLineParser::String, "MRtrix SH image", us::Any(), false); parser.addArgument("shOrder", "sh", ctkCommandLineParser::Int, "spherical harmonics order"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; int shOrder = -1; if (parsedArgs.count("shOrder")) shOrder = us::any_cast(parsedArgs["shOrder"]); switch (shOrder) { case 4: return StartShConversion<4>(argc, argv); case 6: return StartShConversion<6>(argc, argv); case 8: return StartShConversion<8>(argc, argv); case 10: return StartShConversion<10>(argc, argv); case 12: return StartShConversion<12>(argc, argv); } return EXIT_FAILURE; } RegisterDiffusionMiniApp(ExportShImage); diff --git a/Modules/DiffusionImaging/MiniApps/ExtractImageStatistics.cpp b/Modules/DiffusionImaging/MiniApps/ExtractImageStatistics.cpp index 06ad8f9597..24015cb965 100644 --- a/Modules/DiffusionImaging/MiniApps/ExtractImageStatistics.cpp +++ b/Modules/DiffusionImaging/MiniApps/ExtractImageStatistics.cpp @@ -1,121 +1,127 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include "ctkCommandLineParser.h" #include "mitkImage.h" #include "mitkImageStatisticsCalculator.h" #include "mitkIOUtil.h" #include #include #include int ExtractImageStatistics(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Extract Image Statistics"); + parser.setCategory("Preprocessing Tools"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("help", "h", ctkCommandLineParser::String, "Show this help text"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "input image", us::Any(),false); - parser.addArgument("mask", "m", ctkCommandLineParser::String, "mask image / roi image denotin area on which statistics are calculated", us::Any(),false); - parser.addArgument("out", "o", ctkCommandLineParser::String, "output file (default: filenameOfRoi.nrrd_statistics.txt)", us::Any()); + parser.addArgument("help", "h", ctkCommandLineParser::String, "Help:", "Show this help text"); + parser.addArgument("input", "i", ctkCommandLineParser::File, "Input:", "input image", us::Any(),false); + parser.addArgument("mask", "m", ctkCommandLineParser::File, "Mask:", "mask image / roi image denotin area on which statistics are calculated", us::Any(),false); + parser.addArgument("out", "o", ctkCommandLineParser::File, "Output", "output file (default: filenameOfRoi.nrrd_statistics.txt)", us::Any()); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << "\n\n MiniApp Description: \nCalculates statistics on the supplied image using given mask." << endl; std::cout << "Output is written to the designated output file in this order:" << endl; std::cout << "Mean, Standard Deviation, RMS, Max, Min, Number of Voxels, Volume [mm3]" << endl; std::cout << "\n\n Parameters:"<< endl; std::cout << parser.helpText(); return EXIT_SUCCESS; } // Parameters: bool ignoreZeroValues = false; unsigned int timeStep = 0; std::string inputImageFile = us::any_cast(parsedArgs["input"]); std::string maskImageFile = us::any_cast(parsedArgs["mask"]); std::string outFile; if (parsedArgs.count("out") || parsedArgs.count("o") ) outFile = us::any_cast(parsedArgs["out"]); else outFile = inputImageFile + "_statistics.txt"; // Load image and mask mitk::Image::Pointer maskImage = mitk::IOUtil::LoadImage(maskImageFile); mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile); // Calculate statistics mitk::ImageStatisticsCalculator::Statistics statisticsStruct; mitk::ImageStatisticsCalculator::Pointer calculator = mitk::ImageStatisticsCalculator::New(); try { calculator->SetImage(inputImage); calculator->SetImageMask(maskImage); calculator->SetMaskingModeToImage(); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Statistic Calculation Failed - ITK Exception:" << e.what(); return -1; } calculator->SetDoIgnorePixelValue(ignoreZeroValues); calculator->SetIgnorePixelValue(0); try { calculator->ComputeStatistics(timeStep); } catch ( mitk::Exception& e) { MITK_ERROR<< "MITK Exception: " << e.what(); return -1; } statisticsStruct = calculator->GetStatistics(timeStep); // Calculate Volume double volume = 0; const mitk::BaseGeometry *geometry = inputImage->GetGeometry(); if ( geometry != NULL ) { const mitk::Vector3D &spacing = inputImage->GetGeometry()->GetSpacing(); volume = spacing[0] * spacing[1] * spacing[2] * (double) statisticsStruct.N; } // Write Results to file std::ofstream output; output.open(outFile.c_str()); output << statisticsStruct.Mean << " , "; output << statisticsStruct.Sigma << " , "; output << statisticsStruct.RMS << " , "; output << statisticsStruct.Max << " , "; output << statisticsStruct.Min << " , "; output << statisticsStruct.N << " , "; output << volume << "\n"; output.flush(); output.close(); return 0; } RegisterDiffusionMiniApp(ExtractImageStatistics); diff --git a/Modules/DiffusionImaging/MiniApps/FiberDirectionExtraction.cpp b/Modules/DiffusionImaging/MiniApps/FiberDirectionExtraction.cpp index 914d9df06f..0b868f4a8b 100755 --- a/Modules/DiffusionImaging/MiniApps/FiberDirectionExtraction.cpp +++ b/Modules/DiffusionImaging/MiniApps/FiberDirectionExtraction.cpp @@ -1,163 +1,169 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include #include #include #include #include #include "ctkCommandLineParser.h" #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include int FiberDirectionExtraction(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Fiber Direction Extraction"); + parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "input tractogram (.fib, vtk ascii file format)", us::Any(), false); - parser.addArgument("out", "o", ctkCommandLineParser::String, "output root", us::Any(), false); - parser.addArgument("mask", "m", ctkCommandLineParser::String, "mask image"); - parser.addArgument("athresh", "a", ctkCommandLineParser::Float, "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); - parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "output optional and intermediate calculation results"); + parser.addArgument("input", "i", ctkCommandLineParser::File, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false); + parser.addArgument("out", "o", ctkCommandLineParser::Directory, "Output:", "output root", us::Any(), false); + parser.addArgument("mask", "m", ctkCommandLineParser::File, "Mask:", "mask image"); + parser.addArgument("athresh", "a", ctkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); + parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string fibFile = us::any_cast(parsedArgs["input"]); string maskImage(""); if (parsedArgs.count("mask")) maskImage = us::any_cast(parsedArgs["mask"]); float angularThreshold = 25; if (parsedArgs.count("athresh")) angularThreshold = us::any_cast(parsedArgs["athresh"]); string outRoot = us::any_cast(parsedArgs["out"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); try { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; // load fiber bundle mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::LoadDataNode(fibFile)->GetData()); // load/create mask image ItkUcharImgType::Pointer itkMaskImage = NULL; if (maskImage.compare("")!=0) { MITK_INFO << "Using mask image"; itkMaskImage = ItkUcharImgType::New(); mitk::Image::Pointer mitkMaskImage = dynamic_cast(mitk::IOUtil::LoadDataNode(maskImage)->GetData()); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); } // extract directions from fiber bundle itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetMaskImage(itkMaskImage); fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180)); fOdfFilter->SetNormalizeVectors(false); fOdfFilter->SetUseWorkingCopy(false); fOdfFilter->Update(); ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer(); // write direction images for (unsigned int i=0; iSize(); i++) { itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer itkImg = directionImageContainer->GetElement(i); typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter::ItkDirectionImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_DIRECTION_"); outfilename.append(boost::lexical_cast(i)); outfilename.append(".nrrd"); MITK_INFO << "writing " << outfilename; writer->SetFileName(outfilename.c_str()); writer->SetInput(itkImg); writer->Update(); } if (verbose) { // write vector field mitk::FiberBundleX::Pointer directions = fOdfFilter->GetOutputFiberBundle(); mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) { if ( (*it)->CanWriteBaseDataType(directions.GetPointer()) ) { string outfilename = outRoot; outfilename.append("_VECTOR_FIELD.fib"); (*it)->SetFileName( outfilename.c_str() ); (*it)->DoWrite( directions.GetPointer() ); } } // write num direction image { ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage(); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_NUM_DIRECTIONS.nrrd"); MITK_INFO << "writing " << outfilename; writer->SetFileName(outfilename.c_str()); writer->SetInput(numDirImage); writer->Update(); } } MITK_INFO << "DONE"; } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } RegisterDiffusionMiniApp(FiberDirectionExtraction); diff --git a/Modules/DiffusionImaging/MiniApps/FiberProcessing.cpp b/Modules/DiffusionImaging/MiniApps/FiberProcessing.cpp index ebfaf0fa41..987bdbd2b6 100644 --- a/Modules/DiffusionImaging/MiniApps/FiberProcessing.cpp +++ b/Modules/DiffusionImaging/MiniApps/FiberProcessing.cpp @@ -1,234 +1,240 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include #include #include #include #include #include #include #include #include #include #include #include "ctkCommandLineParser.h" #include #include mitk::FiberBundleX::Pointer LoadFib(std::string filename) { const std::string s1="", s2=""; std::vector fibInfile = mitk::BaseDataIO::LoadBaseDataFromFile( filename, s1, s2, false ); if( fibInfile.empty() ) MITK_INFO << "File " << filename << " could not be read!"; mitk::BaseData::Pointer baseData = fibInfile.at(0); return dynamic_cast(baseData.GetPointer()); } int FiberProcessing(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Fiber Processing"); + parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "input fiber bundle (.fib)", us::Any(), false); - parser.addArgument("outFile", "o", ctkCommandLineParser::String, "output fiber bundle (.fib)", us::Any(), false); + parser.addArgument("input", "i", ctkCommandLineParser::File, "Input:", "input fiber bundle (.fib)", us::Any(), false); + parser.addArgument("outFile", "o", ctkCommandLineParser::File, "Output:", "output fiber bundle (.fib)", us::Any(), false); - parser.addArgument("resample", "r", ctkCommandLineParser::Float, "Resample fiber with the given point distance (in mm)"); - parser.addArgument("smooth", "s", ctkCommandLineParser::Float, "Smooth fiber with the given point distance (in mm)"); - parser.addArgument("minLength", "l", ctkCommandLineParser::Float, "Minimum fiber length (in mm)"); - parser.addArgument("maxLength", "m", ctkCommandLineParser::Float, "Maximum fiber length (in mm)"); - parser.addArgument("minCurv", "a", ctkCommandLineParser::Float, "Minimum curvature radius (in mm)"); - parser.addArgument("mirror", "p", ctkCommandLineParser::Int, "Invert fiber coordinates XYZ (e.g. 010 to invert y-coordinate of each fiber point)"); + parser.addArgument("resample", "r", ctkCommandLineParser::Float, "Resample:", "Resample fiber with the given point distance (in mm)"); + parser.addArgument("smooth", "s", ctkCommandLineParser::Float, "Smooth:", "Smooth fiber with the given point distance (in mm)"); + parser.addArgument("minLength", "l", ctkCommandLineParser::Float, "Minimum length:", "Minimum fiber length (in mm)"); + parser.addArgument("maxLength", "m", ctkCommandLineParser::Float, "Maximum length:", "Maximum fiber length (in mm)"); + parser.addArgument("minCurv", "a", ctkCommandLineParser::Float, "Minimum curvature radius:", "Minimum curvature radius (in mm)"); + parser.addArgument("mirror", "p", ctkCommandLineParser::Int, "Invert coordinates:", "Invert fiber coordinates XYZ (e.g. 010 to invert y-coordinate of each fiber point)"); - parser.addArgument("copyAndJoin", "c", ctkCommandLineParser::Bool, "Create a copy of the input fiber bundle (applied after resample/smooth/minLength/maxLength/minCurv/mirror) and join copy with original (applied after rotate/scale/translate)"); + parser.addArgument("copyAndJoin", "c", ctkCommandLineParser::Bool, "Copy & Join:", "Create a copy of the input fiber bundle (applied after resample/smooth/minLength/maxLength/minCurv/mirror) and join copy with original (applied after rotate/scale/translate)"); //parser.addArgument("join", "j", ctkCommandLineParser::Bool, "Join the original and copied fiber bundle (applied after rotate/scale/translate)"); - parser.addArgument("rotate-x", "rx", ctkCommandLineParser::Float, "Rotate around x-axis (if copy is given the copy is rotated, in deg)"); - parser.addArgument("rotate-y", "ry", ctkCommandLineParser::Float, "Rotate around y-axis (if copy is given the copy is rotated, in deg)"); - parser.addArgument("rotate-z", "rz", ctkCommandLineParser::Float, "Rotate around z-axis (if copy is given the copy is rotated, in deg)"); + parser.addArgument("rotate-x", "rx", ctkCommandLineParser::Float, "Rotate x-axis:", "Rotate around x-axis (if copy is given the copy is rotated, in deg)"); + parser.addArgument("rotate-y", "ry", ctkCommandLineParser::Float, "Rotate y-axis:", "Rotate around y-axis (if copy is given the copy is rotated, in deg)"); + parser.addArgument("rotate-z", "rz", ctkCommandLineParser::Float, "Rotate z-axis:", "Rotate around z-axis (if copy is given the copy is rotated, in deg)"); - parser.addArgument("scale-x", "sx", ctkCommandLineParser::Float, "Scale in direction of x-axis (if copy is given the copy is scaled)"); - parser.addArgument("scale-y", "sy", ctkCommandLineParser::Float, "Scale in direction of y-axis (if copy is given the copy is scaled)"); - parser.addArgument("scale-z", "sz", ctkCommandLineParser::Float, "Scale in direction of z-axis (if copy is given the copy is scaled)"); + parser.addArgument("scale-x", "sx", ctkCommandLineParser::Float, "Scale x-axis:", "Scale in direction of x-axis (if copy is given the copy is scaled)"); + parser.addArgument("scale-y", "sy", ctkCommandLineParser::Float, "Scale y-axis:", "Scale in direction of y-axis (if copy is given the copy is scaled)"); + parser.addArgument("scale-z", "sz", ctkCommandLineParser::Float, "Scale z-axis", "Scale in direction of z-axis (if copy is given the copy is scaled)"); - parser.addArgument("translate-x", "tx", ctkCommandLineParser::Float, "Translate in direction of x-axis (if copy is given the copy is translated, in mm)"); - parser.addArgument("translate-y", "ty", ctkCommandLineParser::Float, "Translate in direction of y-axis (if copy is given the copy is translated, in mm)"); - parser.addArgument("translate-z", "tz", ctkCommandLineParser::Float, "Translate in direction of z-axis (if copy is given the copy is translated, in mm)"); + parser.addArgument("translate-x", "tx", ctkCommandLineParser::Float, "Translate x-axis:", "Translate in direction of x-axis (if copy is given the copy is translated, in mm)"); + parser.addArgument("translate-y", "ty", ctkCommandLineParser::Float, "Translate y-axis:", "Translate in direction of y-axis (if copy is given the copy is translated, in mm)"); + parser.addArgument("translate-z", "tz", ctkCommandLineParser::Float, "Translate z-axis:", "Translate in direction of z-axis (if copy is given the copy is translated, in mm)"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; float pointDist = -1; if (parsedArgs.count("resample")) pointDist = us::any_cast(parsedArgs["resample"]); float smoothDist = -1; if (parsedArgs.count("smooth")) smoothDist = us::any_cast(parsedArgs["smooth"]); float minFiberLength = -1; if (parsedArgs.count("minLength")) minFiberLength = us::any_cast(parsedArgs["minLength"]); float maxFiberLength = -1; if (parsedArgs.count("maxLength")) maxFiberLength = us::any_cast(parsedArgs["maxLength"]); float curvThres = -1; if (parsedArgs.count("minCurv")) curvThres = us::any_cast(parsedArgs["minCurv"]); int axis = 0; if (parsedArgs.count("mirror")) axis = us::any_cast(parsedArgs["mirror"]); bool copyAndJoin = false; if(parsedArgs.count("copyAndJoin")) copyAndJoin = us::any_cast(parsedArgs["copyAndJoin"]); float rotateX = 0; if (parsedArgs.count("rotate-x")) rotateX = us::any_cast(parsedArgs["rotate-x"]); float rotateY = 0; if (parsedArgs.count("rotate-y")) rotateY = us::any_cast(parsedArgs["rotate-y"]); float rotateZ = 0; if (parsedArgs.count("rotate-z")) rotateZ = us::any_cast(parsedArgs["rotate-z"]); float scaleX = 0; if (parsedArgs.count("scale-x")) scaleX = us::any_cast(parsedArgs["scale-x"]); float scaleY = 0; if (parsedArgs.count("scale-y")) scaleY = us::any_cast(parsedArgs["scale-y"]); float scaleZ = 0; if (parsedArgs.count("scale-z")) scaleZ = us::any_cast(parsedArgs["scale-z"]); float translateX = 0; if (parsedArgs.count("translate-x")) translateX = us::any_cast(parsedArgs["translate-x"]); float translateY = 0; if (parsedArgs.count("translate-y")) translateY = us::any_cast(parsedArgs["translate-y"]); float translateZ = 0; if (parsedArgs.count("translate-z")) translateZ = us::any_cast(parsedArgs["translate-z"]); string inFileName = us::any_cast(parsedArgs["input"]); string outFileName = us::any_cast(parsedArgs["outFile"]); try { mitk::FiberBundleX::Pointer fib = LoadFib(inFileName); if (minFiberLength>0) fib->RemoveShortFibers(minFiberLength); if (maxFiberLength>0) fib->RemoveLongFibers(maxFiberLength); if (curvThres>0) fib->ApplyCurvatureThreshold(curvThres, false); if (pointDist>0) fib->ResampleFibers(pointDist); if (smoothDist>0) fib->DoFiberSmoothing(smoothDist); if (axis/100==1) fib->MirrorFibers(0); if ((axis%100)/10==1) fib->MirrorFibers(1); if (axis%10==1) fib->MirrorFibers(2); if (copyAndJoin == true) { MITK_INFO << "Create copy"; mitk::FiberBundleX::Pointer fibCopy = fib->GetDeepCopy(); if (rotateX > 0 || rotateY > 0 || rotateZ > 0){ MITK_INFO << "Rotate " << rotateX << " " << rotateY << " " << rotateZ; fibCopy->RotateAroundAxis(rotateX, rotateY, rotateZ); } if (translateX > 0 || translateY > 0 || translateZ > 0) fibCopy->TranslateFibers(translateX, translateY, translateZ); if (scaleX > 0 || scaleY > 0 || scaleZ > 0) fibCopy->ScaleFibers(scaleX, scaleY, scaleZ); MITK_INFO << "Join copy with original"; fib = fib->AddBundle(fibCopy.GetPointer()); } else { if (rotateX > 0 || rotateY > 0 || rotateZ > 0){ MITK_INFO << "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::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) { if ( (*it)->CanWriteBaseDataType(fib.GetPointer()) ) { MITK_INFO << "writing " << outFileName; (*it)->SetFileName( outFileName.c_str() ); (*it)->DoWrite( fib.GetPointer() ); } } } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } RegisterDiffusionMiniApp(FiberProcessing); diff --git a/Modules/DiffusionImaging/MiniApps/FileFormatConverter.cpp b/Modules/DiffusionImaging/MiniApps/FileFormatConverter.cpp index 6a692ef12d..381b160e8c 100755 --- a/Modules/DiffusionImaging/MiniApps/FileFormatConverter.cpp +++ b/Modules/DiffusionImaging/MiniApps/FileFormatConverter.cpp @@ -1,94 +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 "MiniAppManager.h" #include #include #include #include #include #include #include #include "ctkCommandLineParser.h" #include "ctkCommandLineParser.cpp" using namespace mitk; int FileFormatConverter(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Format Converter"); + parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("in", "i", ctkCommandLineParser::String, "input file", us::Any(), false); - parser.addArgument("out", "o", ctkCommandLineParser::String, "output file", us::Any(), false); + parser.addArgument("in", "i", ctkCommandLineParser::File, "Input:", "input file", us::Any(), false); + parser.addArgument("out", "o", ctkCommandLineParser::File, "Output:", "output file", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments string inName = us::any_cast(parsedArgs["in"]); string outName = us::any_cast(parsedArgs["out"]); try { MITK_INFO << "Loading " << inName; const std::string s1="", s2=""; std::vector infile = BaseDataIO::LoadBaseDataFromFile( inName, s1, s2, false ); mitk::BaseData::Pointer baseData = infile.at(0); if ( dynamic_cast*>(baseData.GetPointer()) ) { MITK_INFO << "Writing " << outName; DiffusionImage::Pointer dwi = dynamic_cast*>(baseData.GetPointer()); NrrdDiffusionImageWriter::Pointer writer = NrrdDiffusionImageWriter::New(); writer->SetFileName(outName); writer->SetInput(dwi); writer->Update(); } else if ( dynamic_cast(baseData.GetPointer()) ) { Image::Pointer image = dynamic_cast(baseData.GetPointer()); mitk::IOUtil::SaveImage(image, outName); } else if ( dynamic_cast(baseData.GetPointer()) ) { MITK_INFO << "Writing " << outName; FiberBundleXWriter::Pointer fibWriter = FiberBundleXWriter::New(); fibWriter->SetFileName(outName.c_str()); fibWriter->DoWrite( dynamic_cast(baseData.GetPointer()) ); } else MITK_INFO << "File type currently not supported!"; } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } MITK_INFO << "DONE"; return EXIT_SUCCESS; } RegisterDiffusionMiniApp(FileFormatConverter); diff --git a/Modules/DiffusionImaging/MiniApps/GibbsTracking.cpp b/Modules/DiffusionImaging/MiniApps/GibbsTracking.cpp index a2aa1e20cf..ff95feaba6 100755 --- a/Modules/DiffusionImaging/MiniApps/GibbsTracking.cpp +++ b/Modules/DiffusionImaging/MiniApps/GibbsTracking.cpp @@ -1,245 +1,251 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include #include #include #include #include #include #include #include #include #include #include "ctkCommandLineParser.h" #include #include #include template typename itk::ShCoefficientImageImporter< float, shOrder >::QballImageType::Pointer TemplatedConvertShCoeffs(mitk::Image* mitkImg, int toolkit, bool noFlip = false) { typedef itk::ShCoefficientImageImporter< float, shOrder > FilterType; typedef mitk::ImageToItk< itk::Image< float, 4 > > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(mitkImg); caster->Update(); itk::Image< float, 4 >::Pointer itkImage = caster->GetOutput(); typename FilterType::Pointer filter = FilterType::New(); if (noFlip) { filter->SetInputImage(itkImage); } else { MITK_INFO << "Flipping image"; itk::FixedArray flipAxes; flipAxes[0] = true; flipAxes[1] = true; flipAxes[2] = false; flipAxes[3] = false; itk::FlipImageFilter< itk::Image< float, 4 > >::Pointer flipper = itk::FlipImageFilter< itk::Image< float, 4 > >::New(); flipper->SetInput(itkImage); flipper->SetFlipAxes(flipAxes); flipper->Update(); itk::Image< float, 4 >::Pointer flipped = flipper->GetOutput(); itk::Matrix< double,4,4 > m = itkImage->GetDirection(); m[0][0] *= -1; m[1][1] *= -1; flipped->SetDirection(m); itk::Point< float, 4 > o = itkImage->GetOrigin(); o[0] -= (flipped->GetLargestPossibleRegion().GetSize(0)-1); o[1] -= (flipped->GetLargestPossibleRegion().GetSize(1)-1); flipped->SetOrigin(o); filter->SetInputImage(flipped); } switch (toolkit) { case 0: filter->SetToolkit(FilterType::FSL); break; case 1: filter->SetToolkit(FilterType::MRTRIX); break; default: filter->SetToolkit(FilterType::FSL); } filter->GenerateData(); return filter->GetQballImage(); } int GibbsTracking(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Gibbs Tracking"); + parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false); - parser.addArgument("parameters", "p", ctkCommandLineParser::String, "parameter file (.gtp)", us::Any(), false); - parser.addArgument("mask", "m", ctkCommandLineParser::String, "binary mask image"); - parser.addArgument("shConvention", "s", ctkCommandLineParser::String, "sh coefficient convention (FSL, MRtrix)", string("FSL"), true); - parser.addArgument("outFile", "o", ctkCommandLineParser::String, "output fiber bundle (.fib)", us::Any(), false); - parser.addArgument("noFlip", "f", ctkCommandLineParser::Bool, "do not flip input image to match MITK coordinate convention"); + parser.addArgument("input", "i", ctkCommandLineParser::File, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false); + parser.addArgument("parameters", "p", ctkCommandLineParser::File, "Parameters:", "parameter file (.gtp)", us::Any(), false); + parser.addArgument("mask", "m", ctkCommandLineParser::File, "Mask:", "binary mask image"); + parser.addArgument("shConvention", "s", ctkCommandLineParser::String, "SH coefficient:", "sh coefficient convention (FSL, MRtrix)", string("FSL"), true); + parser.addArgument("outFile", "o", ctkCommandLineParser::File, "Output:", "output fiber bundle (.fib)", us::Any(), false); + parser.addArgument("noFlip", "f", ctkCommandLineParser::Bool, "No flip:", "do not flip input image to match MITK coordinate convention"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; string inFileName = us::any_cast(parsedArgs["input"]); string paramFileName = us::any_cast(parsedArgs["parameters"]); string outFileName = us::any_cast(parsedArgs["outFile"]); bool noFlip = false; if (parsedArgs.count("noFlip")) noFlip = us::any_cast(parsedArgs["noFlip"]); try { // instantiate gibbs tracker typedef itk::Vector OdfVectorType; typedef itk::Image ItkQballImageType; typedef itk::GibbsTrackingFilter GibbsTrackingFilterType; GibbsTrackingFilterType::Pointer gibbsTracker = GibbsTrackingFilterType::New(); // load input image const std::string s1="", s2=""; std::vector infile = mitk::BaseDataIO::LoadBaseDataFromFile( inFileName, s1, s2, false ); mitk::Image::Pointer mitkImage = dynamic_cast(infile.at(0).GetPointer()); // try to cast to qball image if( boost::algorithm::ends_with(inFileName, ".qbi") ) { MITK_INFO << "Loading qball image ..."; mitk::QBallImage::Pointer mitkQballImage = dynamic_cast(infile.at(0).GetPointer()); ItkQballImageType::Pointer itk_qbi = ItkQballImageType::New(); mitk::CastToItkImage(mitkQballImage, itk_qbi); gibbsTracker->SetQBallImage(itk_qbi.GetPointer()); } else if( boost::algorithm::ends_with(inFileName, ".dti") ) { MITK_INFO << "Loading tensor image ..."; typedef itk::Image< itk::DiffusionTensor3D, 3 > ItkTensorImage; mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast(infile.at(0).GetPointer()); ItkTensorImage::Pointer itk_dti = ItkTensorImage::New(); mitk::CastToItkImage(mitkTensorImage, itk_dti); gibbsTracker->SetTensorImage(itk_dti); } else if ( boost::algorithm::ends_with(inFileName, ".nii") ) { MITK_INFO << "Loading sh-coefficient image ..."; int nrCoeffs = mitkImage->GetLargestPossibleRegion().GetSize()[3]; int c=3, d=2-2*nrCoeffs; double D = c*c-4*d; int shOrder; if (D>0) { shOrder = (-c+sqrt(D))/2.0; if (shOrder<0) shOrder = (-c-sqrt(D))/2.0; } else if (D==0) shOrder = -c/2.0; MITK_INFO << "using SH-order " << shOrder; int toolkitConvention = 0; if (parsedArgs.count("shConvention")) { string convention = us::any_cast(parsedArgs["shConvention"]).c_str(); if ( boost::algorithm::equals(convention, "MRtrix") ) { toolkitConvention = 1; MITK_INFO << "Using MRtrix style sh-coefficient convention"; } else MITK_INFO << "Using FSL style sh-coefficient convention"; } else MITK_INFO << "Using FSL style sh-coefficient convention"; switch (shOrder) { case 4: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<4>(mitkImage, toolkitConvention, noFlip)); break; case 6: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<6>(mitkImage, toolkitConvention, noFlip)); break; case 8: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<8>(mitkImage, toolkitConvention, noFlip)); break; case 10: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<10>(mitkImage, toolkitConvention, noFlip)); break; case 12: gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<12>(mitkImage, toolkitConvention, noFlip)); break; default: MITK_INFO << "SH-order " << shOrder << " not supported"; } } else return EXIT_FAILURE; // global tracking if (parsedArgs.count("mask")) { typedef itk::Image MaskImgType; mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::LoadImage(us::any_cast(parsedArgs["mask"])); MaskImgType::Pointer itk_mask = MaskImgType::New(); mitk::CastToItkImage(mitkMaskImage, itk_mask); gibbsTracker->SetMaskImage(itk_mask); } gibbsTracker->SetDuplicateImage(false); gibbsTracker->SetLoadParameterFile( paramFileName ); // gibbsTracker->SetLutPath( "" ); gibbsTracker->Update(); mitk::FiberBundleX::Pointer mitkFiberBundle = mitk::FiberBundleX::New(gibbsTracker->GetFiberBundle()); mitkFiberBundle->SetReferenceImage(mitkImage); mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) { if ( (*it)->CanWriteBaseDataType(mitkFiberBundle.GetPointer()) ) { (*it)->SetFileName( outFileName.c_str() ); (*it)->DoWrite( mitkFiberBundle.GetPointer() ); } } } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } RegisterDiffusionMiniApp(GibbsTracking); diff --git a/Modules/DiffusionImaging/MiniApps/LocalDirectionalFiberPlausibility.cpp b/Modules/DiffusionImaging/MiniApps/LocalDirectionalFiberPlausibility.cpp index 0a64df0196..6f3bfd4bc4 100755 --- a/Modules/DiffusionImaging/MiniApps/LocalDirectionalFiberPlausibility.cpp +++ b/Modules/DiffusionImaging/MiniApps/LocalDirectionalFiberPlausibility.cpp @@ -1,298 +1,304 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include #include #include #include #include #include #include "ctkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include int LocalDirectionalFiberPlausibility(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Local Directional Fiber Plausibility"); + parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", ctkCommandLineParser::String, "input tractogram (.fib, vtk ascii file format)", us::Any(), false); - parser.addArgument("reference", "r", ctkCommandLineParser::StringList, "reference direction images", us::Any(), false); - parser.addArgument("out", "o", ctkCommandLineParser::String, "output root", us::Any(), false); - parser.addArgument("mask", "m", ctkCommandLineParser::StringList, "mask images"); - parser.addArgument("athresh", "a", ctkCommandLineParser::Float, "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); - parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "output optional and intermediate calculation results"); - parser.addArgument("ignore", "n", ctkCommandLineParser::Bool, "don't increase error for missing or too many directions"); + parser.addArgument("input", "i", ctkCommandLineParser::File, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false); + parser.addArgument("reference", "r", ctkCommandLineParser::StringList, "Reference images:", "reference direction images", us::Any(), false); + parser.addArgument("out", "o", ctkCommandLineParser::Directory, "Output:", "output root", us::Any(), false); + parser.addArgument("mask", "m", ctkCommandLineParser::StringList, "Masks:", "mask images"); + parser.addArgument("athresh", "a", ctkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); + parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results"); + parser.addArgument("ignore", "n", ctkCommandLineParser::Bool, "Ignore:", "don't increase error for missing or too many directions"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; ctkCommandLineParser::StringContainerType referenceImages = us::any_cast(parsedArgs["reference"]); ctkCommandLineParser::StringContainerType maskImages; if (parsedArgs.count("mask")) maskImages = us::any_cast(parsedArgs["mask"]); string fibFile = us::any_cast(parsedArgs["input"]); float angularThreshold = 25; if (parsedArgs.count("athresh")) angularThreshold = us::any_cast(parsedArgs["athresh"]); string outRoot = us::any_cast(parsedArgs["out"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); bool ignore = false; if (parsedArgs.count("ignore")) ignore = us::any_cast(parsedArgs["ignore"]); try { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType; // load fiber bundle mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::LoadDataNode(fibFile)->GetData()); // load reference directions ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New(); for (unsigned int i=0; i(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData()); typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput(); referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg); } catch(...){ MITK_INFO << "could not load: " << referenceImages.at(i); } } ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New(); ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0); itkMaskImage->SetSpacing( dirImg->GetSpacing() ); itkMaskImage->SetOrigin( dirImg->GetOrigin() ); itkMaskImage->SetDirection( dirImg->GetDirection() ); itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->Allocate(); itkMaskImage->FillBuffer(1); // extract directions from fiber bundle itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetMaskImage(itkMaskImage); fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180)); fOdfFilter->SetNormalizeVectors(true); fOdfFilter->SetUseWorkingCopy(false); fOdfFilter->Update(); ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer(); if (verbose) { // write vector field mitk::FiberBundleX::Pointer directions = fOdfFilter->GetOutputFiberBundle(); mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) { if ( (*it)->CanWriteBaseDataType(directions.GetPointer()) ) { string outfilename = outRoot; outfilename.append("_VECTOR_FIELD.fib"); (*it)->SetFileName( outfilename.c_str() ); (*it)->DoWrite( directions.GetPointer() ); } } // write direction images for (unsigned int i=0; iSize(); i++) { itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer itkImg = directionImageContainer->GetElement(i); typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter::ItkDirectionImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_DIRECTION_"); outfilename.append(boost::lexical_cast(i)); outfilename.append(".nrrd"); MITK_INFO << "writing " << outfilename; writer->SetFileName(outfilename.c_str()); writer->SetInput(itkImg); writer->Update(); } // write num direction image { ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage(); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_NUM_DIRECTIONS.nrrd"); MITK_INFO << "writing " << outfilename; writer->SetFileName(outfilename.c_str()); writer->SetInput(numDirImage); writer->Update(); } } string logFile = outRoot; logFile.append("_ANGULAR_ERROR.csv"); ofstream file; file.open (logFile.c_str()); if (maskImages.size()>0) { for (unsigned int i=0; i(mitk::IOUtil::LoadDataNode(maskImages.at(i))->GetData()); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); // evaluate directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(ignore); evaluationFilter->Update(); if (verbose) { EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_ERROR_IMAGE.nrrd"); MITK_INFO << "writing " << outfilename; writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } string sens = itksys::SystemTools::GetFilenameWithoutExtension(itksys::SystemTools::GetFilenameName(fibFile)); sens.append(","); sens.append(itksys::SystemTools::GetFilenameWithoutExtension(itksys::SystemTools::GetFilenameName(maskImages.at(i)))); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append(";\n"); file << sens; } } else { // evaluate directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(ignore); evaluationFilter->Update(); if (verbose) { EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_ERROR_IMAGE.nrrd"); MITK_INFO << "writing " << outfilename; writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } string sens = itksys::SystemTools::GetFilenameWithoutExtension(itksys::SystemTools::GetFilenameName(fibFile)); sens.append(","); sens.append("FULL"); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append(";\n"); file << sens; } file.close(); MITK_INFO << "DONE"; } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } RegisterDiffusionMiniApp(LocalDirectionalFiberPlausibility); diff --git a/Modules/DiffusionImaging/MiniApps/MultishellMethods.cpp b/Modules/DiffusionImaging/MiniApps/MultishellMethods.cpp index dcab052bc7..d1a52851d9 100644 --- a/Modules/DiffusionImaging/MiniApps/MultishellMethods.cpp +++ b/Modules/DiffusionImaging/MiniApps/MultishellMethods.cpp @@ -1,224 +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 "MiniAppManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ctkCommandLineParser.h" #include #include #include #include #include #include #include int MultishellMethods(int argc, char* argv[]) { ctkCommandLineParser parser; + + parser.setTitle("Multishell Methods"); + parser.setCategory("Fiber Tracking and Processing Methods"); + parser.setDescription(""); + parser.setContributor("MBI"); + parser.setArgumentPrefix("--", "-"); - parser.addArgument("in", "i", ctkCommandLineParser::String, "input file", us::Any(), false); - parser.addArgument("out", "o", ctkCommandLineParser::String, "output file", us::Any(), false); - parser.addArgument("adc", "D", ctkCommandLineParser::Bool, "ADC Average", us::Any(), false); - parser.addArgument("akc", "K", ctkCommandLineParser::Bool, "Kurtosis Fit", us::Any(), false); - parser.addArgument("biexp", "B", ctkCommandLineParser::Bool, "BiExp fit", us::Any(), false); - parser.addArgument("targetbvalue", "b", ctkCommandLineParser::String, "target bValue (mean, min, max)", us::Any(), false); + parser.addArgument("in", "i", ctkCommandLineParser::File, "Input:", "input file", us::Any(), false); + parser.addArgument("out", "o", ctkCommandLineParser::File, "Output:", "output file", us::Any(), false); + parser.addArgument("adc", "D", ctkCommandLineParser::Bool, "ADC:", "ADC Average", us::Any(), false); + parser.addArgument("akc", "K", ctkCommandLineParser::Bool, "Kurtosis fit:", "Kurtosis Fit", us::Any(), false); + parser.addArgument("biexp", "B", ctkCommandLineParser::Bool, "BiExp fit:", "BiExp fit", us::Any(), false); + parser.addArgument("targetbvalue", "b", ctkCommandLineParser::String, "b Value:", "target bValue (mean, min, max)", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments string inName = us::any_cast(parsedArgs["in"]); string outName = us::any_cast(parsedArgs["out"]); bool applyADC = us::any_cast(parsedArgs["adc"]); bool applyAKC = us::any_cast(parsedArgs["akc"]); bool applyBiExp = us::any_cast(parsedArgs["biexp"]); string targetType = us::any_cast(parsedArgs["targetbvalue"]); try { MITK_INFO << "Loading " << inName; const std::string s1="", s2=""; std::vector infile = mitk::BaseDataIO::LoadBaseDataFromFile( inName, s1, s2, false ); mitk::BaseData::Pointer baseData = infile.at(0); if ( dynamic_cast*>(baseData.GetPointer()) ) { MITK_INFO << "Writing " << outName; mitk::DiffusionImage::Pointer dwi = dynamic_cast*>(baseData.GetPointer()); typedef itk::RadialMultishellToSingleshellImageFilter FilterType; typedef itk::DwiGradientLengthCorrectionFilter CorrectionFilterType; CorrectionFilterType::Pointer roundfilter = CorrectionFilterType::New(); roundfilter->SetRoundingValue( 1000 ); roundfilter->SetReferenceBValue(dwi->GetReferenceBValue()); roundfilter->SetReferenceGradientDirectionContainer(dwi->GetDirections()); roundfilter->Update(); dwi->SetReferenceBValue( roundfilter->GetNewBValue() ); dwi->SetDirections( roundfilter->GetOutputGradientDirectionContainer()); // filter input parameter const mitk::DiffusionImage::BValueMap &originalShellMap = dwi->GetBValueMap(); const mitk::DiffusionImage::ImageType *vectorImage = dwi->GetVectorImage(); const mitk::DiffusionImage::GradientDirectionContainerType::Pointer gradientContainer = dwi->GetDirections(); const unsigned int &bValue = dwi->GetReferenceBValue(); // filter call vnl_vector bValueList(originalShellMap.size()-1); double targetBValue = bValueList.mean(); mitk::DiffusionImage::BValueMap::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::DiffusionImage::Pointer outImage = mitk::DiffusionImage::New(); outImage->SetVectorImage( filter->GetOutput() ); outImage->SetReferenceBValue( targetBValue ); outImage->SetDirections( filter->GetTargetGradientDirections() ); outImage->InitializeFromVectorImage(); mitk::NrrdDiffusionImageWriter::Pointer writer = mitk::NrrdDiffusionImageWriter::New(); writer->SetFileName((string(outName) + "_ADC.dwi")); writer->SetInput(outImage); writer->Update(); } 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::DiffusionImage::Pointer outImage = mitk::DiffusionImage::New(); outImage->SetVectorImage( filter->GetOutput() ); outImage->SetReferenceBValue( targetBValue ); outImage->SetDirections( filter->GetTargetGradientDirections() ); outImage->InitializeFromVectorImage(); mitk::NrrdDiffusionImageWriter::Pointer writer = mitk::NrrdDiffusionImageWriter::New(); writer->SetFileName((string(outName) + "_AKC.dwi")); writer->SetInput(outImage); writer->Update(); } 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::DiffusionImage::Pointer outImage = mitk::DiffusionImage::New(); outImage->SetVectorImage( filter->GetOutput() ); outImage->SetReferenceBValue( targetBValue ); outImage->SetDirections( filter->GetTargetGradientDirections() ); outImage->InitializeFromVectorImage(); mitk::NrrdDiffusionImageWriter::Pointer writer = mitk::NrrdDiffusionImageWriter::New(); writer->SetFileName((string(outName) + "_BiExp.dwi")); writer->SetInput(outImage); writer->Update(); } } } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } MITK_INFO << "DONE"; return EXIT_SUCCESS; } RegisterDiffusionMiniApp(MultishellMethods);