[vtkusers] PCA in VTK
Jonathan Bailleul
Jonathan.Bailleul at greyc.ismra.fr
Sun Aug 22 17:11:40 EDT 2004
#include "vtkPCAAnalysisFilter.h"
It is simple to use and features many things you might need...
It takes in input polydatas and can generate shape instances with
coefficients you provide, or estimate coefficients of an unknown
polydata.
(of course, polydata designate landmarked data).
Here is old code playing around with it (not reference code ok?), just
showing how to use some features...
So, you managed to implement the Frangi method, didn't you? ;)
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkPolyData.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkPolyDataNormals.h"
#include "vtkPCAAnalysisFilter.h"
#include "vtkProcrustesAlignmentFilter.h"
#include "vtkPolyDataReader.h"
#include "vtkPolyDataWriter.h"
#include "vtkLandmarkTransform.h"
#include "vtkPointSetToPointSetFilter.h"
#include "vtkDataSetWriter.h"
#include <assert.h>
/* GLOS (Graphic Library in Open Source), an ANSI Common Lisp OpenGL
subset.
Copyright (C) 2001 the GLOS development team
(http://glos.sourceforge.net) */
static void
usage(int argc, char **argv)
{
if (argc - 1 <= 2)
{
printf("Displays PCA mode of given already procrustes-aligned vtk
files\n");
printf("Usage: %s <mode number> <output instances number> <input
vtk landmark files> \n", argv[0]);
printf("\ncreate shape files deviated from mean shape along
selected mode. Instances number: e.g 1 means instances for phi = {-3.0,
0, -3.0}\n");
exit(1);
}
}
/* mode: index of mode from 0*/
void
CreateShapeInstance(vtkPCAAnalysisFilter *pca_filter, char* filename,
int mode, float variance_fact, vtkPointSet *shape_container)
{
vtkFloatArray *params = vtkFloatArray::New();
params -> SetNumberOfComponents(1); // 1 per tuple
params -> SetNumberOfTuples(1 + mode); // 1 instance
// float val[1]; val[0] = variance_fact; params -> SetTuple(0, val);
for (int i = 0; i < mode; i++) {params -> SetTuple1(i, 0.0);}
params -> SetTuple1(mode, variance_fact);
pca_filter -> GetParameterisedShape(params, shape_container);
vtkDataSetWriter *writer = vtkDataSetWriter::New();
writer -> SetFileName(filename);
writer -> SetInput(shape_container);
writer -> Update();
}
int
main( int argc, char *argv[] )
{
usage(argc, argv);
char* filename_in;
char* filename_out;
int i;
int inputs = argc - 3;
int mode_number = atoi(argv[1]);
int mode_instances = atoi(argv[2]); // shape instances in range ]0;
+-3]
//
----------------------------------------------------------------------
/* STEP 1: PCA computation */
//
----------------------------------------------------------------------
// allocate one reader per file since input pca filter source
// are read in parallel when filter is executed
vtkPolyDataReader **readers;
assert(readers = (vtkPolyDataReader**)calloc(inputs,
sizeof(vtkPolyDataReader*)));
for (i = 0; i < inputs; i++)
readers[i] = vtkPolyDataReader::New();
vtkPCAAnalysisFilter *pca = vtkPCAAnalysisFilter::New();
pca -> SetNumberOfInputs(inputs);
cout << "Inputfiles: " << inputs << endl;
// assign pca inputs with landmark file readers
for (i = 0; i < inputs; i++)
{
filename_in = argv[i + 3];
cout << "infile: " << filename_in << endl;
readers[i] -> SetFileName(filename_in);
readers[i] -> Update();
pca -> SetInput(i, readers[i] -> GetOutput());
}
// execute pca
pca -> Update();
pca -> PrintSelf(cout, 0);
//
----------------------------------------------------------------------
/* STEP 2 */
//
----------------------------------------------------------------------
// eigenmodes display
cout << endl << "eigenvalues:";
inputs = pca -> GetEvals() -> GetNumberOfTuples();
for (i = 0; i < inputs; i++)
cout << " " << pca -> GetEvals() -> GetValue(i);
cout << endl;
float fact_delta = 3.0 / mode_instances;
float fact;
char* outfile;
assert(outfile = (char *) calloc (150, sizeof(char)));
sprintf(outfile, "./file_out_meanshape.vtk");//, mode_number, 0.0);
CreateShapeInstance(pca, outfile, mode_number, 0.0, readers[0] ->
GetOutput());
for (i = 0, fact = fact_delta; i < mode_instances; i++, fact +=
fact_delta)
{
sprintf(outfile, "./file_out_mode_%d_varpos_%d.vtk", mode_number,
i);
CreateShapeInstance(pca, outfile, mode_number, fact, readers[0] ->
GetOutput());
}
for (i = 0, fact = -fact_delta; i < mode_instances; i++, fact -=
fact_delta)
{
sprintf(outfile, "./file_out_mode_%d_varneg_%d.vtk", mode_number,
i);
CreateShapeInstance(pca, outfile, mode_number, fact, readers[0] ->
GetOutput());
}
cout << endl;
return 0;
}
--
-----------------------------------
Jonathan BAILLEUL, Doctorant
GREYC Image - Université de Caen
http://www.greyc.ismra.fr/~bailleul
More information about the vtkusers
mailing list