[vtkusers] vtkWin32VideoSource shows no output when used in conjunction with vtkTextActor3D
Rhys Thomas
eep22f at bangor.ac.uk
Thu Jul 17 06:00:04 EDT 2008
Hello vtkusers,
I have been experiencing problems whilst using vtkTextActor3D. My
application should display an image from a vtkWin32VideoSource in the
background (from a webcam) with a combination of different
vizualisations on top. I use a combination of volume data (vtkVolume),
polydata, arrows (using vtkArrowSource) and text (using vtkTextActor3D).
As well as displaying the data the data is rotated. This is achieved by
placing all of the components into a vtkAssembly. When I compile the
code without enabling the text the desired result is produced, however
when the text is enabled everything apart from the video is displayed on
top of a white background (on machine 1), or on an alternating black and
white background (machine 2).
Machine 1 has an Intel P4 processor and an nVidia 8800GTX graphics card,
running windows xp and Visual Studio 2005. Machine 2 is an Acer laptop
with an AMD TL-52 processor and an ATI mobility Radeon graphics card,
running windows xp MCE and Visual Studio 2005 Express Edition. Both
machines have vtk version 5.04 installed.
I have included the source code for the application below. The line
"#define _TEXT_" can be commented/uncommented to turn the text on and
off, and the line "#define _VIDEO_" can be used to commented/uncommented
to turn the video feed on and off. Is this problem a result of my
coding, or because of the experimental nature of vtkTextActor3D?
#include <vtkPolyData.h>
#include <vtkRenderer.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataReader.h>
#include <vtkStructuredPoints.h>
#include <vtkStructuredPointsReader.h>
#include <vtkVolume.h>
#include <vtkAssembly.h>
#include <vtkVolumeTextureMapper3D.h>
#include <vtkVolumeProperty.h>
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkProperty.h>
#include <vtkCommand.h>
#include <vtkArrowSource.h>
#include <vtkTextActor3D.h>
#include <vtkTextProperty.h>
#include <vtkSphereSource.h>
#include <vtkWin32VideoSource.h>
#include <vtkImageMapper.h>
#include <vtkActor2D.h>
#include <vtkProperty2D.h>
#include <vtkCamera.h>
#include <vtkImageResample.h>
#include <vtkOutputWindow.h>
#define OPACITY_DELTA 0.00125
//#define _ACTOR_
#define _TEXT_
#define _VIDEO_
vtkRenderWindowInteractor *iren;
vtkPiecewiseFunction *transparency;
vtkAssembly *assembly;
vtkVolumeProperty *volProperty;
vtkRenderWindow *renWin;
vtkProp3D *textPointer;
vtkProp3D *textPointer2;
vtkAssembly *aqueduct;
double opacityLevel;
double opacityDelta;
bool changeTransparency;
vtkWin32VideoSource *webcam;
vtkImageMapper *camMapper;
vtkActor2D *camActor;
/**
Time dependant operations. Was initially used to change transparency
with
time (hence the name). Now rotates the assembly and grabs a camera
frame.
*/
class TransparencyChanger : public vtkCommand
{
public:
static TransparencyChanger *New()
{return new TransparencyChanger;}
virtual void Execute(vtkObject *caller, unsigned long, void *)
{
if(changeTransparency)
{
webcam->Grab();
/**
Reverse the direction of change of opacity if either
zero or one
have been reached.
*/
/* if((opacityLevel <= 0) || (opacityLevel >= 0.125))
{
opacityDelta *= -1;
}
opacityLevel += opacityDelta;*/
transparency->RemovePoint(3);
transparency->RemovePoint(255);
//transparency->AddSegment(2, opacityLevel, 255, opacityLevel);
transparency->AddPoint(3, opacityLevel);
transparency->AddPoint(255, opacityLevel);
// assembly->RotateX(0.1);
// cout << ".";
// cout << opacityLevel << "\r";
// assembly->Modified();
assembly->RotateY(1);
textPointer->RotateY(1);
textPointer2->RotateY(1);
aqueduct->RotateY(-1);
renWin->Render();
iren->CreateTimer(VTKI_TIMER_UPDATE);
}
}
};
/**
Attempts to reset the vtk timer. Also gives feedback to the user about
what events have been generated.
*/
class TimerResetter : public vtkCommand
{
public:
static TimerResetter *New()
{return new TimerResetter;}
virtual void Execute(vtkObject *caller, unsigned long eventId, void *)
{
cout << "Event" << eventId << endl;
if(eventId == vtkCommand::ModifiedEvent)
{
cout << "Modified Event" << endl;
}
if(eventId == vtkCommand::StartEvent)
{
cout << "Start Event" << endl;
}
if(eventId == vtkCommand::DeleteEvent)
{
cout << "Delete Event" << endl;
}
if(eventId == vtkCommand::LeftButtonPressEvent)
{
cout << "Left Mouse Button Pressed" << endl;
}
iren->CreateTimer(VTKI_TIMER_UPDATE);
}
};
/**
Catches key events and processes them appropriately.
*/
class myVTKKeyboardCallback : public vtkCommand
{
public:
static myVTKKeyboardCallback *New()
{return new myVTKKeyboardCallback;}
virtual void Execute(vtkObject *caller, unsigned long, void *)
{
char keyPressed =
vtkRenderWindowInteractor::SafeDownCast(caller)->GetKeyCode();
/**
The escape key. Exit the program if this is pressed.
*/
//cout << keyPressed << endl;
if(keyPressed == 27)
{
iren->Disable();
iren->TerminateApp();
// cout << "Exit Event";
}
/**
Toggle whether or not the transparency changes with time.
*/
//if(keyPressed == 97)//The 'T' key
//{
// changeTransparency = !changeTransparency;
// iren->ReInitialize();
//}
/**
Change the opacity of the volume data making the polydata
more or
less visible.
*/
if(keyPressed == ']')
{
if(opacityLevel > 0)
{
opacityLevel += OPACITY_DELTA;
cout << "Up" << endl;
renWin->Render();
}
}
if(keyPressed == '[')
{
if(opacityLevel < 0.25)
{
opacityLevel -= OPACITY_DELTA;
renWin->Render();
}
}
}
};
void main(int argc, char **argv)
{
vtkOutputWindow::GetInstance()->PromptUserOn();
/**
Set up pipeline for polydata.
*/
vtkPolyDataReader *polyReader = vtkPolyDataReader::New();
polyReader->SetFileName("C:\\JDHead\\VentriclesPoly.vtk");
//polyReader->SetFileName("VentriclesPoly.vtk");
polyReader->Update();
vtkPolyData *ventricles = polyReader->GetOutput();
vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
mapper->SetInput(ventricles);
vtkActor *actor = vtkActor::New();
actor->SetMapper(mapper);
vtkProperty *ventProperty = vtkProperty::New();
ventProperty->SetColor(1.0, 0, 0);
ventProperty->SetDiffuseColor(1.0, 0.0, 0.0);
ventProperty->SetSpecular(0);
// ventProperty->SetSpecularPower(20);
ventProperty->SetSpecularColor(0.75, 0.75, 0.75);
ventProperty->SetOpacity(1.0);
actor->SetProperty(ventProperty);
/**
Set up pipeline for volume data.
*/
vtkStructuredPointsReader *structReader =
vtkStructuredPointsReader::New();
structReader->SetFileName("C:\\JDHead\\JDHead_8.vtk");
//structReader->SetFileName("JDHead_8.vtk");
structReader->Update();
vtkStructuredPoints *points = structReader->GetOutput();
vtkVolumeTextureMapper3D *volMap = vtkVolumeTextureMapper3D::New();
volMap->SetInput(points);
vtkVolume *volume = vtkVolume::New();
volume->SetMapper(volMap);
opacityLevel = 0.01;
opacityDelta = OPACITY_DELTA;
transparency = vtkPiecewiseFunction::New();
transparency->AddSegment(0, 0, 2, 0);
// transparency->AddSegment(2, 0.01, 255, 0.01);
transparency->AddPoint(3, opacityLevel);
transparency->AddPoint(255, opacityLevel);
/**
We want a transparent volume so that we can see the polydata
located
within.
*/
volProperty = vtkVolumeProperty::New();
volProperty->SetScalarOpacity(transparency);
volume->SetProperty(volProperty);
vtkColorTransferFunction *rescaleGrey = vtkColorTransferFunction::New();
rescaleGrey->AddRGBSegment(0.0, 0.0, 0.0, 0.0, 255.0, 1.0, 1.0, 1.0);
volProperty->SetColor(rescaleGrey);
/**
Set up pipeline for arrow. Use only one arrow, supplied to three
different
actors, each with a different position, orientation and scale.
*/
vtkArrowSource *arrow = vtkArrowSource::New();
arrow->SetTipResolution(20);
arrow->SetShaftResolution(20);
vtkPolyData *arrowData = arrow->GetOutput();
vtkPolyDataMapper *arrowMapper = vtkPolyDataMapper::New();
arrowMapper->SetInput(arrowData);
vtkActor *arrowActor = vtkActor::New();
arrowActor->SetMapper(arrowMapper);
vtkProperty *arrowProperty = vtkProperty::New();
arrowProperty->SetDiffuseColor(0.0, 1.0, 0.0);
arrowActor->SetProperty(arrowProperty);
arrowActor->SetScale(150);
arrowActor->SetPosition(30, 192, 110);
vtkActor *arrow2Actor = vtkActor::New();
arrow2Actor->SetMapper(arrowMapper);
arrow2Actor->SetScale(150);
arrow2Actor->SetProperty(arrowProperty);
arrow2Actor->SetPosition(430, 230, 110);
arrow2Actor->RotateY(180);
vtkActor *arrow3Actor = vtkActor::New();
arrow3Actor->SetMapper(arrowMapper);
arrow3Actor->SetScale(300, 50, 50);
arrow3Actor->SetPosition(92, 410, 260);
arrow3Actor->SetProperty(arrowProperty);
arrow3Actor->RotateY(45);
arrow3Actor->RotateZ(-45);
/**
Set up pipeline for 3D text. All text components here have the same
properties.
*/
vtkTextActor3D *text = vtkTextActor3D::New();
text->SetInput("Third Ventricle");
vtkTextProperty *textProperty = vtkTextProperty::New();
textProperty->SetColor(0.0, 1.0, 0.0);
textProperty->BoldOn();
text->SetTextProperty(textProperty);
text->SetPosition(30, 180, 110);
text->RotateY(180);
text->RotateZ(180);
text->SetScale(2);
textPointer = text;
vtkTextActor3D *text2 = vtkTextActor3D::New();
text2->SetInput("Fourth Ventricle");
text2->SetTextProperty(textProperty);
text2->SetPosition(430, 218, 110);
text2->RotateZ(180);
text2->RotateY(180);
text2->SetScale(2);
textPointer2 = text2;
vtkTextActor3D *text3 = vtkTextActor3D::New();
text3->SetInput("Cerebral Aqueduct");
text3->SetTextProperty(textProperty);
text3->SetScale(2);
text3->RotateX(180);
text3->SetPosition(92, 410, 260);
text3->RotateY(180);
/**
Set up combined part of the vtk pipeline.
*/
assembly = vtkAssembly::New();
assembly->AddPart(actor);
assembly->AddPart(volume);
assembly->AddPart(arrowActor);
assembly->AddPart(arrow2Actor);
assembly->RotateX(180);
assembly->SetOrigin(192, 192, 110);
assembly->SetPosition(192, 192, 110);
aqueduct = vtkAssembly::New();
aqueduct->AddPart(arrow3Actor);
aqueduct->SetOrigin(240, 200, 110);
assembly->AddPart(aqueduct);
aqueduct->RotateY(180);
#ifdef _TEXT_
assembly->AddPart(text);
assembly->AddPart(text2);
aqueduct->AddPart(text3);
#endif
cout << assembly->GetEstimatedRenderTime() << endl;
/**
Setup pipeline to capture video from our webcam.
*/
webcam = vtkWin32VideoSource::New();
webcam->SetFrameSize(640, 480, 1);
webcam->SetOutputFormat(VTK_RGB);
webcam->SetFrameRate(15.0);
//webcam->VideoFormatDialog();
camMapper = vtkImageMapper::New();
vtkImageResample *resample = vtkImageResample::New();
resample->SetInput(webcam->GetOutput());
resample->SetAxisOutputSpacing(0, 0.5);
resample->SetAxisOutputSpacing(1, 0.46875);
camMapper->SetInput(resample->GetOutput());
//camMapper->SetInput(webcam->GetOutput());
camMapper->SetColorLevel(127.5);
camMapper->SetColorWindow(255);
camMapper->SetZSlice(0);
camActor = vtkActor2D::New();
camActor->SetMapper(camMapper);
vtkRenderer *camRenderer = vtkRenderer::New();
camRenderer->AddActor(camActor);
vtkRenderer *renderer = vtkRenderer::New();
#ifdef _ACTOR_
renderer->AddActor(actor);
#else
renderer->AddActor(assembly);
#endif
// renderer->EraseOff();
camRenderer->EraseOff();
renderer->SetBackground(1.0, 1.0, 1.0);
renWin = vtkRenderWindow::New();
renWin->SetNumberOfLayers(2);
#ifdef _VIDEO_
renWin->AddRenderer(camRenderer);
#endif
renWin->AddRenderer(renderer);
renderer->SetLayer(1);
camRenderer->SetLayer(0);
// camRenderer->InteractiveOff();
renWin->SetSize(1280, 1024);
renWin->FullScreenOn();
renWin->SetStereoTypeToCrystalEyes();
// camActor->SetWidth(1);
// camActor->SetHeight(1);
// renderer->SetAllocatedRenderTime(0.25);
// camRenderer->SetAllocatedRenderTime(0.25);
/**
Set up interaction. The timer controls frame grabbing and
rotation of
the assembly.
*/
iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
myVTKKeyboardCallback *keyed = myVTKKeyboardCallback::New();
iren->AddObserver(vtkCommand::KeyPressEvent, keyed, 1);
TransparencyChanger *changer = TransparencyChanger::New();
iren->AddObserver(vtkCommand::TimerEvent, changer, 1);
TimerResetter *resetter = TimerResetter::New();
iren->AddObserver(vtkCommand::LeftButtonPressEvent, resetter, 0);
changeTransparency = true;
iren->Initialize();
iren->CreateTimer(VTKI_TIMER_FIRST);
iren->Start();
polyReader->Delete();
structReader->Delete();
// ventricles->Delete();
// points->Delete();
mapper->Delete();
actor->Delete();
renderer->Delete();
renWin->Delete();
iren->Delete();
}
Many Thanks
Rhys Thomas
--
Mr. Rhys Thomas
School of Computer Science
Bangor University
http://www.cs.bangor.ac.uk/
--
Gall y neges e-bost hon, ac unrhyw atodiadau a anfonwyd gyda hi,
gynnwys deunydd cyfrinachol ac wedi eu bwriadu i'w defnyddio'n unig
gan y sawl y cawsant eu cyfeirio ato (atynt). Os ydych wedi derbyn y
neges e-bost hon trwy gamgymeriad, rhowch wybod i'r anfonwr ar
unwaith a dilëwch y neges. Os na fwriadwyd anfon y neges atoch chi,
rhaid i chi beidio â defnyddio, cadw neu ddatgelu unrhyw wybodaeth a
gynhwysir ynddi. Mae unrhyw farn neu safbwynt yn eiddo i'r sawl a'i
hanfonodd yn unig ac nid yw o anghenraid yn cynrychioli barn
Prifysgol Bangor. Nid yw Prifysgol Bangor yn gwarantu
bod y neges e-bost hon neu unrhyw atodiadau yn rhydd rhag firysau neu
100% yn ddiogel. Oni bai fod hyn wedi ei ddatgan yn uniongyrchol yn
nhestun yr e-bost, nid bwriad y neges e-bost hon yw ffurfio contract
rhwymol - mae rhestr o lofnodwyr awdurdodedig ar gael o Swyddfa
Cyllid Prifysgol Bangor. www.bangor.ac.uk
This email and any attachments may contain confidential material and
is solely for the use of the intended recipient(s). If you have
received this email in error, please notify the sender immediately
and delete this email. If you are not the intended recipient(s), you
must not use, retain or disclose any information contained in this
email. Any views or opinions are solely those of the sender and do
not necessarily represent those of the Bangor University.
Bangor University does not guarantee that this email or
any attachments are free from viruses or 100% secure. Unless
expressly stated in the body of the text of the email, this email is
not intended to form a binding contract - a list of authorised
signatories is available from the Bangor University Finance
Office. www.bangor.ac.uk
More information about the vtkusers
mailing list