Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkImageToContourFilter.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 #include "mitkImageAccessByItk.h"
19 #include "mitkImageCast.h"
21 #include "vtkLinearTransform.h"
22 #include "vtkMatrix4x4.h"
23 #include "vtkProperty.h"
24 #include "vtkSmartPointer.h"
25 
26 #include <itkConstantPadImageFilter.h>
27 
29 {
30  this->m_UseProgressBar = false;
31  this->m_ProgressStepSize = 1;
32 }
33 
35 {
36 }
37 
39 {
41 
42  if (!sliceImage)
43  {
44  MITK_ERROR << "mitk::ImageToContourFilter: No input available. Please set the input!" << std::endl;
45  itkExceptionMacro("mitk::ImageToContourFilter: No input available. Please set the input!");
46  return;
47  }
48 
49  if (sliceImage->GetDimension() > 2 || sliceImage->GetDimension() < 2)
50  {
51  MITK_ERROR << "mitk::ImageToImageFilter::GenerateData() works only with 2D images. Please assure that your input "
52  "image is 2D!"
53  << std::endl;
54  itkExceptionMacro(
55  "mitk::ImageToImageFilter::GenerateData() works only with 2D images. Please assure that your input image is 2D!");
56  return;
57  }
58 
59  m_SliceGeometry = sliceImage->GetGeometry();
60 
61  AccessFixedDimensionByItk(sliceImage, Itk2DContourExtraction, 2);
62 
63  // Setting progressbar
64  if (this->m_UseProgressBar)
65  mitk::ProgressBar::GetInstance()->Progress(this->m_ProgressStepSize);
66 }
67 
68 template <typename TPixel, unsigned int VImageDimension>
69 void mitk::ImageToContourFilter::Itk2DContourExtraction(const itk::Image<TPixel, VImageDimension> *sliceImage)
70 {
71  typedef itk::Image<TPixel, VImageDimension> ImageType;
72  typedef itk::ContourExtractor2DImageFilter<ImageType> ContourExtractor;
73 
74  typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType;
75  typename PadFilterType::Pointer padFilter = PadFilterType::New();
76  typename ImageType::SizeType lowerExtendRegion;
77  lowerExtendRegion[0] = 1;
78  lowerExtendRegion[1] = 1;
79 
80  typename ImageType::SizeType upperExtendRegion;
81  upperExtendRegion[0] = 1;
82  upperExtendRegion[1] = 1;
83 
84  /*
85  * We need to pad here, since the ITK contour extractor fails if the
86  * segmentation touches more than one image edge.
87  * By padding the image for one row at each edge we overcome this issue
88  */
89  padFilter->SetInput(sliceImage);
90  padFilter->SetConstant(0);
91  padFilter->SetPadLowerBound(lowerExtendRegion);
92  padFilter->SetPadUpperBound(upperExtendRegion);
93 
94  typename ContourExtractor::Pointer contourExtractor = ContourExtractor::New();
95  contourExtractor->SetInput(padFilter->GetOutput());
96  contourExtractor->SetContourValue(0.5);
97 
98  contourExtractor->Update();
99 
100  unsigned int foundPaths = contourExtractor->GetNumberOfOutputs();
101 
102  vtkSmartPointer<vtkPolyData> contourSurface = vtkSmartPointer<vtkPolyData>::New();
103  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
104  vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();
105 
106  unsigned int pointId(0);
107 
108  for (unsigned int i = 0; i < foundPaths; i++)
109  {
110  const ContourPath *currentPath = contourExtractor->GetOutput(i)->GetVertexList();
111 
112  vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
113  polygon->GetPointIds()->SetNumberOfIds(currentPath->Size());
114 
115  Point3D currentPoint;
116  Point3D currentWorldPoint;
117 
118  for (unsigned int j = 0; j < currentPath->Size(); j++)
119  {
120  currentPoint[0] = currentPath->ElementAt(j)[0];
121  currentPoint[1] = currentPath->ElementAt(j)[1];
122  currentPoint[2] = 0;
123 
124  m_SliceGeometry->IndexToWorld(currentPoint, currentWorldPoint);
125 
126  points->InsertPoint(pointId, currentWorldPoint[0], currentWorldPoint[1], currentWorldPoint[2]);
127  polygon->GetPointIds()->SetId(j, pointId);
128  pointId++;
129 
130  } // for2
131 
132  polygons->InsertNextCell(polygon);
133 
134  } // for1
135 
136  contourSurface->SetPoints(points);
137  contourSurface->SetPolys(polygons);
138  contourSurface->BuildLinks();
139  Surface::Pointer finalSurface = this->GetOutput();
140 
141  finalSurface->SetVtkPolyData(contourSurface);
142 }
143 
145 {
146  Superclass::GenerateOutputInformation();
147 }
148 
150 {
151  this->m_UseProgressBar = status;
152 }
153 
155 {
156  this->m_ProgressStepSize = stepSize;
157 }
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
itk::SmartPointer< Self > Pointer
#define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension)
Access a mitk-image with known dimension by an itk-image.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
const mitk::Image * GetInput(void)
itk::SmartPointer< Self > Pointer
Definition: mitkSurface.h:37
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
virtual void GenerateData() override
void SetProgressStepSize(unsigned int stepSize)
Set the stepsize which the progress bar should proceed.
map::core::discrete::Elements< 3 >::InternalImageType ImageType
void SetUseProgressBar(bool)
Set whether the mitkProgressBar should be used.
virtual void GenerateOutputInformation() override
Computes a list of PolyLineParametricPath objects from the contours in a 2D image.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.