Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkPointCloudScoringFilter.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 
19 #include <math.h>
20 
21 #include <vtkDoubleArray.h>
22 #include <vtkKdTree.h>
23 #include <vtkPointData.h>
24 #include <vtkPoints.h>
25 #include <vtkPolyVertex.h>
26 #include <vtkSmartPointer.h>
27 #include <vtkUnstructuredGrid.h>
28 
30 {
31  this->SetNumberOfIndexedOutputs(1);
32 }
33 
35 {
36 }
37 
39 {
40  if (UnstructuredGridToUnstructuredGridFilter::GetNumberOfInputs() != 2)
41  {
42  MITK_ERROR << "Not enough input arguments for PointCloudScoringFilter" << std::endl;
43  return;
44  }
45 
46  DataObjectPointerArray inputs = UnstructuredGridToUnstructuredGridFilter::GetInputs();
47  mitk::UnstructuredGrid::Pointer edgeGrid = dynamic_cast<mitk::UnstructuredGrid *>(inputs.at(0).GetPointer());
48  mitk::UnstructuredGrid::Pointer segmGrid = dynamic_cast<mitk::UnstructuredGrid *>(inputs.at(1).GetPointer());
49 
50  if (edgeGrid->IsEmpty() || segmGrid->IsEmpty())
51  {
52  if (edgeGrid->IsEmpty())
53  MITK_ERROR << "edgeGrid is empty" << std::endl;
54  if (segmGrid->IsEmpty())
55  MITK_ERROR << "segmGrid is empty" << std::endl;
56  }
57 
58  if (m_FilteredScores.size() > 0)
59  m_FilteredScores.clear();
60 
61  vtkSmartPointer<vtkUnstructuredGrid> edgevtkGrid = edgeGrid->GetVtkUnstructuredGrid();
62  vtkSmartPointer<vtkUnstructuredGrid> segmvtkGrid = segmGrid->GetVtkUnstructuredGrid();
63 
64  // KdTree from here
65  vtkSmartPointer<vtkPoints> kdPoints = vtkSmartPointer<vtkPoints>::New();
66  vtkSmartPointer<vtkKdTree> kdTree = vtkSmartPointer<vtkKdTree>::New();
67 
68  for (int i = 0; i < edgevtkGrid->GetNumberOfPoints(); i++)
69  {
70  kdPoints->InsertNextPoint(edgevtkGrid->GetPoint(i));
71  }
72 
73  kdTree->BuildLocatorFromPoints(kdPoints);
74  // KdTree until here
75 
76  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
77 
78  for (int i = 0; i < segmvtkGrid->GetNumberOfPoints(); i++)
79  {
80  points->InsertNextPoint(segmvtkGrid->GetPoint(i));
81  }
82 
83  std::vector<ScorePair> score;
84  std::vector<double> distances;
85 
86  double dist_glob = 0.0;
87  double dist = 0.0;
88 
89  for (int i = 0; i < points->GetNumberOfPoints(); i++)
90  {
91  double point[3];
92  points->GetPoint(i, point);
93  kdTree->FindClosestPoint(point[0], point[1], point[2], dist);
94  dist_glob += dist;
95  distances.push_back(dist);
96  score.push_back(std::make_pair(i, dist));
97  }
98 
99  double avg = dist_glob / points->GetNumberOfPoints();
100 
101  double tmpVar = 0.0;
102  double highest = 0.0;
103 
104  for (unsigned int i = 0; i < distances.size(); i++)
105  {
106  tmpVar = tmpVar + ((distances.at(i) - avg) * (distances.at(i) - avg));
107  if (distances.at(i) > highest)
108  highest = distances.at(i);
109  }
110 
111  // CUBIC MEAN
112  double cubicAll = 0.0;
113  for (unsigned i = 0; i < score.size(); i++)
114  {
115  cubicAll = cubicAll + score.at(i).second * score.at(i).second * score.at(i).second;
116  }
117  double root2 = cubicAll / static_cast<double>(score.size());
118  double cubic = pow(root2, 1.0 / 3.0);
119  // CUBIC END
120 
121  double metricValue = cubic;
122 
123  for (unsigned int i = 0; i < score.size(); i++)
124  {
125  if (score.at(i).second > metricValue)
126  {
127  m_FilteredScores.push_back(std::make_pair(score.at(i).first, score.at(i).second));
128  }
129  }
130 
131  m_NumberOfOutpPoints = m_FilteredScores.size();
132 
133  vtkSmartPointer<vtkPoints> filteredPoints = vtkSmartPointer<vtkPoints>::New();
134 
135  // storing the distances in the uGrid PointData
136  vtkSmartPointer<vtkDoubleArray> pointDataDistances = vtkSmartPointer<vtkDoubleArray>::New();
137  pointDataDistances->SetNumberOfComponents(1);
138  pointDataDistances->SetNumberOfTuples(m_FilteredScores.size());
139  pointDataDistances->SetName("Distances");
140 
141  for (unsigned int i = 0; i < m_FilteredScores.size(); i++)
142  {
143  mitk::Point3D point;
144  point = segmvtkGrid->GetPoint(m_FilteredScores.at(i).first);
145  filteredPoints->InsertNextPoint(point[0], point[1], point[2]);
146  if (score.at(i).second > 0.001)
147  {
148  double dist[1] = {score.at(i).second};
149  pointDataDistances->InsertTuple(i, dist);
150  }
151  else
152  {
153  double dist[1] = {0.0};
154  pointDataDistances->InsertTuple(i, dist);
155  }
156  }
157 
158  unsigned int numPoints = filteredPoints->GetNumberOfPoints();
159 
160  vtkSmartPointer<vtkPolyVertex> verts = vtkSmartPointer<vtkPolyVertex>::New();
161 
162  verts->GetPointIds()->SetNumberOfIds(numPoints);
163  for (unsigned int i = 0; i < numPoints; i++)
164  {
165  verts->GetPointIds()->SetId(i, i);
166  }
167 
168  vtkSmartPointer<vtkUnstructuredGrid> uGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
169  uGrid->Allocate(1);
170 
171  uGrid->InsertNextCell(verts->GetCellType(), verts->GetPointIds());
172  uGrid->SetPoints(filteredPoints);
173  uGrid->GetPointData()->AddArray(pointDataDistances);
174 
176  outputGrid->SetVtkUnstructuredGrid(uGrid);
177  this->SetNthOutput(0, outputGrid);
178 
179  score.clear();
180  distances.clear();
181 }
182 
184 {
185  Superclass::GenerateOutputInformation();
186 }
#define MITK_ERROR
Definition: mitkLogMacros.h:24
static Pointer New()
virtual void GenerateOutputInformation() override
Class for storing unstructured grids (vtkUnstructuredGrid)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.