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

Tim Hutton T.Hutton at eastman.ucl.ac.uk
Tue Aug 27 05:30:23 EDT 2002


Hi Alia,

25 landmarks is quite a lot for warping a face, since there aren't that 
many good places to put them. If you use too many then the transform can 
crumple up. Make sure that the landmarks are placed correctly on the faces, 
and that their indices correspond. The code looks fine (assuming you 
actually do warp->SetTransform(tpst); ). Try with fewer landmarks to start 
with? (Eg. 9)

Hope this helps,

Tim.

At 21:27 25/08/2002 +0100, Alia wrote:

>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
>---------------------------------------------------------
>
>
>_______________________________________________
>This is the private VTK discussion list.
>Please keep messages on-topic. Check the FAQ at: 
><http://public.kitware.com/cgi-bin/vtkfaq>
>Follow this link to subscribe/unsubscribe:
>http://public.kitware.com/mailman/listinfo/vtkusers





More information about the vtkusers mailing list