Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.