Medical Imaging Interaction Toolkit  2018.4.99-f51274ea
Medical Imaging Interaction Toolkit
mitkSurfaceBasedInterpolationController.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 
15 #include "mitkColorProperty.h"
18 #include "mitkIOUtil.h"
19 #include "mitkImageAccessByItk.h"
20 #include "mitkImageCast.h"
22 #include "mitkInteractionConst.h"
23 #include "mitkMemoryUtilities.h"
24 #include "mitkProperties.h"
26 
28 #include "vtkAppendPolyData.h"
29 #include "vtkPolyData.h"
30 #include "vtkProperty.h"
31 #include "vtkSmartPointer.h"
32 
33 #include <itkCommand.h>
34 
36  : m_MinSpacing(1.0), m_MaxSpacing(1.0), m_WorkingImage(nullptr), m_ActiveLabel(0)
37 {
38  this->Initialize();
39 }
40 
42 {
43  auto it = m_MapOfContourLists.begin();
44  for (; it != m_MapOfContourLists.end(); it++)
45  {
46  for (unsigned int j = 0; j < m_MapOfContourLists[(*it).first].size(); ++j)
47  {
48  delete (m_MapOfContourLists[(*it).first].at(j).second);
49  }
50  m_MapOfContourLists.erase(it);
51  }
52 }
53 
55 {
56  m_InterpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New();
57  m_InterpolateSurfaceFilter->SetUseProgressBar(false);
58 
59  m_Contours = Surface::New();
60 
61  m_InterpolationResult = nullptr;
62 }
63 
65 {
67 
68  if (m_Instance == nullptr)
69  {
70  m_Instance = new SurfaceBasedInterpolationController();
71  }
72 
73  return m_Instance;
74 }
75 
78 {
79  if (m_ActiveLabel == 0)
80  return;
81 
82  AffineTransform3D::Pointer transform = AffineTransform3D::New();
83  transform = op->GetTransform();
84 
85  mitk::Vector3D direction = op->GetDirectionVector();
86  int pos(-1);
87 
88  for (unsigned int i = 0; i < m_MapOfContourLists[m_ActiveLabel].size(); i++)
89  {
90  itk::Matrix<ScalarType> diffM =
91  transform->GetMatrix() - m_MapOfContourLists[m_ActiveLabel].at(i).second->GetTransform()->GetMatrix();
92  bool isSameMatrix(true);
93  for (unsigned int j = 0; j < 3; j++)
94  {
95  if (fabs(diffM[j][0]) > 0.0001 && fabs(diffM[j][1]) > 0.0001 && fabs(diffM[j][2]) > 0.0001)
96  {
97  isSameMatrix = false;
98  break;
99  }
100  }
101  itk::Vector<float> diffV =
102  m_MapOfContourLists[m_ActiveLabel].at(i).second->GetTransform()->GetOffset() - transform->GetOffset();
103  if (isSameMatrix && m_MapOfContourLists[m_ActiveLabel].at(i).second->GetPos() == op->GetPos() &&
104  (fabs(diffV[0]) < 0.0001 && fabs(diffV[1]) < 0.0001 && fabs(diffV[2]) < 0.0001))
105  {
106  pos = i;
107  break;
108  }
109  }
110 
111  if (pos == -1 && newContour->GetNumberOfVertices() > 0) // add a new contour
112  {
114  OpRESTOREPLANEPOSITION, op->GetWidth(), op->GetHeight(), op->GetSpacing(), op->GetPos(), direction, transform);
115  ContourPositionPair newData = std::make_pair(newContour, newOp);
116  m_MapOfContourLists[m_ActiveLabel].push_back(newData);
117  }
118  else if (pos != -1) // replace existing contour
119  {
120  m_MapOfContourLists[m_ActiveLabel].at(pos).first = newContour;
121  }
122 
123  this->Modified();
124 }
125 
127 {
128  if (m_MapOfContourLists[m_ActiveLabel].size() < 2)
129  {
130  // If no interpolation is possible reset the interpolation result
131  m_InterpolationResult = nullptr;
132  return;
133  }
134 
135  m_InterpolateSurfaceFilter->Reset();
136 
137  // MLI TODO
138  // m_InterpolateSurfaceFilter->SetReferenceImage( m_WorkingImage );
139 
140  // CreateDistanceImageFromSurfaceFilter::Pointer interpolateSurfaceFilter =
141  // CreateDistanceImageFromSurfaceFilter::New();
142  vtkSmartPointer<vtkAppendPolyData> polyDataAppender = vtkSmartPointer<vtkAppendPolyData>::New();
143 
144  for (unsigned int i = 0; i < m_MapOfContourLists[m_ActiveLabel].size(); i++)
145  {
147  converter->SetInput(m_MapOfContourLists[m_ActiveLabel].at(i).first);
148  converter->Update();
149 
150  mitk::Surface::Pointer surface = converter->GetOutput();
151  surface->DisconnectPipeline();
152 
154  reduceFilter->SetUseProgressBar(false);
155  reduceFilter->SetInput(surface);
156  reduceFilter->SetMinSpacing(m_MinSpacing);
157  reduceFilter->SetMaxSpacing(m_MaxSpacing);
158  reduceFilter->Update();
159 
161  normalsFilter->SetUseProgressBar(false);
162  normalsFilter->SetInput(reduceFilter->GetOutput());
163  normalsFilter->SetMaxSpacing(m_MaxSpacing);
164  // MLI TODO
165  // normalsFilter->SetSegmentationBinaryImage(m_WorkingImage, m_ActiveLabel);
166  // normalsFilter->Update();
167 
168  m_InterpolateSurfaceFilter->SetInput(i, normalsFilter->GetOutput());
169 
170  polyDataAppender->AddInputData(reduceFilter->GetOutput()->GetVtkPolyData());
171  }
172 
173  polyDataAppender->Update();
174  m_Contours->SetVtkPolyData(polyDataAppender->GetOutput());
175 
176  // update the filter and get the resulting distance-image
177  m_InterpolateSurfaceFilter->Update();
178  Image::Pointer distanceImage = m_InterpolateSurfaceFilter->GetOutput();
179  if (distanceImage.IsNull())
180  {
181  // If no interpolation is possible reset the interpolation result
182  m_InterpolationResult = nullptr;
183  return;
184  }
185 
186  // create a surface from the distance-image
188  imageToSurfaceFilter->SetInput(distanceImage);
189  imageToSurfaceFilter->SetThreshold(0);
190  imageToSurfaceFilter->SetSmooth(true);
191  imageToSurfaceFilter->SetSmoothIteration(20);
192  imageToSurfaceFilter->Update();
193  m_InterpolationResult = imageToSurfaceFilter->GetOutput();
194 
195  m_InterpolationResult->DisconnectPipeline();
196 }
197 
199 {
200  return m_InterpolationResult;
201 }
202 
204 {
205  return m_Contours;
206 }
207 
209 {
210  m_MinSpacing = minSpacing;
211 }
212 
214 {
215  m_MaxSpacing = maxSpacing;
216 }
217 
219 {
220  m_DistanceImageVolume = value;
221 }
222 
224 {
225  m_WorkingImage = workingImage;
226 }
227 
229 {
230  return m_InterpolateSurfaceFilter->GetOutput();
231 }
232 
234 {
235  double numberOfPoints = 0.0;
236  for (unsigned int i = 0; i < m_MapOfContourLists[m_ActiveLabel].size(); i++)
237  {
238  numberOfPoints += m_MapOfContourLists[m_ActiveLabel].at(i).first->GetNumberOfVertices() * 3;
239  }
240 
241  double sizeOfPoints = pow(numberOfPoints, 2) * sizeof(double);
243  double percentage = sizeOfPoints / totalMem;
244  return percentage;
245 }
246 
248 {
249  if (m_ActiveLabel == activeLabel)
250  return;
251 
252  if (activeLabel == 0)
253  return;
254 
255  m_ActiveLabel = activeLabel;
256 
257  auto it = m_MapOfContourLists.find(m_ActiveLabel);
258 
259  if (it == m_MapOfContourLists.end())
260  {
261  ContourPositionPairList newList;
262  m_MapOfContourLists.insert(std::pair<unsigned int, ContourPositionPairList>(m_ActiveLabel, newList));
263  m_InterpolationResult = nullptr;
264  }
265 
266  this->Modified();
267 }
268 
269 /*
270 void mitk::SurfaceBasedInterpolationController::RemoveSegmentationFromContourList(mitk::Image *segmentation)
271 {
272  if (segmentation != 0)
273  {
274  m_MapOfContourLists.erase(segmentation);
275  if (m_SelectedSegmentation == segmentation)
276  {
277  SetSegmentationImage(nullptr);
278  m_SelectedSegmentation = 0;
279  }
280  }
281 }
282 */
283 
284 /*
285 void mitk::SurfaceBasedInterpolationController::OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject
286 &event)
287 {
288  mitk::Image* tempImage = dynamic_cast<mitk::Image*>(const_cast<itk::Object*>(caller));
289  if (tempImage)
290  {
291  RemoveSegmentationFromContourList(tempImage);
292  if (tempImage == m_SelectedSegmentation)
293  {
294  SetSegmentationImage(nullptr);
295  m_SelectedSegmentation = 0;
296  }
297  }
298 }
299 */
static vcl_size_t GetTotalSizeOfPhysicalRam()
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:28
static SurfaceBasedInterpolationController * GetInstance()
Constants for most interaction classes, due to the generic StateMachines.
void AddNewContour(ContourModel::Pointer newContour, RestorePlanePositionOperation *op)
Image class for storing images.
Definition: mitkImage.h:72
static Pointer New()