Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkUnstructuredGridClusteringFilter.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 <vector>
20 
21 #include <vtkDataArray.h>
22 #include <vtkDelaunay3D.h>
23 #include <vtkDoubleArray.h>
24 #include <vtkPointData.h>
25 #include <vtkPointLocator.h>
26 #include <vtkPoints.h>
27 #include <vtkPolyVertex.h>
28 #include <vtkSmartPointer.h>
29 #include <vtkUnstructuredGrid.h>
30 #include <vtkVariant.h>
31 
33  : m_eps(5.0), m_MinPts(4), m_Meshing(false), m_DistCalc(false)
34 {
35  this->m_UnstructGrid = mitk::UnstructuredGrid::New();
36 }
37 
39 {
40 }
41 
42 std::map<int, bool> visited;
43 std::map<int, bool> isNoise;
44 std::map<int, bool> clusterMember;
45 vtkSmartPointer<vtkPointLocator> pLocator;
46 std::vector<vtkSmartPointer<vtkPoints>> clusterVector;
47 
48 std::vector<std::vector<int>> clustersPointsIDs;
49 
51 {
52  m_UnstructGrid = this->GetOutput();
53 }
54 
56 {
57  mitk::UnstructuredGrid::Pointer inputGrid = const_cast<mitk::UnstructuredGrid *>(this->GetInput());
58  if (inputGrid.IsNull())
59  return;
60 
61  vtkSmartPointer<vtkUnstructuredGrid> vtkInpGrid = inputGrid->GetVtkUnstructuredGrid();
62  vtkSmartPointer<vtkPoints> inpPoints = vtkInpGrid->GetPoints();
64 
65  vtkSmartPointer<vtkDoubleArray> distances = vtkSmartPointer<vtkDoubleArray>::New();
66  if (inputGrid->GetVtkUnstructuredGrid()->GetPointData()->GetNumberOfArrays() > 0)
67  {
68  m_DistCalc = true;
69  distances = dynamic_cast<vtkDoubleArray *>(vtkInpGrid->GetPointData()->GetArray(0));
70  }
71 
72  pLocator->SetDataSet(vtkInpGrid);
73  pLocator->AutomaticOn();
74  pLocator->SetNumberOfPointsPerBucket(2);
75  pLocator->BuildLocator();
76 
77  // fill the visited map with false for checking
78  for (int i = 0; i < inpPoints->GetNumberOfPoints(); i++)
79  {
80  visited[i] = false;
81  isNoise[i] = false;
82  clusterMember[i] = false;
83  }
84 
85  for (int i = 0; i < inpPoints->GetNumberOfPoints(); i++)
86  {
87  if (!visited[i])
88  {
89  visited[i] = true; // mark P as visited
90  vtkSmartPointer<vtkIdList> idList = vtkSmartPointer<vtkIdList>::New(); // represent N
91  pLocator->FindPointsWithinRadius(m_eps, inpPoints->GetPoint(i), idList); // N = D.regionQuery(P, eps)
92  if (idList->GetNumberOfIds() < m_MinPts) // if sizeof(N) < MinPts
93  {
94  isNoise[i] = true; // mark P as NOISE
95  }
96  else
97  {
98  vtkSmartPointer<vtkPoints> cluster = vtkSmartPointer<vtkPoints>::New(); // represent a cluster
99  clusterVector.push_back(cluster); // C = next cluster
100  this->ExpandCluster(
101  i, idList, cluster, inpPoints); // expandCluster(P, N, C, eps, MinPts) mod. the parameter list
102  }
103  }
104  }
105 
106  // OUTPUT LOGIC
107  m_Clusters = clusterVector;
108  int numberOfClusterPoints = 0;
109  int IdOfBiggestCluster = 0;
110 
111  for (unsigned int i = 0; i < m_Clusters.size(); i++)
112  {
113  vtkSmartPointer<vtkDoubleArray> array = vtkSmartPointer<vtkDoubleArray>::New();
114  vtkSmartPointer<vtkPoints> points = m_Clusters.at(i);
115  if (m_DistCalc)
116  {
117  array->SetNumberOfComponents(1);
118  array->SetNumberOfTuples(points->GetNumberOfPoints());
119  for (int j = 0; j < points->GetNumberOfPoints(); j++)
120  {
121  double point[3];
122  points->GetPoint(j, point);
123  if (clustersPointsIDs.at(i).at(j) < inpPoints->GetNumberOfPoints())
124  {
125  if (distances->GetValue(clustersPointsIDs.at(i).at(j)) > 0.001)
126  {
127  double dist[1] = {distances->GetValue(clustersPointsIDs.at(i).at(j))};
128  array->SetTuple(j, dist);
129  }
130  else
131  {
132  double dist[1] = {0.0};
133  array->SetTuple(j, dist);
134  }
135  }
136  }
137  m_DistanceArrays.push_back(array);
138  }
139  if (points->GetNumberOfPoints() > numberOfClusterPoints)
140  {
141  numberOfClusterPoints = points->GetNumberOfPoints();
142  IdOfBiggestCluster = i;
143  }
144  }
145 
146  vtkSmartPointer<vtkUnstructuredGrid> biggestCluster = vtkSmartPointer<vtkUnstructuredGrid>::New();
147 
148  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
149  points = m_Clusters.at(IdOfBiggestCluster);
150 
151  vtkSmartPointer<vtkPolyVertex> verts = vtkSmartPointer<vtkPolyVertex>::New();
152  verts->GetPointIds()->SetNumberOfIds(m_Clusters.at(IdOfBiggestCluster)->GetNumberOfPoints());
153  for (int i = 0; i < m_Clusters.at(IdOfBiggestCluster)->GetNumberOfPoints(); i++)
154  {
155  verts->GetPointIds()->SetId(i, i);
156  }
157 
158  biggestCluster->Allocate(1);
159  biggestCluster->InsertNextCell(verts->GetCellType(), verts->GetPointIds());
160  biggestCluster->SetPoints(m_Clusters.at(IdOfBiggestCluster));
161 
162  if (m_Meshing)
163  {
164  vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
165  mesher->SetInputData(biggestCluster);
166  mesher->SetAlpha(0.9);
167  mesher->Update();
168 
169  vtkSmartPointer<vtkUnstructuredGrid> output = mesher->GetOutput();
170  m_UnstructGrid->SetVtkUnstructuredGrid(output);
171  }
172  else
173  {
174  m_UnstructGrid->SetVtkUnstructuredGrid(biggestCluster);
175  }
176 
177  clusterVector.clear();
178  clustersPointsIDs.clear();
179 }
180 
181 void mitk::UnstructuredGridClusteringFilter::ExpandCluster(int id,
182  vtkIdList *pointIDs,
183  vtkPoints *cluster,
184  vtkPoints *inpPoints)
185 {
186  std::vector<int> x;
187  x.push_back(id);
188  cluster->InsertNextPoint(inpPoints->GetPoint(id)); // add P to cluster C
189  clusterMember[id] = true;
190 
191  vtkSmartPointer<vtkPoints> neighbours = vtkSmartPointer<vtkPoints>::New(); // same N as in other function
192  inpPoints->GetPoints(pointIDs, neighbours);
193 
194  for (int i = 0; i < pointIDs->GetNumberOfIds(); i++) // for each point P' in N
195  {
196  if (!visited[pointIDs->GetId(i)]) // if P' is not visited
197  {
198  visited[pointIDs->GetId(i)] = true; // mark P' as visited
199  vtkSmartPointer<vtkIdList> idList = vtkSmartPointer<vtkIdList>::New(); // represent N'
200  pLocator->FindPointsWithinRadius(
201  m_eps, inpPoints->GetPoint(pointIDs->GetId(i)), idList); // N' = D.regionQuery(P', eps)
202 
203  if (idList->GetNumberOfIds() >= m_MinPts) // if sizeof(N') >= MinPts
204  {
205  for (int j = 0; j < idList->GetNumberOfIds(); j++) // N = N joined with N'
206  {
207  if (idList->GetId(j) < inpPoints->GetNumberOfPoints()) // a litte bit hacked ?!
208  {
209  pointIDs->InsertNextId(idList->GetId(j));
210  }
211  }
212  }
213  }
214  if (!clusterMember[pointIDs->GetId(i)]) // if P' is not yet member of any cluster
215  {
216  if (pointIDs->GetId(i) < inpPoints->GetNumberOfPoints())
217  {
218  clusterMember[pointIDs->GetId(i)] = true;
219  x.push_back(pointIDs->GetId(i));
220  cluster->InsertNextPoint(inpPoints->GetPoint(pointIDs->GetId(i))); // add P' to cluster C
221  }
222  }
223  }
224 
225  clustersPointsIDs.push_back(x);
226 }
227 
228 std::vector<mitk::UnstructuredGrid::Pointer> mitk::UnstructuredGridClusteringFilter::GetAllClusters()
229 {
230  std::vector<mitk::UnstructuredGrid::Pointer> mitkUGridVector;
231 
232  for (unsigned int i = 0; i < m_Clusters.size(); i++)
233  {
234  vtkSmartPointer<vtkUnstructuredGrid> cluster = vtkSmartPointer<vtkUnstructuredGrid>::New();
235 
236  vtkSmartPointer<vtkPoints> points = m_Clusters.at(i);
237 
238  vtkSmartPointer<vtkPolyVertex> verts = vtkSmartPointer<vtkPolyVertex>::New();
239 
240  verts->GetPointIds()->SetNumberOfIds(points->GetNumberOfPoints());
241  for (int j = 0; j < points->GetNumberOfPoints(); j++)
242  {
243  verts->GetPointIds()->SetId(j, j);
244  }
245 
246  cluster->Allocate(1);
247  cluster->InsertNextCell(verts->GetCellType(), verts->GetPointIds());
248  cluster->SetPoints(points);
249  if (m_DistCalc)
250  {
251  cluster->GetPointData()->AddArray(m_DistanceArrays.at(i));
252  }
253 
255 
256  if (m_Meshing)
257  {
258  vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
259  mesher->SetInputData(cluster);
260  mesher->SetAlpha(0.9);
261  mesher->Update();
262 
263  vtkSmartPointer<vtkUnstructuredGrid> output = mesher->GetOutput();
264  mitkGrid->SetVtkUnstructuredGrid(output);
265  }
266  else
267  {
268  mitkGrid->SetVtkUnstructuredGrid(cluster);
269  }
270 
271  mitkUGridVector.push_back(mitkGrid);
272  }
273 
274  return mitkUGridVector;
275 }
276 
278 {
279  return m_Clusters.size();
280 }
std::vector< std::vector< int > > clustersPointsIDs
std::map< int, bool > isNoise
std::map< int, bool > visited
static Pointer New()
std::vector< vtkSmartPointer< vtkPoints > > clusterVector
virtual std::vector< mitk::UnstructuredGrid::Pointer > GetAllClusters()
std::map< int, bool > clusterMember
vtkSmartPointer< vtkPointLocator > pLocator
Class for storing unstructured grids (vtkUnstructuredGrid)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.