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
FiberProcessing.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 <vector>
18 #include <iostream>
19 #include <fstream>
20 #include <algorithm>
21 #include <string>
22 
23 #include <itkImageFileWriter.h>
24 #include <itkMetaDataObject.h>
25 #include <itkVectorImage.h>
26 
27 #include <mitkBaseData.h>
28 #include <mitkFiberBundle.h>
29 #include "mitkCommandLineParser.h"
30 #include <boost/lexical_cast.hpp>
31 #include <mitkCoreObjectFactory.h>
32 #include <mitkIOUtil.h>
34 
35 
37 {
38  std::vector<mitk::BaseData::Pointer> fibInfile = mitk::IOUtil::Load(filename);
39  if( fibInfile.empty() )
40  std::cout << "File " << filename << " could not be read!";
41  mitk::BaseData::Pointer baseData = fibInfile.at(0);
42  return dynamic_cast<mitk::FiberBundle*>(baseData.GetPointer());
43 }
44 
48 int main(int argc, char* argv[])
49 {
50  mitkCommandLineParser parser;
51 
52  parser.setTitle("Fiber Processing");
53  parser.setCategory("Fiber Tracking and Processing Methods");
54  parser.setDescription("Modify input tractogram: fiber resampling, compression, pruning and transformation.");
55  parser.setContributor("MBI");
56 
57  parser.setArgumentPrefix("--", "-");
58  parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input fiber bundle (.fib)", us::Any(), false);
59  parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib)", us::Any(), false);
60 
61  parser.addArgument("smooth", "s", mitkCommandLineParser::Float, "Spline resampling:", "Resample fiber using splines with the given point distance (in mm)");
62  parser.addArgument("compress", "c", mitkCommandLineParser::Float, "Compress:", "Compress fiber using the given error threshold (in mm)");
63  parser.addArgument("minLength", "l", mitkCommandLineParser::Float, "Minimum length:", "Minimum fiber length (in mm)");
64  parser.addArgument("maxLength", "m", mitkCommandLineParser::Float, "Maximum length:", "Maximum fiber length (in mm)");
65  parser.addArgument("maxAngle", "a", mitkCommandLineParser::Float, "Maximum angle:", "Maximum angular STDEV over 1cm (in degree)");
66  parser.addArgument("mirror", "p", mitkCommandLineParser::Int, "Invert coordinates:", "Invert fiber coordinates XYZ (e.g. 010 to invert y-coordinate of each fiber point)");
67 
68  parser.addArgument("rotate-x", "rx", mitkCommandLineParser::Float, "Rotate x-axis:", "Rotate around x-axis (if copy is given the copy is rotated, in deg)");
69  parser.addArgument("rotate-y", "ry", mitkCommandLineParser::Float, "Rotate y-axis:", "Rotate around y-axis (if copy is given the copy is rotated, in deg)");
70  parser.addArgument("rotate-z", "rz", mitkCommandLineParser::Float, "Rotate z-axis:", "Rotate around z-axis (if copy is given the copy is rotated, in deg)");
71 
72  parser.addArgument("scale-x", "sx", mitkCommandLineParser::Float, "Scale x-axis:", "Scale in direction of x-axis (if copy is given the copy is scaled)");
73  parser.addArgument("scale-y", "sy", mitkCommandLineParser::Float, "Scale y-axis:", "Scale in direction of y-axis (if copy is given the copy is scaled)");
74  parser.addArgument("scale-z", "sz", mitkCommandLineParser::Float, "Scale z-axis", "Scale in direction of z-axis (if copy is given the copy is scaled)");
75 
76  parser.addArgument("translate-x", "tx", mitkCommandLineParser::Float, "Translate x-axis:", "Translate in direction of x-axis (if copy is given the copy is translated, in mm)");
77  parser.addArgument("translate-y", "ty", mitkCommandLineParser::Float, "Translate y-axis:", "Translate in direction of y-axis (if copy is given the copy is translated, in mm)");
78  parser.addArgument("translate-z", "tz", mitkCommandLineParser::Float, "Translate z-axis:", "Translate in direction of z-axis (if copy is given the copy is translated, in mm)");
79 
80 
81  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
82  if (parsedArgs.size()==0)
83  return EXIT_FAILURE;
84 
85  float smoothDist = -1;
86  if (parsedArgs.count("smooth"))
87  smoothDist = us::any_cast<float>(parsedArgs["smooth"]);
88 
89  float compress = -1;
90  if (parsedArgs.count("compress"))
91  compress = us::any_cast<float>(parsedArgs["compress"]);
92 
93  float minFiberLength = -1;
94  if (parsedArgs.count("minLength"))
95  minFiberLength = us::any_cast<float>(parsedArgs["minLength"]);
96 
97  float maxFiberLength = -1;
98  if (parsedArgs.count("maxLength"))
99  maxFiberLength = us::any_cast<float>(parsedArgs["maxLength"]);
100 
101  float maxAngularDev = -1;
102  if (parsedArgs.count("maxAngle"))
103  maxAngularDev = us::any_cast<float>(parsedArgs["maxAngle"]);
104 
105  int axis = 0;
106  if (parsedArgs.count("mirror"))
107  axis = us::any_cast<int>(parsedArgs["mirror"]);
108 
109  float rotateX = 0;
110  if (parsedArgs.count("rotate-x"))
111  rotateX = us::any_cast<float>(parsedArgs["rotate-x"]);
112 
113  float rotateY = 0;
114  if (parsedArgs.count("rotate-y"))
115  rotateY = us::any_cast<float>(parsedArgs["rotate-y"]);
116 
117  float rotateZ = 0;
118  if (parsedArgs.count("rotate-z"))
119  rotateZ = us::any_cast<float>(parsedArgs["rotate-z"]);
120 
121  float scaleX = 0;
122  if (parsedArgs.count("scale-x"))
123  scaleX = us::any_cast<float>(parsedArgs["scale-x"]);
124 
125  float scaleY = 0;
126  if (parsedArgs.count("scale-y"))
127  scaleY = us::any_cast<float>(parsedArgs["scale-y"]);
128 
129  float scaleZ = 0;
130  if (parsedArgs.count("scale-z"))
131  scaleZ = us::any_cast<float>(parsedArgs["scale-z"]);
132 
133  float translateX = 0;
134  if (parsedArgs.count("translate-x"))
135  translateX = us::any_cast<float>(parsedArgs["translate-x"]);
136 
137  float translateY = 0;
138  if (parsedArgs.count("translate-y"))
139  translateY = us::any_cast<float>(parsedArgs["translate-y"]);
140 
141  float translateZ = 0;
142  if (parsedArgs.count("translate-z"))
143  translateZ = us::any_cast<float>(parsedArgs["translate-z"]);
144 
145 
146  string inFileName = us::any_cast<string>(parsedArgs["input"]);
147  string outFileName = us::any_cast<string>(parsedArgs["outFile"]);
148 
149  try
150  {
151  mitk::FiberBundle::Pointer fib = LoadFib(inFileName);
152 
153  if (minFiberLength>0)
154  fib->RemoveShortFibers(minFiberLength);
155 
156  if (maxFiberLength>0)
157  fib->RemoveLongFibers(maxFiberLength);
158 
159  if (maxAngularDev>0)
160  {
161  auto filter = itk::FiberCurvatureFilter::New();
162  filter->SetInputFiberBundle(fib);
163  filter->SetAngularDeviation(maxAngularDev);
164  filter->SetDistance(10);
165  filter->SetRemoveFibers(true);
166  filter->Update();
167  fib = filter->GetOutputFiberBundle();
168  }
169 
170  if (smoothDist>0)
171  fib->ResampleSpline(smoothDist);
172 
173  if (compress>0)
174  fib->Compress(compress);
175 
176  if (axis/100==1)
177  fib->MirrorFibers(0);
178 
179  if ((axis%100)/10==1)
180  fib->MirrorFibers(1);
181 
182  if (axis%10==1)
183  fib->MirrorFibers(2);
184 
185 
186  if (rotateX > 0 || rotateY > 0 || rotateZ > 0){
187  std::cout << "Rotate " << rotateX << " " << rotateY << " " << rotateZ;
188  fib->RotateAroundAxis(rotateX, rotateY, rotateZ);
189  }
190  if (translateX > 0 || translateY > 0 || translateZ > 0){
191  fib->TranslateFibers(translateX, translateY, translateZ);
192  }
193  if (scaleX > 0 || scaleY > 0 || scaleZ > 0)
194  fib->ScaleFibers(scaleX, scaleY, scaleZ);
195 
196  mitk::IOUtil::SaveBaseData(fib.GetPointer(), outFileName );
197 
198  }
199  catch (itk::ExceptionObject e)
200  {
201  std::cout << e;
202  return EXIT_FAILURE;
203  }
204  catch (std::exception e)
205  {
206  std::cout << e.what();
207  return EXIT_FAILURE;
208  }
209  catch (...)
210  {
211  std::cout << "ERROR!?!";
212  return EXIT_FAILURE;
213  }
214  return EXIT_SUCCESS;
215 }
void setContributor(std::string contributor)
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
static Pointer New()
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)
static const std::string filename
Definition: usAny.h:163
Base Class for Fiber Bundles;.
void setCategory(std::string category)
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
int main(int argc, char *argv[])
Modify input tractogram: fiber resampling, compression, pruning and transformation.
static DataStorage::SetOfObjects::Pointer Load(const std::string &path, DataStorage &storage)
Load a file into the given DataStorage.
Definition: mitkIOUtil.cpp:483
void setTitle(std::string title)
void setDescription(std::string description)
mitk::FiberBundle::Pointer LoadFib(std::string filename)