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