[vtkusers] [vtkusers]: Please Help: Problem to display 2D image in volume using vtkActor/vtkPlaneSource

Thomas - Kuiran Chen chent at cs.queensu.ca
Thu May 20 22:50:37 EDT 2004


Hi Lisa,

Need your kind advice again, :-).

I am having a problem to properly translate, rotate, scale and finally display a 2D image in a 3D volume.

1.  The 3D volume is properly volume rendered; the volume was placed in a world coordinating system
2.  The transform matrix (homogeneous 4x4) that transfer a 2D image into the same world coordinating system is verified to be accurate.
- the matrix contains scaling, translation and rotation all together.

Now I used vtkPlaneSource to generate a plane, then used vtkTexture to map the image onto this plane, then a vtkActor was used, with the above transform matrix, to place the 2D plane into the same coordinating system with the volume.

The problem I am facing is: the image has the same scaling factor as that of the volume which is set to be 0.0001 (in units of meters/pixel), but:
- if I set the proper scale (0.0001) using vtkActor::SetScale, the 2D plane is completely invisible inside the volume (later I found out that it was too small to be seen); this is wierd because the volume has the same  scaling range as that of the image.
- if I set a wrong scale as (0.01, 0.01, 0.01), the plane is visible now, but still way too small comparable to the volume;
- if I don't set the scale in vtkActor, then the plane is way bigger than the volume itself.
- the center also does't seem to be aligned right.

The volume was properly rendered from vtkStructuredPoints with a spacing set to be (0.0001, 0.0001, 0.0001).

Did I do something wrong?  The following is the piece of code that does the job:

//=====================================================
// Set the homogeneous 4x4 matrix of the slice transform
	vtkMatrix4x4* SliceTransformMatrix = vtkMatrix4x4::New();

	// All the units are set in meters
	SliceTransformMatrix->SetElement(0, 0, -0.33658448304182);
	SliceTransformMatrix->SetElement(0, 1, -0.85428086875344);
	SliceTransformMatrix->SetElement(0, 2, 0);
	SliceTransformMatrix->SetElement(0, 3, 0.24762597798394);

	SliceTransformMatrix->SetElement(1, 0, 0.86780991318033);
	SliceTransformMatrix->SetElement(1, 1, -0.06357157476514);
	SliceTransformMatrix->SetElement(1, 2, 0);
	SliceTransformMatrix->SetElement(1, 3, -0.02272676782324);
	
	SliceTransformMatrix->SetElement(2, 0, -0.36553696548425);
	SliceTransformMatrix->SetElement(2, 1, 0.50824159678083);
	SliceTransformMatrix->SetElement(2, 2, 0);
	SliceTransformMatrix->SetElement(2, 3, -1.27555842452333);
	
	SliceTransformMatrix->SetElement(3, 0, 0);
	SliceTransformMatrix->SetElement(3, 1, 0);
	SliceTransformMatrix->SetElement(3, 2, 0);
	SliceTransformMatrix->SetElement(3, 3, 1);

	// Set the homogeneous 4x4 matrix of the slice transform
	vtkMatrix4x4* volumeTransformMatrix = vtkMatrix4x4::New();

	// All the units are set in meters
	volumeTransformMatrix->SetElement(0, 0, 0.12393857010624);
	volumeTransformMatrix->SetElement(0, 1, -0.89668632477451);
	volumeTransformMatrix->SetElement(0, 2, 0.42496196614649);
	volumeTransformMatrix->SetElement(0, 3, 0.24034029575288);

	volumeTransformMatrix->SetElement(1, 0, 0.88705516603304);
	volumeTransformMatrix->SetElement(1, 1, 0.29205555735201);
	volumeTransformMatrix->SetElement(1, 2, 0.35754229218735);
	volumeTransformMatrix->SetElement(1, 3, -0.05566772631269);
	
	volumeTransformMatrix->SetElement(2, 0, -0.44471583075352);
	volumeTransformMatrix->SetElement(2, 1, 0.33265145911430);
	volumeTransformMatrix->SetElement(2, 2, 0.83160726517691);
	volumeTransformMatrix->SetElement(2, 3, -1.28352898977230);
	
	volumeTransformMatrix->SetElement(3, 0, 0);
	volumeTransformMatrix->SetElement(3, 1, 0);
	volumeTransformMatrix->SetElement(3, 2, 0);
	volumeTransformMatrix->SetElement(3, 3, 1);
	
	vtkTransform *sliceTransform = vtkTransform::New();
	sliceTransform->SetMatrix( SliceTransformMatrix );

	double ScaleXInMetersPerPixel = 0.00010302850136;
	double ScaleYInMetersPerPixel = 0.00009794833775;

	// Graphical Pipeline
	
	// Live US Image Reader
	vtkBMPReader *LiveUSImage = vtkBMPReader::New();
	LiveUSImage->SetFileName("../Test_Registration/Data/MatchedUSImageNO775_ROI.bmp");
	LiveUSImage->Update();

	// renderer
	vtkRenderer *aRenderer = vtkRenderer::New();
	vtkRenderWindow *renWin = vtkRenderWindow::New();
	renWin->AddRenderer(aRenderer);
	vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
	iren->SetRenderWindow(renWin);

	// Live US image actor
	vtkLookupTable *lutTexture = vtkLookupTable::New();
	lutTexture->SetTableRange(0, 255);	// set up a semi-transparent color lookup table
	lutTexture->SetHueRange(0, 0);
	lutTexture->SetSaturationRange(0, 0);
	lutTexture->SetValueRange(0, 1);
	lutTexture->SetAlphaRange(0.5, 1);
	lutTexture->Build();

	vtkTexture *texture = vtkTexture::New();
	texture->SetInput( LiveUSImage->GetOutput() );		// set up a texture from live image
	texture->SetLookupTable(lutTexture);			// use the lookup table above

	// Create a plane object
	vtkPlaneSource *plane = vtkPlaneSource::New();
	vtkPolyDataMapper *LiveUSImageMapper = vtkPolyDataMapper::New();
    LiveUSImageMapper->SetInput( plane->GetOutput() );

	vtkActor *LiveUSImagePlaneActor = vtkActor::New();
	LiveUSImagePlaneActor->SetMapper( LiveUSImageMapper );
	LiveUSImagePlaneActor->SetTexture(texture);				// map the texture onto the plane****
	LiveUSImagePlaneActor->SetScale(0.0001, 0.0001, 1);
	LiveUSImagePlaneActor->SetUserMatrix(SliceTransformMatrix);		

	// The following are for the volume rendering
	
	// Create volume
	vtkVolume *Volume = vtkVolume::New();
	Volume->SetProperty( VolumeProperty );
	Volume->SetMapper( RaycastMapper );
	Volume->SetUserMatrix( volumeTransformMatrix );

	aRenderer->AddActor( LiveUSImagePlaneActor );
	aRenderer->AddProp( Volume );

	// Camera setup
	vtkCamera *aCamera = vtkCamera::New();
	aCamera->SetViewUp (0, 0, -1);
	aCamera->SetPosition (0, 1, 0);
	aCamera->SetFocalPoint (0, 0, 0);
	aCamera->ComputeViewPlaneNormal();

	aRenderer->SetActiveCamera(aCamera);
	aRenderer->ResetCamera ();
	//aCamera->Dolly(1.5);

	// Background setup
	aRenderer->SetBackground(0,0,0);
	renWin->SetSize(800, 600);

	aRenderer->ResetCameraClippingRange ();

	// interact with data
	iren->Initialize();
	iren->Start(); 
//=====================================================

Thanks a lot,
Thomas




More information about the vtkusers mailing list