Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
FiberDirectionExtraction.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include <mitkBaseData.h>
18 #include <mitkImageCast.h>
19 #include <mitkImageToItk.h>
20 #include <metaCommand.h>
21 #include "mitkCommandLineParser.h"
22 #include <usAny.h>
23 #include <itkImageFileWriter.h>
24 #include <mitkIOUtil.h>
25 #include <boost/lexical_cast.hpp>
28 #include <mitkCoreObjectFactory.h>
29 
30 #define _USE_MATH_DEFINES
31 #include <math.h>
32 
33 using namespace std;
34 
38 int main(int argc, char* argv[])
39 {
40  mitkCommandLineParser parser;
41 
42  parser.setTitle("Fiber Direction Extraction");
43  parser.setCategory("Fiber Tracking and Processing Methods");
44  parser.setDescription("Extract principal fiber directions from a tractogram");
45  parser.setContributor("MBI");
46 
47  parser.setArgumentPrefix("--", "-");
48  parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib/.trk)", us::Any(), false);
49  parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false);
50  parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image");
51  parser.addArgument("athresh", "a", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true);
52  parser.addArgument("peakthresh", "t", mitkCommandLineParser::Float, "Peak size threshold:", "peak size threshold relative to largest peak in voxel", 0.2, true);
53  parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results");
54  parser.addArgument("numdirs", "d", mitkCommandLineParser::Int, "Max. num. directions:", "maximum number of fibers per voxel", 3, true);
55  parser.addArgument("normalize", "n", mitkCommandLineParser::Bool, "Normalize:", "normalize vectors");
56 
57  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
58  if (parsedArgs.size()==0)
59  return EXIT_FAILURE;
60 
61  string fibFile = us::any_cast<string>(parsedArgs["input"]);
62 
63  string maskImage("");
64  if (parsedArgs.count("mask"))
65  maskImage = us::any_cast<string>(parsedArgs["mask"]);
66 
67  float peakThreshold = 0.2;
68  if (parsedArgs.count("peakthresh"))
69  peakThreshold = us::any_cast<float>(parsedArgs["peakthresh"]);
70 
71  float angularThreshold = 25;
72  if (parsedArgs.count("athresh"))
73  angularThreshold = us::any_cast<float>(parsedArgs["athresh"]);
74 
75  string outRoot = us::any_cast<string>(parsedArgs["out"]);
76 
77  bool verbose = false;
78  if (parsedArgs.count("verbose"))
79  verbose = us::any_cast<bool>(parsedArgs["verbose"]);
80 
81  int maxNumDirs = 3;
82  if (parsedArgs.count("numdirs"))
83  maxNumDirs = us::any_cast<int>(parsedArgs["numdirs"]);
84 
85  bool normalize = false;
86  if (parsedArgs.count("normalize"))
87  normalize = us::any_cast<bool>(parsedArgs["normalize"]);
88 
89  try
90  {
91  typedef itk::Image<unsigned char, 3> ItkUcharImgType;
92  typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType;
93  typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType;
94 
95  // load fiber bundle
96  mitk::FiberBundle::Pointer inputTractogram = dynamic_cast<mitk::FiberBundle*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());
97 
98  // load/create mask image
99  ItkUcharImgType::Pointer itkMaskImage = NULL;
100  if (maskImage.compare("")!=0)
101  {
102  std::cout << "Using mask image";
103  itkMaskImage = ItkUcharImgType::New();
104  mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(maskImage)->GetData());
105  mitk::CastToItkImage(mitkMaskImage, itkMaskImage);
106  }
107 
108  // extract directions from fiber bundle
110  fOdfFilter->SetFiberBundle(inputTractogram);
111  fOdfFilter->SetMaskImage(itkMaskImage);
112  fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180));
113  fOdfFilter->SetNormalizeVectors(normalize);
114  fOdfFilter->SetUseWorkingCopy(false);
115  fOdfFilter->SetSizeThreshold(peakThreshold);
116  fOdfFilter->SetMaxNumDirections(maxNumDirs);
117  fOdfFilter->Update();
118  ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer();
119 
120  // write direction images
121  for (unsigned int i=0; i<directionImageContainer->Size(); i++)
122  {
123  itk::TractsToVectorImageFilter<float>::ItkDirectionImageType::Pointer itkImg = directionImageContainer->GetElement(i);
124  typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter<float>::ItkDirectionImageType > WriterType;
126 
127  string outfilename = outRoot;
128  outfilename.append("_DIRECTION_");
129  outfilename.append(boost::lexical_cast<string>(i));
130  outfilename.append(".nrrd");
131 
132  writer->SetFileName(outfilename.c_str());
133  writer->SetInput(itkImg);
134  writer->Update();
135  }
136 
137  if (verbose)
138  {
139  // write vector field
140  mitk::FiberBundle::Pointer directions = fOdfFilter->GetOutputFiberBundle();
141 
142  string outfilename = outRoot;
143  outfilename.append("_VECTOR_FIELD.fib");
144 
145  mitk::IOUtil::SaveBaseData(directions.GetPointer(), outfilename );
146 
147  // write num direction image
148  {
149  ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage();
150  typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
152 
153  string outfilename = outRoot;
154  outfilename.append("_NUM_DIRECTIONS.nrrd");
155 
156  writer->SetFileName(outfilename.c_str());
157  writer->SetInput(numDirImage);
158  writer->Update();
159  }
160  }
161  }
162  catch (itk::ExceptionObject e)
163  {
164  std::cout << e;
165  return EXIT_FAILURE;
166  }
167  catch (std::exception e)
168  {
169  std::cout << e.what();
170  return EXIT_FAILURE;
171  }
172  catch (...)
173  {
174  std::cout << "ERROR!?!";
175  return EXIT_FAILURE;
176  }
177  return EXIT_SUCCESS;
178 }
itk::SmartPointer< Self > Pointer
void setContributor(std::string contributor)
STL namespace.
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
static bool SaveBaseData(mitk::BaseData *data, const std::string &path)
SaveBaseData Convenience method to save arbitrary baseData.
Definition: mitkIOUtil.cpp:888
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false)
Image class for storing images.
Definition: mitkImage.h:76
Definition: usAny.h:163
Base Class for Fiber Bundles;.
void setCategory(std::string category)
static mitk::DataNode::Pointer LoadDataNode(const std::string &path)
LoadDataNode Method to load an arbitrary DataNode.
Definition: mitkIOUtil.cpp:586
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
int main(int argc, char *argv[])
Extract principal fiber directions from a tractogram.
void setTitle(std::string title)
void setDescription(std::string description)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.