17 #include <vtkCellLinks.h> 19 #include <vtkPointData.h> 20 #include <vtkPolyDataNormals.h> 21 #include <vtkSmartPointer.h> 28 itk::Matrix<double, 3, 3> &mat,
30 std::vector<mitk::Point3D> &pointList,
31 vtkPolyData *polyData);
35 double normalizationValue);
39 struct CovarianceMatrixCalculatorData
41 vtkPolyDataNormals *m_PolyDataNormals;
42 vtkPolyData *m_PolyData;
44 double m_VoronoiScalingFactor;
45 bool m_EnableNormalization;
46 double m_MeanVariance;
48 CovarianceMatrixCalculatorData()
49 : m_PolyDataNormals(vtkPolyDataNormals::New()),
52 m_VoronoiScalingFactor(1.0),
53 m_EnableNormalization(false),
56 m_PolyDataNormals->SplittingOff();
59 ~CovarianceMatrixCalculatorData()
61 if (m_PolyDataNormals)
62 m_PolyDataNormals->Delete();
78 d->m_VoronoiScalingFactor = factor;
83 d->m_EnableNormalization = state;
88 return d->m_MeanVariance;
104 double normalizationValue = -1.0;
105 vtkDataArray *normals =
nullptr;
106 d->m_MeanVariance = 0.0;
109 mitkThrow() <<
"No input surface was set in mitk::CovarianceMatrixCalculator";
111 d->m_PolyData = d->m_Input->GetVtkPolyData();
119 d->m_PolyDataNormals->SetInputData(d->m_PolyData);
120 d->m_PolyDataNormals->Update();
121 normals = d->m_PolyDataNormals->GetOutput()->GetPointData()->GetNormals();
124 if (d->m_EnableNormalization)
125 normalizationValue = 1.5;
133 for (vtkIdType i = 0; i < d->m_PolyData->GetNumberOfPoints(); ++i)
137 Vertex variances = {0.0, 0.0, 0.0};
141 normals->GetTuple(i, normal);
142 d->m_PolyData->GetPoint(i, currentVertex);
147 variances[0] = (d->m_VoronoiScalingFactor * variances[0]);
148 variances[1] = (d->m_VoronoiScalingFactor * variances[1]);
149 variances[2] = (d->m_VoronoiScalingFactor * variances[2]);
151 d->m_MeanVariance += (variances[0] + variances[1] + variances[2]);
157 if (d->m_EnableNormalization)
158 d->m_MeanVariance = normalizationValue / 3.0;
160 d->m_MeanVariance /= (3.0 * (double)d->m_PolyData->GetNumberOfPoints());
163 d->m_PolyData =
nullptr;
164 d->m_Input =
nullptr;
171 vtkIdList *cellIds = vtkIdList::New();
172 vtkIdList *result = vtkIdList::New();
173 polydata->GetPointCells(index, cellIds);
175 for (vtkIdType j = 0; j < cellIds->GetNumberOfIds(); j++)
177 vtkIdList *newPoints = polydata->GetCell(cellIds->GetId(j))->GetPointIds();
178 for (vtkIdType
k = 0;
k < newPoints->GetNumberOfIds();
k++)
181 if (result->IsId(newPoints->GetId(
k)) == -1)
183 result->InsertNextId(newPoints->GetId(
k));
195 itk::Matrix<double, 3, 3> &mat,
197 std::vector<mitk::Point3D> &pointList,
198 vtkPolyData *polyData)
200 typedef std::vector<mitk::Point3D> VectorType;
201 typedef VectorType::const_iterator ConstPointIterator;
204 Vertex mean = {0.0, 0.0, 0.0};
205 Vertex tmp = {0.0, 0.0, 0.0};
207 const vtkIdType size = neighbourPoints->GetNumberOfIds();
210 pointList.reserve(size);
214 for (vtkIdType i = 0; i < size; ++i)
219 polyData->GetPoint((neighbourPoints->GetId(i)), tmp);
221 vtkPlane::GeneralizedProjectPoint(tmp, curVertex, normal, resultPoint);
223 p[0] = resultPoint[0];
224 p[1] = resultPoint[1];
225 p[2] = resultPoint[2];
231 pointList.push_back(p);
234 mean[0] /= (double)size;
235 mean[1] /= (double)size;
236 mean[2] /= (double)size;
239 for (ConstPointIterator it = pointList.begin(); it != pointList.end(); ++it)
241 tmp[0] = ((*it)[0] - mean[0]);
242 tmp[1] = ((*it)[1] - mean[1]);
243 tmp[2] = ((*it)[2] - mean[2]);
246 mat[0][0] += tmp[0] * tmp[0];
247 mat[1][1] += tmp[1] * tmp[1];
248 mat[2][2] += tmp[2] * tmp[2];
251 mat[1][0] += tmp[0] * tmp[1];
252 mat[2][0] += tmp[0] * tmp[2];
253 mat[2][1] += tmp[1] * tmp[2];
258 mat[0][1] = mat[1][0];
259 mat[0][2] = mat[2][0];
260 mat[1][2] = mat[2][1];
265 vnl_svd<double> svd(mat.GetVnlMatrix());
267 for (
int i = 0; i < 3; ++i)
268 for (
int j = 0; j < 3; ++j)
269 mat[i][j] = svd.U()[j][i];
271 return neighbourPoints;
278 typedef std::vector<mitk::Point3D> VectorType;
279 typedef VectorType::const_iterator ConstPointIterator;
280 VectorType projectedPoints;
282 Vertex meanValues = {0.0, 0.0, 0.0};
284 vtkIdList *neighbourPoints =
288 axes[2][0] = normal[0];
289 axes[2][1] = normal[1];
290 axes[2][2] = normal[2];
292 for (vtkIdType i = 0; i < neighbourPoints->GetNumberOfIds(); ++i)
296 d->m_PolyData->GetPoint(neighbourPoints->GetId(i), curNeighbour);
298 curNeighbour[0] = curNeighbour[0] - curVertex[0];
299 curNeighbour[1] = curNeighbour[1] - curVertex[1];
300 curNeighbour[2] = curNeighbour[2] - curVertex[2];
302 for (
int k = 0;
k < 3; ++
k)
304 projectedPoint[
k] = axes[
k][0] * curNeighbour[0] + axes[
k][1] * curNeighbour[1] + axes[
k][2] * curNeighbour[2];
306 meanValues[
k] += projectedPoint[
k];
309 projectedPoints[i] = projectedPoint;
312 meanValues[0] /= (double)projectedPoints.size();
313 meanValues[1] /= (double)projectedPoints.size();
314 meanValues[2] /= (double)projectedPoints.size();
317 for (ConstPointIterator it = projectedPoints.begin(); it != projectedPoints.end(); ++it)
321 variances[0] += (p[0] - meanValues[0]) * (p[0] - meanValues[0]);
322 variances[1] += (p[1] - meanValues[1]) * (p[1] - meanValues[1]);
323 variances[2] += (p[2] - meanValues[2]) * (p[2] - meanValues[2]);
326 variances[0] /= (double)(projectedPoints.size() - 1);
327 variances[1] /= (double)(projectedPoints.size() - 1);
328 variances[2] /= (double)(projectedPoints.size() - 1);
331 neighbourPoints->Delete();
338 double normalizationValue)
340 unsigned int idxMax, idxMin, idxBetween;
341 itk::Matrix<double, 3, 3> returnValue;
342 itk::Matrix<double, 3, 3> V;
343 itk::Matrix<double, 3, 3> diagMatrix;
344 diagMatrix.Fill(0.0);
346 if (sigma[0] >= sigma[1] && sigma[0] >= sigma[2])
349 if (sigma[1] >= sigma[2])
360 else if (sigma[1] >= sigma[0] && sigma[1] >= sigma[2])
363 if (sigma[0] >= sigma[2])
377 if (sigma[0] >= sigma[1])
389 V[0][0] = axes[idxMax][0];
390 V[1][0] = axes[idxMax][1];
391 V[2][0] = axes[idxMax][2];
392 V[0][1] = axes[idxBetween][0];
393 V[1][1] = axes[idxBetween][1];
394 V[2][1] = axes[idxBetween][2];
395 V[0][2] = axes[idxMin][0];
396 V[1][2] = axes[idxMin][1];
397 V[2][2] = axes[idxMin][2];
399 diagMatrix[0][0] = sigma[idxMax];
400 diagMatrix[1][1] = sigma[idxBetween];
401 diagMatrix[2][2] = sigma[idxMin];
403 returnValue = V * diagMatrix * V.GetTranspose();
405 if (normalizationValue > 0.0)
407 double trace = returnValue[0][0] + returnValue[1][1] + returnValue[2][2];
408 returnValue *= (normalizationValue / trace);
Class for storing surfaces (vtkPolyData).
const CovarianceMatrixList & GetCovarianceMatrices() const
std::vector< CovarianceMatrix > CovarianceMatrixList
void EnableNormalization(bool state)
DataCollection - Class to facilitate loading/accessing structured data.
~CovarianceMatrixCalculator() override
CovarianceMatrixList m_CovarianceMatrixList
void SetVoronoiScalingFator(const double factor)
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)
double GetMeanVariance() const
CovarianceMatrixCalculator()
void ComputeCovarianceMatrices()