21 #include <vtkCellLinks.h>
23 #include <vtkPointData.h>
24 #include <vtkPolyDataNormals.h>
25 #include <vtkSmartPointer.h>
32 itk::Matrix<double, 3, 3> &mat,
34 std::vector<mitk::Point3D> &pointList,
35 vtkPolyData *polyData);
39 double normalizationValue);
43 struct CovarianceMatrixCalculatorData
45 vtkPolyDataNormals *m_PolyDataNormals;
46 vtkPolyData *m_PolyData;
48 double m_VoronoiScalingFactor;
49 bool m_EnableNormalization;
50 double m_MeanVariance;
52 CovarianceMatrixCalculatorData()
53 : m_PolyDataNormals(vtkPolyDataNormals::
New()),
56 m_VoronoiScalingFactor(1.0),
57 m_EnableNormalization(false),
60 m_PolyDataNormals->SplittingOff();
63 ~CovarianceMatrixCalculatorData()
65 if (m_PolyDataNormals)
66 m_PolyDataNormals->Delete();
82 d->m_VoronoiScalingFactor = factor;
87 d->m_EnableNormalization = state;
92 return d->m_MeanVariance;
98 return m_CovarianceMatrixList;
108 double normalizationValue = -1.0;
109 vtkDataArray *normals =
nullptr;
110 d->m_MeanVariance = 0.0;
113 mitkThrow() <<
"No input surface was set in mitk::CovarianceMatrixCalculator";
115 d->m_PolyData = d->m_Input->GetVtkPolyData();
123 d->m_PolyDataNormals->SetInputData(d->m_PolyData);
124 d->m_PolyDataNormals->Update();
125 normals = d->m_PolyDataNormals->GetOutput()->GetPointData()->GetNormals();
128 if (d->m_EnableNormalization)
129 normalizationValue = 1.5;
132 m_CovarianceMatrixList.clear();
134 if (d->m_PolyData->GetNumberOfPoints() > (vtkIdType)m_CovarianceMatrixList.capacity())
135 m_CovarianceMatrixList.reserve(d->m_PolyData->GetNumberOfPoints());
137 for (vtkIdType i = 0; i < d->m_PolyData->GetNumberOfPoints(); ++i)
140 Vertex currentVertex;
141 Vertex variances = {0.0, 0.0, 0.0};
145 normals->GetTuple(i, normal);
146 d->m_PolyData->GetPoint(i, currentVertex);
148 ComputeOrthonormalCoordinateSystem(i, normal, mat, variances, currentVertex);
151 variances[0] = (d->m_VoronoiScalingFactor * variances[0]);
152 variances[1] = (d->m_VoronoiScalingFactor * variances[1]);
153 variances[2] = (d->m_VoronoiScalingFactor * variances[2]);
155 d->m_MeanVariance += (variances[0] + variances[1] + variances[2]);
158 m_CovarianceMatrixList.push_back(covarianceMatrix);
161 if (d->m_EnableNormalization)
162 d->m_MeanVariance = normalizationValue / 3.0;
164 d->m_MeanVariance /= (3.0 * (double)d->m_PolyData->GetNumberOfPoints());
167 d->m_PolyData =
nullptr;
168 d->m_Input =
nullptr;
177 polydata->GetPointCells(index, cellIds);
179 for (vtkIdType j = 0; j < cellIds->GetNumberOfIds(); j++)
181 vtkIdList *newPoints = polydata->GetCell(cellIds->GetId(j))->GetPointIds();
182 for (vtkIdType k = 0; k < newPoints->GetNumberOfIds(); k++)
185 if (result->IsId(newPoints->GetId(k)) == -1)
187 result->InsertNextId(newPoints->GetId(k));
199 itk::Matrix<double, 3, 3> &mat,
201 std::vector<mitk::Point3D> &pointList,
202 vtkPolyData *polyData)
204 typedef std::vector<mitk::Point3D>
VectorType;
205 typedef VectorType::const_iterator ConstPointIterator;
206 typedef double Vertex[3];
208 Vertex mean = {0.0, 0.0, 0.0};
209 Vertex tmp = {0.0, 0.0, 0.0};
211 const vtkIdType size = neighbourPoints->GetNumberOfIds();
214 pointList.reserve(size);
218 for (vtkIdType i = 0; i < size; ++i)
223 polyData->GetPoint((neighbourPoints->GetId(i)), tmp);
225 vtkPlane::GeneralizedProjectPoint(tmp, curVertex, normal, resultPoint);
227 p[0] = resultPoint[0];
228 p[1] = resultPoint[1];
229 p[2] = resultPoint[2];
235 pointList.push_back(p);
238 mean[0] /= (double)size;
239 mean[1] /= (double)size;
240 mean[2] /= (double)size;
243 for (ConstPointIterator it = pointList.begin(); it != pointList.end(); ++it)
245 tmp[0] = ((*it)[0] - mean[0]);
246 tmp[1] = ((*it)[1] - mean[1]);
247 tmp[2] = ((*it)[2] - mean[2]);
250 mat[0][0] += tmp[0] * tmp[0];
251 mat[1][1] += tmp[1] * tmp[1];
252 mat[2][2] += tmp[2] * tmp[2];
255 mat[1][0] += tmp[0] * tmp[1];
256 mat[2][0] += tmp[0] * tmp[2];
257 mat[2][1] += tmp[1] * tmp[2];
262 mat[0][1] = mat[1][0];
263 mat[0][2] = mat[2][0];
264 mat[1][2] = mat[2][1];
269 vnl_svd<double> svd(mat.GetVnlMatrix());
271 for (
int i = 0; i < 3; ++i)
272 for (
int j = 0; j < 3; ++j)
273 mat[i][j] = svd.U()[j][i];
275 return neighbourPoints;
280 const int index, Vertex normal,
CovarianceMatrix &axes, Vertex variances, Vertex curVertex)
282 typedef std::vector<mitk::Point3D>
VectorType;
283 typedef VectorType::const_iterator ConstPointIterator;
284 VectorType projectedPoints;
286 Vertex meanValues = {0.0, 0.0, 0.0};
288 vtkIdList *neighbourPoints =
292 axes[2][0] = normal[0];
293 axes[2][1] = normal[1];
294 axes[2][2] = normal[2];
296 for (vtkIdType i = 0; i < neighbourPoints->GetNumberOfIds(); ++i)
300 d->m_PolyData->GetPoint(neighbourPoints->GetId(i), curNeighbour);
302 curNeighbour[0] = curNeighbour[0] - curVertex[0];
303 curNeighbour[1] = curNeighbour[1] - curVertex[1];
304 curNeighbour[2] = curNeighbour[2] - curVertex[2];
306 for (
int k = 0; k < 3; ++k)
308 projectedPoint[k] = axes[k][0] * curNeighbour[0] + axes[k][1] * curNeighbour[1] + axes[k][2] * curNeighbour[2];
310 meanValues[k] += projectedPoint[k];
313 projectedPoints[i] = projectedPoint;
316 meanValues[0] /= (double)projectedPoints.size();
317 meanValues[1] /= (double)projectedPoints.size();
318 meanValues[2] /= (double)projectedPoints.size();
321 for (ConstPointIterator it = projectedPoints.begin(); it != projectedPoints.end(); ++it)
325 variances[0] += (p[0] - meanValues[0]) * (p[0] - meanValues[0]);
326 variances[1] += (p[1] - meanValues[1]) * (p[1] - meanValues[1]);
327 variances[2] += (p[2] - meanValues[2]) * (p[2] - meanValues[2]);
330 variances[0] /= (double)(projectedPoints.size() - 1);
331 variances[1] /= (double)(projectedPoints.size() - 1);
332 variances[2] /= (double)(projectedPoints.size() - 1);
335 neighbourPoints->Delete();
342 double normalizationValue)
344 unsigned int idxMax, idxMin, idxBetween;
345 itk::Matrix<double, 3, 3> returnValue;
346 itk::Matrix<double, 3, 3> V;
347 itk::Matrix<double, 3, 3> diagMatrix;
348 diagMatrix.Fill(0.0);
350 if (sigma[0] >= sigma[1] && sigma[0] >= sigma[2])
353 if (sigma[1] >= sigma[2])
364 else if (sigma[1] >= sigma[0] && sigma[1] >= sigma[2])
367 if (sigma[0] >= sigma[2])
381 if (sigma[0] >= sigma[1])
393 V[0][0] = axes[idxMax][0];
394 V[1][0] = axes[idxMax][1];
395 V[2][0] = axes[idxMax][2];
396 V[0][1] = axes[idxBetween][0];
397 V[1][1] = axes[idxBetween][1];
398 V[2][1] = axes[idxBetween][2];
399 V[0][2] = axes[idxMin][0];
400 V[1][2] = axes[idxMin][1];
401 V[2][2] = axes[idxMin][2];
403 diagMatrix[0][0] = sigma[idxMax];
404 diagMatrix[1][1] = sigma[idxBetween];
405 diagMatrix[2][2] = sigma[idxMin];
407 returnValue = V * diagMatrix * V.GetTranspose();
409 if (normalizationValue > 0.0)
411 double trace = returnValue[0][0] + returnValue[1][1] + returnValue[2][2];
412 returnValue *= (normalizationValue / trace);
Class for storing surfaces (vtkPolyData).
std::vector< CovarianceMatrix > CovarianceMatrixList
void EnableNormalization(bool state)
DataCollection - Class to facilitate loading/accessing structured data.
double GetMeanVariance() const
void SetVoronoiScalingFator(const double factor)
const CovarianceMatrixList & GetCovarianceMatrices() const
itk::Vector< float, 3 > VectorType
~CovarianceMatrixCalculator()
static vtkIdList * CalculatePCAonPointNeighboursForNormalVector(int index, double normal[3], itk::Matrix< double, 3, 3 > &mat, double curVertex[3], std::vector< mitk::Point3D > &pointList, vtkPolyData *polyData)
void SetInputSurface(Surface *input)
static vtkIdList * GetNeighboursOfPoint(unsigned int index, vtkPolyData *polydata)
void ComputeOrthonormalCoordinateSystem(const int index, Vertex normal, CovarianceMatrix &principalComponents, Vertex variances, Vertex curVertex)
itk::Matrix< double, 3, 3 > CovarianceMatrix
static itk::Matrix< double, 3, 3 > ComputeCovarianceMatrix(itk::Matrix< double, 3, 3 > &axes, double sigma[3], double normalizationValue)
CovarianceMatrixCalculator()
void ComputeCovarianceMatrices()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.