Medical Imaging Interaction Toolkit  2018.4.99-b585543d
Medical Imaging Interaction Toolkit
CLLungSegmentation.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkProperties.h"
14 
15 #include "mitkCommandLineParser.h"
16 #include "mitkIOUtil.h"
17 
19 #include "mitkLabelSetImage.h"
20 
21 #include "mitkImageCast.h"
22 #include "mitkImageTimeSelector.h"
23 #include "mitkITKImageImport.h"
24 #include "mitkImageAccessByItk.h"
25 
27 
28 #include <itkConnectedThresholdImageFilter.h>
29 #include <itkImageRegionConstIterator.h>
30 
31 template<typename TPixel, unsigned int VImageDimension>
32 void GetMinimum(itk::Image<TPixel, VImageDimension>* itkImage, double &minimum)
33 {
34  typedef itk::Image<TPixel, VImageDimension> InputImageType;
35 
37  itk::ImageRegionConstIterator<InputImageType> iter(itkImage, itkImage->GetLargestPossibleRegion());
38 
39  while (!iter.IsAtEnd())
40  {
41  minimum = std::min<double>(minimum, iter.Get());
42  ++iter;
43  }
44 }
45 
46 template<typename TPixel, unsigned int VImageDimension>
47 void StartRegionGrowing(itk::Image<TPixel, VImageDimension>* itkImage, mitk::Image::Pointer &result)
48 {
49  typedef itk::Image<TPixel, VImageDimension> InputImageType;
50  typedef typename InputImageType::IndexType IndexType;
51  typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
52  typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
53 
54  // convert world coordinates to image indices
55  IndexType startIndex;
56  IndexType seedIndex;
57  IndexType bestSeedIndex;
58  startIndex[0] = itkImage->GetLargestPossibleRegion().GetSize()[0]/2;
59  startIndex[1] = itkImage->GetLargestPossibleRegion().GetSize()[1]/2;
60  startIndex[2] = itkImage->GetLargestPossibleRegion().GetSize()[2]/2;
61  auto region = itkImage->GetLargestPossibleRegion();
62  auto spacing = itkImage->GetSpacing();
63  spacing[0] = itkImage->GetSpacing()[0];
64  spacing[1] = itkImage->GetSpacing()[1];
65  spacing[2] = itkImage->GetSpacing()[2];
66 
67  int minimumDistance = 50 * 50 * (spacing[0] + spacing[1] + spacing[2]);
68 
69  for (int x = -50; x < 50; ++x)
70  {
71  for (int y = -50; y < 50; ++y)
72  {
73  for (int z = -20; z < 20; ++z)
74  {
75  seedIndex[0] = startIndex[0] + x;
76  seedIndex[1] = startIndex[1] + y;
77  seedIndex[2] = startIndex[2] + z;
78  if (region.IsInside(seedIndex))
79  {
80  if (itkImage->GetPixel(seedIndex) > 0)
81  {
82  int newDistance = x*x*spacing[0] + y*y*spacing[1] + z*z*spacing[2];
83  if (newDistance < minimumDistance)
84  {
85  bestSeedIndex = seedIndex;
86  minimumDistance = newDistance;
87  }
88  }
89  }
90  }
91  }
92  }
93  seedIndex = bestSeedIndex;
94 
95  MITK_INFO << "Seedpoint: " << seedIndex;
96  //perform region growing in desired segmented region
97  regionGrower->SetInput(itkImage);
98  regionGrower->AddSeed(seedIndex);
99 
100  regionGrower->SetLower(1);
101  regionGrower->SetUpper(255);
102 
103  try
104  {
105  regionGrower->Update();
106  }
107  catch (const itk::ExceptionObject&)
108  {
109  return; // can't work
110  }
111  catch (...)
112  {
113  return;
114  }
115 
116  //Store result and preview
117  mitk::CastToMitkImage(regionGrower->GetOutput(), result);
118 }
119 
120 int main(int argc, char* argv[])
121 {
122  mitkCommandLineParser parser;
123 
124  parser.setTitle("Dicom Loader");
125  parser.setCategory("Preprocessing Tools");
126  parser.setDescription("");
127  parser.setContributor("German Cancer Research Center (DKFZ)");
128 
129  parser.setArgumentPrefix("--","-");
130  // Add command line argument names
131  parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text");
132  parser.addArgument("input", "i", mitkCommandLineParser::Directory, "Input folder:", "Input folder", us::Any(), false, false, false, mitkCommandLineParser::Input);
133  parser.addArgument("output", "o", mitkCommandLineParser::File, "Output file:", "Output file",us::Any(),false, false, false, mitkCommandLineParser::Output);
134 
135 
136  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
137 
138  if (parsedArgs.size()==0)
139  return EXIT_FAILURE;
140 
141  // Show a help message
142  if ( parsedArgs.count("help") || parsedArgs.count("h"))
143  {
144  std::cout << parser.helpText();
145  return EXIT_SUCCESS;
146  }
147 
148  std::string inputFile = us::any_cast<std::string>(parsedArgs["input"]);
149  std::string outFileName = us::any_cast<std::string>(parsedArgs["output"]);
150 
151  MITK_INFO << "Start Image Loading";
152 
153  mitk::Image::Pointer image = mitk::IOUtil::Load<mitk::Image>(inputFile);
154 
155  MITK_INFO << "Loaded Image";
156  double minimum = 0;
157  AccessByItk_1(image, GetMinimum, minimum);
158 
159  unsigned int offset = 0;
160  if (minimum < -3000)
161  {
162  offset = 1;
163  }
164  MITK_INFO << "With Minimum at " << minimum<< " Offset is set to: " << offset;
165 
167  otsuFilter->SetNumberOfThresholds(1+offset);
168  otsuFilter->SetValleyEmphasis(false);
169  otsuFilter->SetNumberOfBins(128);
170  otsuFilter->SetInput(image);
171  try
172  {
173  otsuFilter->Update();
174  }
175  catch (...)
176  {
177  mitkThrow() << "itkOtsuFilter error (image dimension must be in {2, 3} and image must not be RGB)";
178  }
179 
180  MITK_INFO << "Calculated Otsu";
181 
183  resultImage->InitializeByLabeledImage(otsuFilter->GetOutput());
184  mitk::Image::Pointer rawMask = resultImage->CreateLabelMask(offset);
185  mitk::Image::Pointer pickedMask;
186 
187  AccessFixedTypeByItk_n(rawMask, StartRegionGrowing, (mitk::LabelSet::PixelType), (2)(3), (pickedMask));
188 
190  mitk::MorphologicalOperations::Closing(pickedMask, 5, mitk::MorphologicalOperations::StructuralElementType::Ball);
192 
193 
194  mitk::IOUtil::Save(pickedMask, outFileName);
195 
196  return EXIT_SUCCESS;
197 }
#define AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, va_tuple)
Access a mitk-image with known type (pixel type and dimension) by an itk-image with one or more param...
void GetMinimum(itk::Image< TPixel, VImageDimension > *itkImage, double &minimum)
#define MITK_INFO
Definition: mitkLogMacros.h:18
void setContributor(std::string contributor)
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
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, mitkCommandLineParser::Channel channel=mitkCommandLineParser::Channel::None)
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1)
static void Closing(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement)
Perform morphological operation on 2D, 3D or 3D+t segmentation.
void StartRegionGrowing(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer &result)
static Vector3D offset
#define mitkThrow()
Definition: usAny.h:163
std::string helpText() const
static T max(T x, T y)
Definition: svm.cpp:56
void setCategory(std::string category)
mitk::Image::Pointer image
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
static Pointer New()
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
Definition: mitkImageCast.h:74
static void Save(const mitk::BaseData *data, const std::string &path, bool setPathProperty=false)
Save a mitk::BaseData instance.
Definition: mitkIOUtil.cpp:774
mitk::Label::PixelType PixelType
Definition: mitkLabelSet.h:37
void setTitle(std::string title)
std::string outFileName
void setDescription(std::string description)
int main(int argc, char *argv[])
static void FillHoles(mitk::Image::Pointer &image)
Perform morphological operation on 2D, 3D or 3D+t segmentation.