[vtkusers] trouble with thin plate spline transform (please help!!)

Alia aks01 at doc.ic.ac.uk
Sun Aug 25 16:27:09 EDT 2002


Hello,

I was hoping someone could help me regarding thin plate spline
transforms (code follows the end of this mail)

I have two 3d models of a face, and a list of corresponding points on
each model.
I am trying to find the thin plate spline transform bewtween the two
models, then pass it to the first model,
to see if it will correctly produce the second model.

However when I do this, the effect is as though I had 'steamrollered'
the face - it becomes completely flattened, from the side on.

Using the source landmarks as both source and target data produces an
(unchanged) 3d image, so I dont know if its
my dataset or the way I'm applying the warp at fault.

Either way I think I've just misunderstood how to use the function.
(I'm following the ThinPlateSpline example from the kitware man pages)

If anyone has any suggestions as to where this is going wrong, I would
be extremely grateful.

Thanks!

Alia

//******************CODE*******************

//SOURCE LANDMARK POINTS
vtkPoints* Sp1 = vtkPoints::New();
Sp1-> SetNumberOfPoints(25);
//Sp1-> SetPoint( 0, 0, 0, 0);
Sp1-> SetPoint( 0, 178.552, 505.336, 0.587569);
Sp1-> SetPoint( 1, 178.552, 505.336, 0.587569);
Sp1-> SetPoint( 2, 219.822, 475.996, 0.346727);
Sp1-> SetPoint( 3, 215.346, 503.522, 0.529492);
Sp1-> SetPoint( 4, 210.153, 504.513, 0.671797);
Sp1-> SetPoint( 5, 222.091, 477.032, 0.856578);
Sp1-> SetPoint( 6, 233.848, 484.04, 0.388976);
Sp1-> SetPoint( 7, 233.78, 489.953, 0.429802);
Sp1-> SetPoint( 8, 229.159, 493.521, 0.449271);
Sp1-> SetPoint( 9, 229.134, 496.219, 0.46988);
Sp1-> SetPoint( 10, 233.536, 496.394, 0.511361);
Sp1-> SetPoint( 11, 228.196, 500.614, 0.693835);
Sp1-> SetPoint( 12, 228.065, 499.355, 0.714371);
Sp1-> SetPoint( 13, 223.389, 499.312, 0.734568);
Sp1-> SetPoint( 14, 227.619, 493.607, 0.775678);
Sp1-> SetPoint( 15, 231.807, 484.082, 0.816502);
Sp1-> SetPoint( 16, 247.343, 491.885, 0.491815);
Sp1-> SetPoint( 17, 246.295, 493.429, 0.715644);
Sp1-> SetPoint( 18, 270.413, 476.406, 0.514177);
Sp1-> SetPoint( 19, 274.666, 476.693, 0.596224);
Sp1-> SetPoint( 20, 274.247, 472.686, 0.697853);
Sp1-> SetPoint( 21, 300.117, 430.763, 0.519777);
Sp1-> SetPoint( 22, 304.981, 423.321, 0.579194);
Sp1-> SetPoint( 23, 304.981, 423.321, 0.579194);
Sp1-> SetPoint( 24, 304.828, 415.138, 0.678476);

//TEST, SOURCE POINTS AGAIN, USED FOR TARGET POINTS
//(GIVES UNWARPED 3D IMAGE)
vtkPoints* Tp1 = vtkPoints::New();
Tp1-> SetNumberOfPoints(25);
//Tp1-> SetPoint( 0, 0, 0, 0);
Tp1-> SetPoint( 0, 178.552, 505.336, 0.587569);
Tp1-> SetPoint( 1, 178.552, 505.336, 0.587569);
Tp1-> SetPoint( 2, 219.822, 475.996, 0.346727);
Tp1-> SetPoint( 3, 215.346, 503.522, 0.529492);
Tp1-> SetPoint( 4, 210.153, 504.513, 0.671797);
Tp1-> SetPoint( 5, 222.091, 477.032, 0.856578);
Tp1-> SetPoint( 6, 233.848, 484.04, 0.388976);
Tp1-> SetPoint( 7, 233.78, 489.953, 0.429802);
Tp1-> SetPoint( 8, 229.159, 493.521, 0.449271);
Tp1-> SetPoint( 9, 229.134, 496.219, 0.46988);
Tp1-> SetPoint( 10, 233.536, 496.394, 0.511361);
Tp1-> SetPoint( 11, 228.196, 500.614, 0.693835);
Tp1-> SetPoint( 12, 228.065, 499.355, 0.714371);
Tp1-> SetPoint( 13, 223.389, 499.312, 0.734568);
Tp1-> SetPoint( 14, 227.619, 493.607, 0.775678);
Tp1-> SetPoint( 15, 231.807, 484.082, 0.816502);
Tp1-> SetPoint( 16, 247.343, 491.885, 0.491815);
Tp1-> SetPoint( 17, 246.295, 493.429, 0.715644);
Tp1-> SetPoint( 18, 270.413, 476.406, 0.514177);
Tp1-> SetPoint( 19, 274.666, 476.693, 0.596224);
Tp1-> SetPoint( 20, 274.247, 472.686, 0.697853);
Tp1-> SetPoint( 21, 300.117, 430.763, 0.519777);
Tp1-> SetPoint( 22, 304.981, 423.321, 0.579194);
Tp1-> SetPoint( 23, 304.981, 423.321, 0.579194);
Tp1-> SetPoint( 24, 304.828, 415.138, 0.678476);


//CORRESPONDING TARGET LANDMARK POINTS
//(PRODUCE FLATTENED IMAGE)
vtkPoints* Tp2 = vtkPoints::New();
Tp2-> SetNumberOfPoints(25);
//Tp2-> SetPoint( 0, 0, 0, 0);
Tp2-> SetPoint( 0, 178.501, 504.663, 0.587356);
Tp2-> SetPoint( 1, 178.501, 504.663, 0.587356);
Tp2-> SetPoint( 2, 219.813, 475.771, 0.346861);
Tp2-> SetPoint( 3, 215.402, 502.522, 0.509251);
Tp2-> SetPoint( 4, 210.17, 504.878, 0.672354);
Tp2-> SetPoint( 5, 222.078, 476.633, 0.856691);
Tp2-> SetPoint( 6, 238.372, 488.552, 0.430278);
Tp2-> SetPoint( 7, 233.85, 484.143, 0.389087);
Tp2-> SetPoint( 8, 233.82, 487.281, 0.409283);
Tp2-> SetPoint( 9, 238.178, 494.076, 0.491318);
Tp2-> SetPoint( 10, 233.535, 496.318, 0.51113);
Tp2-> SetPoint( 11, 232.47, 496.046, 0.735303);
Tp2-> SetPoint( 12, 228.3, 500.881, 0.673786);
Tp2-> SetPoint( 13, 232.315, 493.501, 0.755316);
Tp2-> SetPoint( 14, 223.208, 496.647, 0.754803);
Tp2-> SetPoint( 15, 231.815, 484.444, 0.816477);
Tp2-> SetPoint( 16, 238.252, 492.808, 0.471113);
Tp2-> SetPoint( 17, 246.172, 490.505, 0.736029);
Tp2-> SetPoint( 18, 270.415, 476.298, 0.514539);
Tp2-> SetPoint( 19, 274.676, 476.138, 0.596509);
Tp2-> SetPoint( 20, 283.955, 450.626, 0.739343);
Tp2-> SetPoint( 21, 300.575, 423.86, 0.484908);
Tp2-> SetPoint( 22, 304.743, 426.315, 0.599277);
Tp2-> SetPoint( 23, 304.743, 426.315, 0.599277);
Tp2-> SetPoint( 24, 294.645, 414.154, 0.759259);

	//have reader read in source obj file
	vtkOBJReader *reader1 = vtkOBJReader::New();
	reader1->SetFileName("DATA/0001_SURFACE123.OBJ");

	string inputTEXnameSOURCE = "DATA/0001_SURFACE123.BMP";

	vtkBMPReader *readerBmp1 = vtkBMPReader::New();
	readerBmp1->SetFileName(inputTEXnameSOURCE.c_str());
  	vtkTexture *atext1 = vtkTexture::New();
	atext1->SetInput(readerBmp1->GetOutput());
	atext1->InterpolateOn();

	std::cout <<"Performing Thin Plate Spline Transform" << endl;

	vtkThinPlateSplineTransform* tpst =
vtkThinPlateSplineTransform::New();
	//tpst->Modified();
	tpst->SetSourceLandmarks(Sp1);
//	tpst->SetTargetLandmarks(Tp1);	TEST uncomment this to test with
same source & target points
	tpst->SetTargetLandmarks(Tp2);
	tpst->SetBasisToR();
	//tpst->Update();

	std::cout <<"Warp complete" << endl;

	//IF YOU WANT TO DO INVERSE!!!
	vtkGeneralTransform* tpstconcat = vtkGeneralTransform::New();
    tpstconcat->SetInput(tpst);
    tpstconcat->Concatenate(tpst->GetInverse());
    tpstconcat->Concatenate(tpst);

	vtkTransformPolyDataFilter* warp =
vtkTransformPolyDataFilter::New();
	warp->SetInput(reader1->GetOutput());
    warp->SetTransform(tpstconcat);


	vtkPolyDataMapper* mapper =	vtkPolyDataMapper::New();
    mapper->SetInput(warp->GetOutput());


	vtkActor* actor = vtkActor::New();
	//	actor->SetUserTransform(A LINER TRANSFORM);
    actor->SetMapper(mapper);
	actor->SetTexture(atext1);
	actor->GetProperty()->SetOpacity(1);
	actor->GetProperty()->SetInterpolationToGouraud();
	actor->GetProperty()->SetColor (215, 215, 237);
	actor->GetProperty()->SetRepresentationToWireframe();


	// create a rendering window and renderer
	vtkRenderer *ren = vtkRenderer::New();
	vtkRenderWindow *renWindow = vtkRenderWindow::New();
	renWindow->AddRenderer(ren);
	vtkRenderWindowInteractor *RWInteractor =
vtkRenderWindowInteractor::New();
	RWInteractor->SetRenderWindow(renWindow);
	ren->AddActor(actor);
	ren->SetBackground(0,0,0);
	renWindow->SetSize(400, 400);
	renWindow->Render();
	RWInteractor->Start();
	std::cout << "You can use the mouse to interact with the
surface" << endl;



---------------------------------------------------------
To lift an autumn hair is no sign of great strength;
To see the sun and moon is no sign of sharp sight;
To hear the noise of thunder is no sign of a quick ear.
-Sun Tzu on The Art Of War
---------------------------------------------------------





More information about the vtkusers mailing list