// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause /** * @class vtkPCAAnalysisFilter * @brief Performs principal component analysis of a set of aligned pointsets * * * vtkPCAAnalysisFilter is a filter that takes as input a set of aligned * pointsets (any object derived from vtkPointSet) and performs * a principal component analysis of the coordinates. * This can be used to visualise the major or minor modes of variation * seen in a set of similar biological objects with corresponding * landmarks. * vtkPCAAnalysisFilter is designed to work with the output from * the vtkProcrustesAnalysisFilter * vtkPCAAnalysisFilter requires a vtkMultiBlock input consisting * of vtkPointSets as first level children. * * vtkPCAAnalysisFilter is an implementation of (for example): * * T. Cootes et al. : Active Shape Models - their training and application. * Computer Vision and Image Understanding, 61(1):38-59, 1995. * * The material can also be found in Tim Cootes' ever-changing online report * published at his website: * http://www.isbe.man.ac.uk/~bim/ * * @warning * All of the input pointsets must have the same number of points. * * @par Thanks: * Rasmus Paulsen and Tim Hutton who developed and contributed this class * * @sa * vtkProcrustesAlignmentFilter */ #ifndef vtkPCAAnalysisFilter_h #define vtkPCAAnalysisFilter_h #include "vtkFiltersHybridModule.h" // For export macro #include "vtkMultiBlockDataSetAlgorithm.h" VTK_ABI_NAMESPACE_BEGIN class vtkFloatArray; class vtkPointSet; class VTKFILTERSHYBRID_EXPORT vtkPCAAnalysisFilter : public vtkMultiBlockDataSetAlgorithm { public: vtkTypeMacro(vtkPCAAnalysisFilter, vtkMultiBlockDataSetAlgorithm); /** * Prints information about the state of the filter. */ void PrintSelf(ostream& os, vtkIndent indent) override; /** * Creates with similarity transform. */ static vtkPCAAnalysisFilter* New(); ///@{ /** * Get the vector of eigenvalues sorted in descending order */ vtkGetObjectMacro(Evals, vtkFloatArray); ///@} /** * Fills the shape with: * mean + b[0] * sqrt(eigenvalue[0]) * eigenvector[0] * + b[1] * sqrt(eigenvalue[1]) * eigenvector[1] * ... * + b[sizeb-1] * sqrt(eigenvalue[bsize-1]) * eigenvector[bsize-1] * here b are the parameters expressed in standard deviations * bsize is the number of parameters in the b vector * This function assumes that shape is already allocated * with the right size, it just moves the points. */ void GetParameterisedShape(vtkFloatArray* b, vtkPointSet* shape); /** * Return the bsize parameters b that best model the given shape * (in standard deviations). * That is that the given shape will be approximated by: * shape ~ mean + b[0] * sqrt(eigenvalue[0]) * eigenvector[0] * + b[1] * sqrt(eigenvalue[1]) * eigenvector[1] * ... * + b[bsize-1] * sqrt(eigenvalue[bsize-1]) * eigenvector[bsize-1] */ void GetShapeParameters(vtkPointSet* shape, vtkFloatArray* b, int bsize); /** * Retrieve how many modes are necessary to model the given proportion of the variation. * proportion should be between 0 and 1 */ int GetModesRequiredFor(double proportion); protected: vtkPCAAnalysisFilter(); ~vtkPCAAnalysisFilter() override; /** * Usual data generation method. */ int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; private: vtkPCAAnalysisFilter(const vtkPCAAnalysisFilter&) = delete; void operator=(const vtkPCAAnalysisFilter&) = delete; // Eigenvalues vtkFloatArray* Evals; // Matrix where each column is an eigenvector double** evecMat2; // The mean shape in a vector double* meanshape; }; VTK_ABI_NAMESPACE_END #endif