Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
PeaksAngularError.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>
21 #include <metaCommand.h>
22 #include "mitkCommandLineParser.h"
24 #include <usAny.h>
25 #include <itkImageFileWriter.h>
26 #include <mitkIOUtil.h>
27 #include <boost/lexical_cast.hpp>
28 #include <iostream>
29 #include <fstream>
30 
31 #define _USE_MATH_DEFINES
32 #include <math.h>
33 
34 using namespace std;
35 
39 int main(int argc, char* argv[])
40 {
41  mitkCommandLineParser parser;
42  parser.setArgumentPrefix("--", "-");
43  parser.addArgument("test", "t", mitkCommandLineParser::StringList, "Test images", "test direction images", us::Any(), false);
44  parser.addArgument("reference", "r", mitkCommandLineParser::StringList, "Reference images", "reference direction images", us::Any(), false);
45  parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false);
46  parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image");
47  parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose", "output optional and intermediate calculation results");
48  parser.addArgument("ignore", "i", mitkCommandLineParser::Bool, "Ignore", "don't increase error for missing or too many directions");
49 
50  parser.setCategory("Preprocessing Tools");
51  parser.setTitle("Peaks Angular Error");
52  parser.setDescription("Calculate angular error between two sets of directions stored in multiple 3D vector images where each pixel corresponds to a vector (itk::Image< itk::Vector< float, 3>, 3 >)");
53  parser.setContributor("MBI");
54 
55  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
56  if (parsedArgs.size()==0)
57  return EXIT_FAILURE;
58 
61 
62  string maskImage("");
63  if (parsedArgs.count("mask"))
64  maskImage = us::any_cast<string>(parsedArgs["mask"]);
65 
66  string outRoot = us::any_cast<string>(parsedArgs["out"]);
67 
68  bool verbose = false;
69  if (parsedArgs.count("verbose"))
70  verbose = us::any_cast<bool>(parsedArgs["verbose"]);
71 
72  bool ignore = false;
73  if (parsedArgs.count("ignore"))
74  ignore = us::any_cast<bool>(parsedArgs["ignore"]);
75 
76  try
77  {
78  typedef itk::Image<unsigned char, 3> ItkUcharImgType;
79  typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType;
80  typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType;
81  typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType;
82 
84  for (unsigned int i=0; i<testImages.size(); i++)
85  {
86  try
87  {
88  mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(testImages.at(i))->GetData());
91  caster->SetInput(img);
92  caster->Update();
93  ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput();
94  directionImageContainer->InsertElement(directionImageContainer->Size(),itkImg);
95  }
96  catch(...){ std::cout << "could not load: " << referenceImages.at(i); }
97  }
98 
99  // load reference directions
101  for (unsigned int i=0; i<referenceImages.size(); i++)
102  {
103  try
104  {
105  mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData());
108  caster->SetInput(img);
109  caster->Update();
110  ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput();
111  referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg);
112  }
113  catch(...){ std::cout << "could not load: " << referenceImages.at(i); }
114  }
115 
116  // load/create mask image
118  if (maskImage.compare("")==0)
119  {
120  ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0);
121  itkMaskImage->SetSpacing( dirImg->GetSpacing() );
122  itkMaskImage->SetOrigin( dirImg->GetOrigin() );
123  itkMaskImage->SetDirection( dirImg->GetDirection() );
124  itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() );
125  itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() );
126  itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() );
127  itkMaskImage->Allocate();
128  itkMaskImage->FillBuffer(1);
129  }
130  else
131  {
132  mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(maskImage)->GetData());
133  mitk::CastToItkImage(mitkMaskImage, itkMaskImage);
134  }
135 
136  // evaluate directions
138  evaluationFilter->SetImageSet(directionImageContainer);
139  evaluationFilter->SetReferenceImageSet(referenceImageContainer);
140  evaluationFilter->SetMaskImage(itkMaskImage);
141  evaluationFilter->SetIgnoreMissingDirections(ignore);
142  evaluationFilter->Update();
143 
144  if (verbose)
145  {
146  EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0);
147  typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType;
149 
150  string outfilename = outRoot;
151  outfilename.append("_ERROR_IMAGE.nrrd");
152 
153  writer->SetFileName(outfilename.c_str());
154  writer->SetInput(angularErrorImage);
155  writer->Update();
156  }
157 
158  string logFile = outRoot;
159  logFile.append("_ANGULAR_ERROR.csv");
160 
161  ofstream file;
162  file.open (logFile.c_str());
163 
164  string sens = "Mean:";
165  sens.append(",");
166  sens.append(boost::lexical_cast<string>(evaluationFilter->GetMeanAngularError()));
167  sens.append(";\n");
168 
169  sens.append("Median:");
170  sens.append(",");
171  sens.append(boost::lexical_cast<string>(evaluationFilter->GetMedianAngularError()));
172  sens.append(";\n");
173 
174  sens.append("Maximum:");
175  sens.append(",");
176  sens.append(boost::lexical_cast<string>(evaluationFilter->GetMaxAngularError()));
177  sens.append(";\n");
178 
179  sens.append("Minimum:");
180  sens.append(",");
181  sens.append(boost::lexical_cast<string>(evaluationFilter->GetMinAngularError()));
182  sens.append(";\n");
183 
184  sens.append("STDEV:");
185  sens.append(",");
186  sens.append(boost::lexical_cast<string>(std::sqrt(evaluationFilter->GetVarAngularError())));
187  sens.append(";\n");
188 
189  file << sens;
190 
191  file.close();
192  }
193  catch (itk::ExceptionObject e)
194  {
195  std::cout << e;
196  return EXIT_FAILURE;
197  }
198  catch (std::exception e)
199  {
200  std::cout << e.what();
201  return EXIT_FAILURE;
202  }
203  catch (...)
204  {
205  std::cout << "ERROR!?!";
206  return EXIT_FAILURE;
207  }
208  return EXIT_SUCCESS;
209 }
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)
T::Pointer GetData(const std::string &name)
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)
Evaluates the voxel-wise angular error between two sets of directions.
Image class for storing images.
Definition: mitkImage.h:76
static std::ofstream * logFile
Definition: mitkLog.cpp:30
Definition: usAny.h:163
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.
std::vector< std::string > StringContainerType
void setTitle(std::string title)
void setDescription(std::string description)
int main(int argc, char *argv[])
Calculate angular error between two sets of directions stored in multiple 3D vector images where each...
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.