Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkImageToSurfaceFilter.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 "mitkException.h"
15 #include <vtkDecimatePro.h>
16 #include <vtkImageChangeInformation.h>
17 #include <vtkImageData.h>
18 #include <vtkLinearTransform.h>
19 #include <vtkMath.h>
20 #include <vtkMatrix4x4.h>
21 #include <vtkQuadricDecimation.h>
22 
23 #include <vtkCleanPolyData.h>
24 #include <vtkPolyDataNormals.h>
25 #include <vtkSmartPointer.h>
26 
27 #include "mitkProgressBar.h"
28 
30  : m_Smooth(false),
31  m_Decimate(NoDecimation),
32  m_Threshold(1.0),
33  m_TargetReduction(0.95f),
34  m_SmoothIteration(50),
35  m_SmoothRelaxation(0.1)
36 {
37 }
38 
40 {
41 }
42 
44  vtkImageData *vtkimage,
45  mitk::Surface *surface,
46  const ScalarType threshold)
47 {
48  vtkImageChangeInformation *indexCoordinatesImageFilter = vtkImageChangeInformation::New();
49  indexCoordinatesImageFilter->SetInputData(vtkimage);
50  indexCoordinatesImageFilter->SetOutputOrigin(0.0, 0.0, 0.0);
51 
52  // MarchingCube -->create Surface
53  vtkSmartPointer<vtkMarchingCubes> skinExtractor = vtkSmartPointer<vtkMarchingCubes>::New();
54  skinExtractor->ComputeScalarsOff();
55  skinExtractor->SetInputConnection(indexCoordinatesImageFilter->GetOutputPort()); // RC++
56  indexCoordinatesImageFilter->Delete();
57  skinExtractor->SetValue(0, threshold);
58 
59  vtkPolyData *polydata;
60  skinExtractor->Update();
61  polydata = skinExtractor->GetOutput();
62  polydata->Register(nullptr); // RC++
63 
64  if (m_Smooth)
65  {
66  vtkSmoothPolyDataFilter *smoother = vtkSmoothPolyDataFilter::New();
67  // read poly1 (poly1 can be the original polygon, or the decimated polygon)
68  smoother->SetInputConnection(skinExtractor->GetOutputPort()); // RC++
69  smoother->SetNumberOfIterations(m_SmoothIteration);
70  smoother->SetRelaxationFactor(m_SmoothRelaxation);
71  smoother->SetFeatureAngle(60);
72  smoother->FeatureEdgeSmoothingOff();
73  smoother->BoundarySmoothingOff();
74  smoother->SetConvergence(0);
75  smoother->Update();
76 
77  polydata->Delete(); // RC--
78  polydata = smoother->GetOutput();
79  polydata->Register(nullptr); // RC++
80  smoother->Delete();
81  }
83 
84  // decimate = to reduce number of polygons
85  if (m_Decimate == DecimatePro)
86  {
87  vtkDecimatePro *decimate = vtkDecimatePro::New();
88  decimate->SplittingOff();
89  decimate->SetErrorIsAbsolute(5);
90  decimate->SetFeatureAngle(30);
91  decimate->PreserveTopologyOn();
92  decimate->BoundaryVertexDeletionOff();
93  decimate->SetDegree(10); // std-value is 25!
94 
95  decimate->SetInputData(polydata); // RC++
96  decimate->SetTargetReduction(m_TargetReduction);
97  decimate->SetMaximumError(0.002);
98  decimate->Update();
99 
100  polydata->Delete(); // RC--
101  polydata = decimate->GetOutput();
102  polydata->Register(nullptr); // RC++
103  decimate->Delete();
104  }
105  else if (m_Decimate == QuadricDecimation)
106  {
107  vtkQuadricDecimation *decimate = vtkQuadricDecimation::New();
108  decimate->SetTargetReduction(m_TargetReduction);
109 
110  decimate->SetInputData(polydata);
111  decimate->Update();
112  polydata->Delete();
113  polydata = decimate->GetOutput();
114  polydata->Register(nullptr);
115  decimate->Delete();
116  }
117 
119 
120  if (polydata->GetNumberOfPoints() > 0)
121  {
122  mitk::Vector3D spacing = GetInput()->GetGeometry(time)->GetSpacing();
123 
124  vtkPoints *points = polydata->GetPoints();
125  vtkMatrix4x4 *vtkmatrix = vtkMatrix4x4::New();
126  GetInput()->GetGeometry(time)->GetVtkTransform()->GetMatrix(vtkmatrix);
127  double(*matrix)[4] = vtkmatrix->Element;
128 
129  unsigned int i, j;
130  for (i = 0; i < 3; ++i)
131  for (j = 0; j < 3; ++j)
132  matrix[i][j] /= spacing[j];
133 
134  unsigned int n = points->GetNumberOfPoints();
135  double point[3];
136 
137  for (i = 0; i < n; i++)
138  {
139  points->GetPoint(i, point);
140  mitkVtkLinearTransformPoint(matrix, point, point);
141  points->SetPoint(i, point);
142  }
143  vtkmatrix->Delete();
144  }
146 
147  // determine point_data normals for the poly data points.
148  vtkSmartPointer<vtkPolyDataNormals> normalsGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
149  normalsGenerator->SetInputData(polydata);
150  normalsGenerator->FlipNormalsOn();
151 
152  vtkSmartPointer<vtkCleanPolyData> cleanPolyDataFilter = vtkSmartPointer<vtkCleanPolyData>::New();
153  cleanPolyDataFilter->SetInputConnection(normalsGenerator->GetOutputPort());
154  cleanPolyDataFilter->PieceInvariantOff();
155  cleanPolyDataFilter->ConvertLinesToPointsOff();
156  cleanPolyDataFilter->ConvertPolysToLinesOff();
157  cleanPolyDataFilter->ConvertStripsToPolysOff();
158  cleanPolyDataFilter->PointMergingOn();
159  cleanPolyDataFilter->Update();
160 
161  surface->SetVtkPolyData(cleanPolyDataFilter->GetOutput(), time);
162  polydata->UnRegister(nullptr);
163 }
164 
166 {
167  mitk::Surface *surface = this->GetOutput();
168  auto *image = (mitk::Image *)GetInput();
169  if (image == nullptr || !image->IsInitialized())
170  mitkThrow() << "No input image set, please set an valid input image!";
171 
172  mitk::Image::RegionType outputRegion = image->GetRequestedRegion();
173 
174  int tstart = outputRegion.GetIndex(3);
175  int tmax = tstart + outputRegion.GetSize(3); // GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgeloest
176 
177  if ((tmax - tstart) > 0)
178  {
179  ProgressBar::GetInstance()->AddStepsToDo(4 * (tmax - tstart));
180  }
181 
182  int t;
183  for (t = tstart; t < tmax; ++t)
184  {
185  vtkImageData *vtkimagedata = image->GetVtkImageData(t);
186  CreateSurface(t, vtkimagedata, surface, m_Threshold);
188  }
189 }
190 
192 {
193  m_SmoothIteration = smoothIteration;
194 }
195 
197 {
198  m_SmoothRelaxation = smoothRelaxation;
199 }
200 
202 {
203  // Process object is not const-correct so the const_cast is required here
204  this->ProcessObject::SetNthInput(0, const_cast<mitk::Image *>(image));
205 }
206 
208 {
209  if (this->GetNumberOfInputs() < 1)
210  {
211  return nullptr;
212  }
213 
214  return static_cast<const mitk::Image *>(this->ProcessObject::GetInput(0));
215 }
216 
218 {
219  mitk::Image::ConstPointer inputImage = (mitk::Image *)this->GetInput();
220 
221  // mitk::Image *inputImage = (mitk::Image*)this->GetImage();
222  mitk::Surface::Pointer output = this->GetOutput();
223 
224  itkDebugMacro(<< "GenerateOutputInformation()");
225 
226  if (inputImage.IsNull())
227  return;
228 
229  // Set Data
230 }
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:28
double ScalarType
vtkLinearTransform * GetVtkTransform() const
Get the m_IndexToWorldTransform as a vtkLinearTransform.
OutputType * GetOutput()
const mitk::Image * GetInput(void)
virtual void SetInput(const mitk::Image *image)
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
void mitkVtkLinearTransformPoint(T1 matrix[4][4], T2 in[3], T3 out[3])
void SetSmoothRelaxation(float smoothRelaxation)
itk::ImageRegion< RegionDimension > RegionType
#define mitkThrow()
Image class for storing images.
Definition: mitkImage.h:72
void CreateSurface(int time, vtkImageData *vtkimage, mitk::Surface *surface, const ScalarType threshold)
virtual void SetVtkPolyData(vtkPolyData *polydata, unsigned int t=0)
mitk::Image::Pointer image
void AddStepsToDo(unsigned int steps)
Adds steps to totalSteps.
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
void SetSmoothIteration(int smoothIteration)
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:138