Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkFeatureBasedEdgeDetectionFilter.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 
18 
20 #include <mitkITKImageImport.h>
21 #include <mitkImage.h>
22 #include <mitkImageAccessByItk.h>
23 #include <mitkImageStatisticsCalculator.h>
25 #include <mitkProgressBar.h>
26 #include <mitkUnstructuredGrid.h>
28 #include <mitkImageMaskGenerator.h>
29 
30 #include <itkBinaryBallStructuringElement.h>
31 #include <itkBinaryContourImageFilter.h>
32 #include <itkBinaryThresholdImageFilter.h>
33 #include <itkDilateObjectMorphologyImageFilter.h>
34 #include <itkErodeObjectMorphologyImageFilter.h>
35 #include <itkImage.h>
36 
38 {
39  this->SetNumberOfRequiredInputs(1);
40 
41  this->SetNumberOfIndexedOutputs(1);
42 }
43 
45 {
46 }
47 
49 {
51 
52  if (m_SegmentationMask.IsNull())
53  {
54  MITK_WARN << "Please set a segmentation mask first" << std::endl;
55  return;
56  }
57  // First create a threshold segmentation of the image. The threshold is determined
58  // by the mean +/- stddev of the pixel values that are covered by the segmentation mask
59 
60  // Compute mean and stdDev based on the current segmentation
62  statCalc->SetInputImage(image);
63 
65  imgMask->SetImageMask(m_SegmentationMask);
66 
67  mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer stats = statCalc->GetStatistics();
68  double mean = stats->GetMean();
69  double stdDev = stats->GetStd();
70 
71  double upperThreshold = mean + stdDev;
72  double lowerThreshold = mean - stdDev;
73 
74  // Perform thresholding
75  mitk::Image::Pointer thresholdImage = mitk::Image::New();
76  AccessByItk_3(image.GetPointer(), ITKThresholding, lowerThreshold, upperThreshold, thresholdImage)
77 
79  ->Progress(2);
80 
81  // Postprocess threshold segmentation
82  // First a closing will be executed
83  mitk::Image::Pointer closedImage = mitk::Image::New();
84  AccessByItk_1(thresholdImage, ThreadedClosing, closedImage);
85 
86  // Then we will holes that might exist
88 
90 
91  // Extract the binary edges of the resulting segmentation
93  AccessByItk_1(closedImage, ContourSearch, edgeImage);
94 
95  // Convert the edge image into an unstructured grid
97  i2UFilter->SetInput(edgeImage);
98  i2UFilter->SetThreshold(1.0);
99  i2UFilter->Update();
100 
101  m_PointGrid = this->GetOutput();
102  if (m_PointGrid.IsNull())
103  m_PointGrid = mitk::UnstructuredGrid::New();
104 
105  m_PointGrid->SetVtkUnstructuredGrid(i2UFilter->GetOutput()->GetVtkUnstructuredGrid());
106 
108 }
109 
110 template <typename TPixel, unsigned int VImageDimension>
111 void mitk::FeatureBasedEdgeDetectionFilter::ThreadedClosing(itk::Image<TPixel, VImageDimension> *originalImage,
112  mitk::Image::Pointer &result)
113 {
114  typedef itk::BinaryBallStructuringElement<TPixel, VImageDimension> myKernelType;
115 
116  myKernelType ball;
117  ball.SetRadius(1);
118  ball.CreateStructuringElement();
119 
120  typedef typename itk::Image<TPixel, VImageDimension> ImageType;
121 
124  dilationFilter->SetInput(originalImage);
125  dilationFilter->SetKernel(ball);
126  dilationFilter->Update();
127 
128  typename itk::Image<TPixel, VImageDimension>::Pointer dilatedImage = dilationFilter->GetOutput();
129 
132  erodeFilter->SetInput(dilatedImage);
133  erodeFilter->SetKernel(ball);
134  erodeFilter->Update();
135 
136  mitk::GrabItkImageMemory(erodeFilter->GetOutput(), result);
137 }
138 
139 template <typename TPixel, unsigned int VImageDimension>
140 void mitk::FeatureBasedEdgeDetectionFilter::ContourSearch(itk::Image<TPixel, VImageDimension> *originalImage,
141  mitk::Image::Pointer &result)
142 {
143  typedef itk::Image<TPixel, VImageDimension> ImageType;
144  typedef itk::BinaryContourImageFilter<ImageType, ImageType> binaryContourImageFilterType;
145  typedef unsigned short OutputPixelType;
146  typedef itk::Image<OutputPixelType, VImageDimension> OutputImageType;
147 
149  binaryContourFilter->SetInput(originalImage);
150  binaryContourFilter->SetForegroundValue(1);
151  binaryContourFilter->SetBackgroundValue(0);
152  binaryContourFilter->Update();
153 
155  itkImage->Graft(binaryContourFilter->GetOutput());
156 
157  mitk::GrabItkImageMemory(itkImage, result);
158 }
159 
160 template <typename TPixel, unsigned int VImageDimension>
161 void mitk::FeatureBasedEdgeDetectionFilter::ITKThresholding(itk::Image<TPixel, VImageDimension> *originalImage,
162  double lower,
163  double upper,
164  mitk::Image::Pointer &result)
165 {
166  typedef itk::Image<TPixel, VImageDimension> ImageType;
167  typedef itk::Image<unsigned short, VImageDimension> SegmentationType;
168  typedef itk::BinaryThresholdImageFilter<ImageType, SegmentationType> ThresholdFilterType;
169 
170  if (typeid(TPixel) != typeid(float) && typeid(TPixel) != typeid(double))
171  {
172  // round the thresholds if we have nor a float or double image
173  lower = std::floor(lower + 0.5);
174  upper = std::floor(upper - 0.5);
175  }
176  if (lower >= upper)
177  {
178  upper = lower;
179  }
180 
182  filter->SetInput(originalImage);
183  filter->SetLowerThreshold(lower);
184  filter->SetUpperThreshold(upper);
185  filter->SetInsideValue(1);
186  filter->SetOutsideValue(0);
187  filter->Update();
188 
189  mitk::GrabItkImageMemory(filter->GetOutput(), result);
190 }
191 
193 {
194  this->m_SegmentationMask = segmentation;
195 }
196 
198 {
199  Superclass::GenerateOutputInformation();
200 }
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
#define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3)
itk::SmartPointer< Self > Pointer
void ContourSearch(itk::Image< TPixel, VImageDimension > *originalImage, mitk::Image::Pointer &result)
void ITKThresholding(itk::Image< TPixel, VImageDimension > *originalImage, double lower, double upper, mitk::Image::Pointer &result)
static Pointer New()
void ThreadedClosing(itk::Image< TPixel, VImageDimension > *originalImage, mitk::Image::Pointer &result)
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1)
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
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.
static Pointer New()
map::core::discrete::Elements< 3 >::InternalImageType ImageType
#define MITK_WARN
Definition: mitkLogMacros.h:23
static Pointer New()
static void ITKThresholding(itk::Image< TPixel, VImageDimension > *originalImage, mitk::Image *segmentation, double lower, double upper, unsigned int timeStep)
static Pointer New()
static void FillHoles(mitk::Image::Pointer &image)
Perform morphological operation on 2D, 3D or 3D+t segmentation.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.