Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
ConnectednessFeatureMaps.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 <mitkIOUtil.h>
18 
19 #include "mitkCommandLineParser.h"
20 #include "mitkITKImageImport.h"
21 #include "mitkImage.h"
22 #include <itkDiffusionTensor3D.h>
23 #include <mitkImageCast.h>
24 #include <mitkTensorImage.h>
25 
26 #include <itkConnectednessFilter.h>
27 
28 // ITK
29 #include "itkBinaryErodeImageFilter.h"
30 #include "itkFlatStructuringElement.h"
31 
32 using namespace std;
33 
34 typedef itk::Image<unsigned char, 3> BinaryType;
35 typedef itk::Image<mitk::ScalarType, 3> ResultType;
36 typedef itk::Image<itk::DiffusionTensor3D<float>, 3> ItkTensorImage;
37 
38 int main(int argc, char *argv[])
39 {
40  // Setup CLI Module parsable interface
41  mitkCommandLineParser parser;
42  parser.setTitle("Connectedness Maps");
43  parser.setCategory("Features");
44  parser.setDescription("Computes connectedness maps");
45  parser.setContributor("MBI");
46 
47  parser.setArgumentPrefix("--", "-");
48  parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "input file");
49  parser.addArgument("seed", "s", mitkCommandLineParser::InputImage, "seed file");
50  parser.addArgument("mask", "m", mitkCommandLineParser::InputImage, "mask file");
51  parser.addArgument("mode", "t", mitkCommandLineParser::String, "Mode Feature | Vector | FeatureVector");
52  parser.addArgument("vector", "v", mitkCommandLineParser::InputImage, "Tensor Image (.dti)");
53  parser.addArgument(
54  "confidence", "c", mitkCommandLineParser::InputImage, "confidence map (only when Tensor Images are used)");
55  parser.addArgument("valueImage", "x", mitkCommandLineParser::InputImage, "image of values that are propagated");
56 
57  parser.addArgument("erodeSeed", "a", mitkCommandLineParser::Bool, "apply erosion of seed region");
58 
59  parser.addArgument("rankFilter", "r", mitkCommandLineParser::Bool, "median filter for propagation");
60 
61  parser.addArgument("propMap", "p", mitkCommandLineParser::OutputFile, "[out] propagated map");
62  parser.addArgument("distanceMap", "d", mitkCommandLineParser::OutputFile, "[out] connectedness map");
63  parser.addArgument("euclidDistanceMap", "e", mitkCommandLineParser::OutputFile, "[out] euclid distance map");
64 
65  // Parse input parameters
66  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
67 
68  // Show a help message
69  if (parsedArgs.size() == 0 || parsedArgs.count("help") || parsedArgs.count("h"))
70  {
71  std::cout << parser.helpText();
72  return EXIT_SUCCESS;
73  }
74 
75  bool useRank = false;
76  bool applyErosion = false;
77  bool useValueImage = false;
78  if (parsedArgs.count("rankFilter") || parsedArgs.count("r"))
79  useRank = true;
80 
81  if (parsedArgs.count("valueImage") || parsedArgs.count("x"))
82  useValueImage = true;
83 
84  if (parsedArgs.count("erodeSeed") || parsedArgs.count("a"))
85  applyErosion = true;
86 
87  std::string inputFile = us::any_cast<string>(parsedArgs["input"]);
88  std::string propMap = us::any_cast<string>(parsedArgs["propMap"]);
89  std::string conMap = us::any_cast<string>(parsedArgs["distanceMap"]);
90  std::string tensImageFile = us::any_cast<string>(parsedArgs["vector"]);
91  std::string maskFile = us::any_cast<string>(parsedArgs["mask"]);
92  std::string mode = us::any_cast<string>(parsedArgs["mode"]);
93  std::string seedFile = us::any_cast<string>(parsedArgs["seed"]);
94  std::string confFile = us::any_cast<string>(parsedArgs["confidence"]);
95  std::string euclidFile = us::any_cast<string>(parsedArgs["euclidDistanceMap"]);
96 
97  std::string valueImageFile = "";
98  if (useValueImage)
99  valueImageFile = us::any_cast<string>(parsedArgs["valueImage"]);
100 
101  // Read-in image data
102  mitk::Image::Pointer tmpImage;
103  mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputFile);
104  mitk::Image::Pointer maskImage = mitk::IOUtil::LoadImage(maskFile);
105  mitk::Image::Pointer seedImage = mitk::IOUtil::LoadImage(seedFile);
106 
107  mitk::Image::Pointer valueImage;
108  if (useValueImage)
109  valueImage = mitk::IOUtil::LoadImage(valueImageFile);
110 
111  mitk::Image::Pointer confImage;
112  if (mode == "Vector" || mode == "FeatureVector")
113  {
114  MITK_INFO << "Load Tensor/Confidence";
115  tmpImage = mitk::IOUtil::LoadImage(tensImageFile);
116  confImage = mitk::IOUtil::LoadImage(confFile);
117  }
118 
119  mitk::TensorImage *diffusionImage = static_cast<mitk::TensorImage *>(tmpImage.GetPointer());
120 
121  // Convert all input data to ITK
126  ResultType::Pointer itkWeight = ResultType::New();
127  ResultType::Pointer itkValueImage = ResultType::New();
128 
129  mitk::CastToItkImage(inputImage, itkImage);
130  mitk::CastToItkImage(maskImage, itkMask);
131  mitk::CastToItkImage(seedImage, itkSeed);
132  if (useValueImage)
133  mitk::CastToItkImage(valueImage, itkValueImage);
134 
135  if (applyErosion)
136  {
137  typedef itk::FlatStructuringElement<3> StructuringElementType;
138  StructuringElementType::RadiusType elementRadius;
139  elementRadius.Fill(2);
140  elementRadius[2] = 0;
141  StructuringElementType structuringElement = StructuringElementType::Box(elementRadius);
142 
143  typedef itk::BinaryErodeImageFilter<BinaryType, BinaryType, StructuringElementType> BinaryErodeImageFilterType;
144 
146  erodeFilter->SetInput(itkSeed);
147  erodeFilter->SetKernel(structuringElement);
148  erodeFilter->SetForegroundValue(1);
149  erodeFilter->Update();
150  itkSeed = erodeFilter->GetOutput();
151  }
152 
153  if (mode == "Vector" || mode == "FeatureVector")
154  {
155  mitk::CastToItkImage(diffusionImage, itkTensor);
156  mitk::CastToItkImage(confImage, itkWeight);
157  }
158 
159  // Setup filter
162 
163  filter->SetInputImage(itkImage);
164  filter->SetInputSeed(itkSeed);
165  filter->SetInputMask(itkMask);
166  if (mode == "Vector")
167  {
168  filter->SetInputVectorField(itkTensor);
169  filter->SetInputVectorFieldConfidenceMap(itkWeight);
171  }
172  else if (mode == "FeatureVector")
173  {
174  filter->SetInputVectorField(itkTensor);
175  filter->SetInputVectorFieldConfidenceMap(itkWeight);
177  }
178  else
180 
181  if (useValueImage)
182  filter->SetPropagationImage(itkValueImage);
183 
184  filter->SetApplyRankFilter(useRank);
185  filter->Update();
186 
187  // Grab output and write results
189  mitk::GrabItkImageMemory(filter->GetOutput(), result);
190 
191  mitk::IOUtil::Save(result, propMap);
192 
194  mitk::GrabItkImageMemory(filter->GetDistanceImage().GetPointer(), distance);
195  mitk::IOUtil::Save(distance, conMap);
196 
197  mitk::Image::Pointer euclidDistance = mitk::Image::New();
198  mitk::GrabItkImageMemory(filter->GetEuclideanDistanceImage().GetPointer(), euclidDistance);
199  mitk::IOUtil::Save(euclidDistance, euclidFile);
200 
201  return EXIT_SUCCESS;
202 }
itk::Image< mitk::ScalarType, 3 > ResultType
static void Save(const mitk::BaseData *data, const std::string &path)
Save a mitk::BaseData instance.
Definition: mitkIOUtil.cpp:824
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
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 Pointer New()
Image::Pointer GrabItkImageMemory(itk::SmartPointer< ItkOutputImageType > &itkimage, mitk::Image *mitkImage=nullptr, const BaseGeometry *geometry=nullptr, bool update=true)
Grabs the memory of an itk::Image (with a specific type) and puts it into an mitk::Image.The memory is managed by the mitk::Image after calling this function. The itk::Image remains valid until the mitk::Image decides to free the memory.
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)
void setCategory(std::string category)
static Pointer New()
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
itk::Image< unsigned char, 3 > BinaryType
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::string helpText() const
this class encapsulates tensor images
itk::Image< itk::DiffusionTensor3D< float >, 3 > ItkTensorImage
int main(int argc, char *argv[])
void setTitle(std::string title)
void setDescription(std::string description)
static mitk::Image::Pointer LoadImage(const std::string &path)
LoadImage Convenience method to load an arbitrary mitkImage.
Definition: mitkIOUtil.cpp:597
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.