Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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)