2018-09-04 16:50:45:记录一个很老很老的例子,2014年写的,存在这里,算是个见证。
一,显示XYZ三视图切面。
直接用VTK中的一个demo。
class vtkSliderCallback : public vtkCommand
{
public:
static vtkSliderCallback *New()
{
return new vtkSliderCallback;
}
virtual void Execute(vtkObject *caller, unsigned long, void*)
{
vtkSliderWidget *sliderWidget =
reinterpret_cast<vtkSliderWidget*>(caller);
if(!sliderWidget) return;
int value = static_cast<int>(static_cast<vtkSliderRepresentation *>
(sliderWidget->GetRepresentation())->GetValue());
if ( this->WidgetX )
{
this->WidgetX->SetSliceIndex(value);
}
else if( this->WidgetY )
{
this->WidgetY->SetSliceIndex(value);
}
else if (this->WidgetZ)
{
this->WidgetZ->SetSliceIndex(value);
}
}
vtkSliderCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}
vtkImagePlaneWidget* WidgetX;
vtkImagePlaneWidget* WidgetY;
vtkImagePlaneWidget* WidgetZ;
};
class vtkWidgetWindowLevelCallback : public vtkCommand
{
public:
static vtkWidgetWindowLevelCallback *New()
{
return new vtkWidgetWindowLevelCallback;
}
void Execute( vtkObject *caller, unsigned long vtkNotUsed( event ),
void *callData )
{
vtkImagePlaneWidget* self =
reinterpret_cast< vtkImagePlaneWidget* >( caller );
if(!self) return;
double* wl = static_cast<double*>( callData );
if ( self == this->WidgetX )
{
this->WidgetY->SetWindowLevel(wl[0],wl[1]);
this->WidgetZ->SetWindowLevel(wl[0],wl[1]);
}
else if( self == this->WidgetY )
{
this->WidgetX->SetWindowLevel(wl[0],wl[1]);
this->WidgetZ->SetWindowLevel(wl[0],wl[1]);
}
else if (self == this->WidgetZ)
{
this->WidgetX->SetWindowLevel(wl[0],wl[1]);
this->WidgetY->SetWindowLevel(wl[0],wl[1]);
}
}
vtkWidgetWindowLevelCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}
vtkImagePlaneWidget* WidgetX;
vtkImagePlaneWidget* WidgetY;
vtkImagePlaneWidget* WidgetZ;
};
int main()
{
///文件读取的操作
vtkVolume16Reader* pReader = vtkVolume16Reader::New();
pReader->SetDataDimensions( 64, 64);
pReader->SetDataByteOrderToLittleEndian();
pReader->SetImageRange( 1, 93);
pReader->SetDataSpacing( 3.2, 3.2, 1.5);
pReader->SetFilePrefix( "D:\\VTKITK\\vtkdata-5.6.0\\Data\\headsq\\quarter" );
pReader->SetDataMask( 0x7fff);
pReader->Update();
vtkOutlineFilter *DicomOutline = vtkOutlineFilter::New();
DicomOutline->SetInputConnection( pReader->GetOutputPort() );
vtkPolyDataMapper *pMapper = vtkPolyDataMapper::New();
pMapper->SetInputConnection( DicomOutline->GetOutputPort() );
vtkActor *DicomActor = vtkActor::New();
DicomActor->SetMapper( pMapper );
vtkRenderer *ren = vtkRenderer::New();
vtkRenderer *ren1 = vtkRenderer::New();
vtkRenderer *ren2 = vtkRenderer::New();
vtkRenderer *ren3 = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
renWin->AddRenderer( ren1 );
renWin->AddRenderer( ren2 );
renWin->AddRenderer( ren3 );
renWin->AddRenderer( ren );
iren->SetRenderWindow(renWin);
vtkCellPicker *picker = vtkCellPicker::New();
picker->SetTolerance( 0.005 );
vtkImagePlaneWidget *planeWidgetX = vtkImagePlaneWidget::New();
planeWidgetX->SetInteractor( iren );
planeWidgetX->SetKeyPressActivationValue( 'x' );
planeWidgetX->SetPicker( picker );
planeWidgetX->RestrictPlaneToVolumeOn();
planeWidgetX->GetPlaneProperty()->SetColor( 0.0, 0.0, 1.0 );
planeWidgetX->DisplayTextOn();
//planeWidgetX->TextureInterpolateOn();
planeWidgetX->TextureInterpolateOff();
planeWidgetX->SetResliceInterpolateToLinear();
planeWidgetX->SetInput( (vtkDataSet*)pReader->GetOutput() );
planeWidgetX->SetPlaneOrientationToXAxes();//冠
planeWidgetX->SetSliceIndex( 32 );
planeWidgetX->GetTexturePlaneProperty()->SetOpacity( 1 );
planeWidgetX->On();
vtkImagePlaneWidget *planeWidgetY = vtkImagePlaneWidget::New();
planeWidgetY->SetInteractor( iren );
planeWidgetY->SetKeyPressActivationValue( 'y' );
planeWidgetY->SetPicker( picker );
planeWidgetY->RestrictPlaneToVolumeOn();
planeWidgetY->GetPlaneProperty()->SetColor( 1.0, 0.0, 0.0 );
planeWidgetY->DisplayTextOn();
planeWidgetY->TextureInterpolateOn();
planeWidgetY->SetResliceInterpolateToLinear();
planeWidgetY->SetInput( (vtkDataSet*)pReader->GetOutput() );
planeWidgetY->SetPlaneOrientationToYAxes();//矢
planeWidgetY->SetSliceIndex( 25 );
planeWidgetY->On();
vtkImagePlaneWidget *planeWidgetZ = vtkImagePlaneWidget::New();
planeWidgetZ->SetInteractor( iren );
planeWidgetZ->DisplayTextOn();
planeWidgetZ->RestrictPlaneToVolumeOn();
planeWidgetZ->SetKeyPressActivationValue( 'z' );
planeWidgetZ->SetPicker( picker );
planeWidgetZ->GetPlaneProperty()->SetColor( 1.0, 1.0, 0.0 );
planeWidgetZ->TextureInterpolateOn();
planeWidgetZ->SetResliceInterpolateToLinear();
planeWidgetZ->SetInput( (vtkDataSet*)pReader->GetOutput() );
planeWidgetZ->SetPlaneOrientationToZAxes(); //横断面
planeWidgetZ->SetSliceIndex( 50 );
planeWidgetZ->On();
//////////////////////////////////////////////////////
vtkWidgetWindowLevelCallback *cbk = vtkWidgetWindowLevelCallback::New();
cbk->WidgetX = planeWidgetX;
cbk->WidgetY = planeWidgetY;
cbk->WidgetZ = planeWidgetZ;
planeWidgetX->AddObserver( vtkCommand::EndWindowLevelEvent, cbk );
planeWidgetY->AddObserver( vtkCommand::EndWindowLevelEvent, cbk );
planeWidgetZ->AddObserver( vtkCommand::EndWindowLevelEvent, cbk );
cbk->Delete();
//////////////////////////////////////////////////////
vtkSliderRepresentation2D *sliderRep1 = vtkSliderRepresentation2D::New();
sliderRep1->SetMinimumValue(1);
sliderRep1->SetMaximumValue(50);
sliderRep1->SetValue(planeWidgetX->GetSliceIndex());
sliderRep1->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
sliderRep1->GetPoint1Coordinate()->SetValue(.0 ,.02);
sliderRep1->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
sliderRep1->GetPoint2Coordinate()->SetValue(1.0, .02);
vtkSliderWidget *sliderWidget1= vtkSliderWidget::New();
sliderWidget1->SetInteractor(iren);
sliderWidget1->SetRepresentation(sliderRep1);
sliderWidget1->SetAnimationModeToAnimate();
sliderWidget1->EnabledOn();
vtkSliderCallback *slidercbk = vtkSliderCallback::New();
slidercbk->WidgetX = planeWidgetX;
sliderWidget1->AddObserver(vtkCommand::InteractionEvent,slidercbk);
//////////////////////////////////////////////////////
//增加2D图像测试获取切片
vtkImageMapToColors *colorMap1 = vtkImageMapToColors::New();
colorMap1->PassAlphaToOutputOff(); //use in RGBA
colorMap1->SetActiveComponent( 0 );
colorMap1->SetOutputFormatToLuminance();
colorMap1->SetInput( (vtkDataSet*)planeWidgetX->GetResliceOutput() );
colorMap1->SetLookupTable( (vtkScalarsToColors *)planeWidgetX->GetLookupTable() );
vtkImageActor *imageActor1 = vtkImageActor::New();
imageActor1->PickableOff();
imageActor1->SetInput( colorMap1->GetOutput() );
vtkImageMapToColors *colorMap2 = vtkImageMapToColors::New();
colorMap2->PassAlphaToOutputOff();
colorMap2->SetActiveComponent( 0 ); // for muti-component
colorMap2->SetOutputFormatToLuminance();
colorMap2->SetInput( (vtkDataSet*)planeWidgetY->GetResliceOutput() );
colorMap2->SetLookupTable( (vtkScalarsToColors *)planeWidgetX->GetLookupTable() );
vtkImageActor *imageActor2 = vtkImageActor::New();
imageActor2->PickableOff();
imageActor2->SetInput( colorMap2->GetOutput() );
vtkImageMapToColors *colorMap3 = vtkImageMapToColors::New();
colorMap3->PassAlphaToOutputOff();
colorMap3->SetActiveComponent( 0 );
colorMap3->SetOutputFormatToLuminance();
colorMap3->SetInput( (vtkDataSet*)planeWidgetZ->GetResliceOutput() );
colorMap3->SetLookupTable( (vtkScalarsToColors *)planeWidgetX->GetLookupTable());
vtkImageActor *imageActor3 = vtkImageActor::New();
imageActor3->PickableOff();
imageActor3->SetInput( colorMap3->GetOutput() );
/////////////////////////////////////////////////////////////////////
vtkSmartPointer<vtkTransform> transform =
vtkSmartPointer<vtkTransform>::New();
transform->Translate(-10.0, -10.0, -10.0);
vtkSmartPointer<vtkAxesActor> axes =
vtkSmartPointer<vtkAxesActor>::New();
axes->SetUserTransform(transform);
ren->AddActor(axes);
//////////////////////////////////////////////////////
ren->AddActor( DicomActor ); //outline
ren1->AddActor( imageActor1 );
ren2->AddActor( imageActor2 );
ren3->AddActor( imageActor3 );
// OK
ren->SetBackground( 0.1, 0.1, 0.2 );
ren1->SetBackground( 0.1, 0.2, 0.1 );
ren2->SetBackground( 0.2, 0.1, 0.2 );
ren3->SetBackground( 0.2, 0.2, 0.2 );
renWin->SetSize( 600, 400 );
//renWin->SetFullScreen(1);
ren3->SetViewport( 0, 0.5, 0.5, 1 );
ren1->SetViewport( 0.5, 0.5, 1, 1 );
ren2->SetViewport( 0, 0, 0.5, 0.5 );
ren->SetViewport( 0.5, 0, 1, 0.5 );
ren->GetActiveCamera()->Dolly(1.15);
ren1->GetActiveCamera()->Dolly(1.15);
ren2->GetActiveCamera()->Dolly(1.15);
ren3->GetActiveCamera()->Dolly(1.15);
ren->ResetCamera();
ren1->ResetCamera();
ren2->ResetCamera();
ren3->ResetCamera();
iren->Initialize();
renWin->SetWindowName("vtkSuperViewer by winston");
iren->Start();
renWin->Render();
return 0;
}
二,显示Z视图。
这个显示的方法是把vtkImagePlaneWidget不断的映射到vtkImageMapToColors上,其实是new了一个actor。我的需求是把vtkImagePlaneWidget改成一个新的Widget,只有一个面,保持原来的特性,但不能再切换的时候缩小。
class vtkSliderCallback : public vtkCommand
{
public:
static vtkSliderCallback *New()
{
return new vtkSliderCallback;
}
virtual void Execute(vtkObject *caller, unsigned long, void*)
{
vtkSliderWidget *sliderWidget =
reinterpret_cast<vtkSliderWidget*>(caller);
if(!sliderWidget) return;
int value = static_cast<int>(static_cast<vtkSliderRepresentation *>
(sliderWidget->GetRepresentation())->GetValue());
if ( this->WidgetX )
{
this->WidgetX->SetSliceIndex(value);
}
else if( this->WidgetY )
{
this->WidgetY->SetSliceIndex(value);
}
else if (this->WidgetZ)
{
this->WidgetZ->SetSliceIndex(value);
}
}
vtkSliderCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}
vtkImagePlaneWidget* WidgetX;
vtkImagePlaneWidget* WidgetY;
vtkImagePlaneWidget* WidgetZ;
};
class vtkWidgetWindowLevelCallback : public vtkCommand
{
public:
static vtkWidgetWindowLevelCallback *New()
{
return new vtkWidgetWindowLevelCallback;
}
void Execute( vtkObject *caller, unsigned long vtkNotUsed( event ),
void *callData )
{
vtkImagePlaneWidget* self =
reinterpret_cast< vtkImagePlaneWidget* >( caller );
if(!self) return;
double* wl = static_cast<double*>( callData );
if ( self == this->WidgetX )
{
this->WidgetY->SetWindowLevel(wl[0],wl[1]);
this->WidgetZ->SetWindowLevel(wl[0],wl[1]);
}
else if( self == this->WidgetY )
{
this->WidgetX->SetWindowLevel(wl[0],wl[1]);
this->WidgetZ->SetWindowLevel(wl[0],wl[1]);
}
else if (self == this->WidgetZ)
{
this->WidgetX->SetWindowLevel(wl[0],wl[1]);
this->WidgetY->SetWindowLevel(wl[0],wl[1]);
}
}
vtkWidgetWindowLevelCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}
vtkImagePlaneWidget* WidgetX;
vtkImagePlaneWidget* WidgetY;
vtkImagePlaneWidget* WidgetZ;
};
int main()
{
vtkVolume16Reader* pReader = vtkVolume16Reader::New();
pReader->SetDataDimensions( 64, 64);
pReader->SetDataByteOrderToLittleEndian();
pReader->SetImageRange( 1, 93);
pReader->SetDataSpacing( 3.2, 3.2, 1.5);
pReader->SetFilePrefix( "D:\\VTKITK\\VTK\\vtkdata-5.8.0\\Data\\headsq\\quarter" );
pReader->SetDataMask( 0x7fff);
pReader->Update();
vtkRenderer *ren = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
iren->SetInteractorStyle(style);
ren->SetBackground( 0.0, 0.0, 0.4);
renWin->AddRenderer( ren );
iren->SetRenderWindow(renWin);
vtkCellPicker *picker = vtkCellPicker::New();
picker->SetTolerance( 0.005 );
vtkProperty* ipwProp = vtkProperty::New();
vtkImagePlaneWidget *planeWidgetZ = vtkImagePlaneWidget::New();
//planeWidgetZ->SetInteractor( iren );
planeWidgetZ->DisplayTextOn();
planeWidgetZ->SetPicker( picker );
planeWidgetZ->RestrictPlaneToVolumeOn();
planeWidgetZ->GetPlaneProperty()->SetColor( 1.0, 1.0, 0.0 );
planeWidgetZ->SetKeyPressActivationValue( 'z' );
planeWidgetZ->SetTexturePlaneProperty(ipwProp);
planeWidgetZ->SetResliceInterpolateToNearestNeighbour();
planeWidgetZ->SetInput( (vtkDataSet*)pReader->GetOutput() );
planeWidgetZ->SetPlaneOrientationToZAxes(); //横断面
//planeWidgetZ->SetSliceIndex( 50 );
//planeWidgetZ->On();
//////////////////////////////////////////////////////
vtkWidgetWindowLevelCallback *callback = vtkWidgetWindowLevelCallback::New();
callback->WidgetZ = planeWidgetZ;
planeWidgetZ->AddObserver( vtkCommand::EndWindowLevelEvent, callback );
callback->Delete();
//////////////////////////////////////////////////////
vtkSliderRepresentation2D *sliderRep = vtkSliderRepresentation2D::New();
sliderRep->SetMinimumValue(1);
sliderRep->SetMaximumValue(50);
sliderRep->SetValue(planeWidgetZ->GetSliceIndex());
sliderRep->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
sliderRep->GetPoint1Coordinate()->SetValue(.0 ,.02);
sliderRep->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
sliderRep->GetPoint2Coordinate()->SetValue(1.0, .02);
vtkSliderWidget *sliderWidget= vtkSliderWidget::New();
sliderWidget->SetInteractor(iren);
sliderWidget->SetRepresentation(sliderRep);
sliderWidget->SetAnimationModeToAnimate();
sliderWidget->EnabledOn();
vtkSliderCallback *slidercbk = vtkSliderCallback::New();
slidercbk->WidgetX = planeWidgetZ;
sliderWidget->AddObserver(vtkCommand::InteractionEvent,slidercbk);
//////////////////////////////////////////////////////
//增加2D图像测试获取切片
vtkImageMapToColors *colorMap = vtkImageMapToColors::New();
colorMap->PassAlphaToOutputOff();
colorMap->SetActiveComponent( 0 );
colorMap->SetOutputFormatToLuminance();
colorMap->SetInput( (vtkDataSet*)planeWidgetZ->GetResliceOutput() );
colorMap->SetLookupTable( (vtkScalarsToColors *)planeWidgetZ->GetLookupTable());
vtkImageActor *imageActor = vtkImageActor::New();
imageActor->PickableOff();
imageActor->SetInput( colorMap->GetOutput() );
ren->AddActor( imageActor );
// OK
renWin->SetSize( 600, 400 );
ren->ResetCamera();
iren->Initialize();
renWin->SetWindowName("vtkSuperViewer by winston");
iren->Start();
renWin->Render();
//return 0;
}
三,vtkImagePlaneWidget 的一个切片
可以切换,但会有显示问题。大小会改变,这样不能自定义内容,看来只能自己写扩展类。
边框,十字叉,坐标取点,灰度取点,切片切换,窗宽窗位获取,窗宽窗位调节。
class vtkSliderCallback : public vtkCommand
{
public:
static vtkSliderCallback *New()
{
return new vtkSliderCallback;
}
virtual void Execute(vtkObject *caller, unsigned long, void*)
{
vtkSliderWidget *sliderWidget =
reinterpret_cast<vtkSliderWidget*>(caller);
if(!sliderWidget) return;
int value = static_cast<int>(static_cast<vtkSliderRepresentation *>
(sliderWidget->GetRepresentation())->GetValue());
if ( this->WidgetX )
{
this->WidgetX->SetSliceIndex(value);
}
else if( this->WidgetY )
{
this->WidgetY->SetSliceIndex(value);
}
else if (this->WidgetZ)
{
this->WidgetZ->SetSliceIndex(value);
}
}
vtkSliderCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}
vtkImagePlaneWidget* WidgetX;
vtkImagePlaneWidget* WidgetY;
vtkImagePlaneWidget* WidgetZ;
};
int main()
{
vtkVolume16Reader* pReader = vtkVolume16Reader::New();
pReader->SetDataDimensions( 64, 64);
pReader->SetDataByteOrderToLittleEndian();
pReader->SetImageRange( 1, 93);
pReader->SetDataSpacing( 3.2, 3.2, 1.5);
pReader->SetFilePrefix( "D:\\VTKITK\\VTK\\vtkdata-5.8.0\\Data\\headsq\\quarter" );
pReader->SetDataMask( 0x7fff);
pReader->Update();
vtkRenderer *ren = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
iren->SetInteractorStyle(style);
ren->SetBackground( 0.0, 0.0, 0.0);
renWin->AddRenderer( ren );
iren->SetRenderWindow(renWin);
vtkCellPicker *picker = vtkCellPicker::New();
picker->SetTolerance( 0.005 );
vtkProperty* ipwProp = vtkProperty::New();
vtkImagePlaneWidget *planeWidgetZ = vtkImagePlaneWidget::New();
planeWidgetZ->SetInteractor( iren );
planeWidgetZ->DisplayTextOn();
planeWidgetZ->SetPicker( picker );
planeWidgetZ->RestrictPlaneToVolumeOn();
planeWidgetZ->GetPlaneProperty()->SetColor( 1.0, 1.0, 0.0 );
planeWidgetZ->SetKeyPressActivationValue( 'z' );
planeWidgetZ->SetTexturePlaneProperty(ipwProp);
planeWidgetZ->SetResliceInterpolateToNearestNeighbour();
planeWidgetZ->SetInput( (vtkDataSet*)pReader->GetOutput() );
planeWidgetZ->SetPlaneOrientationToZAxes(); //横断面
planeWidgetZ->SetSliceIndex( 50 );
planeWidgetZ->On();
//////////////////////////////////////////////////////
vtkSliderRepresentation2D *sliderRep = vtkSliderRepresentation2D::New();
sliderRep->SetMinimumValue(1);
sliderRep->SetMaximumValue(50);
sliderRep->SetValue(planeWidgetZ->GetSliceIndex());
sliderRep->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
sliderRep->GetPoint1Coordinate()->SetValue(.0 ,.02);
sliderRep->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
sliderRep->GetPoint2Coordinate()->SetValue(1.0, .02);
vtkSliderWidget *sliderWidget= vtkSliderWidget::New();
sliderWidget->SetInteractor(iren);
sliderWidget->SetRepresentation(sliderRep);
sliderWidget->SetAnimationModeToAnimate();
sliderWidget->EnabledOn();
vtkSliderCallback *slidercbk = vtkSliderCallback::New();
slidercbk->WidgetZ = planeWidgetZ;
sliderWidget->AddObserver(vtkCommand::InteractionEvent,slidercbk);
// OK
renWin->SetSize( 600, 400 );
ren->ResetCamera();
iren->Initialize();
renWin->SetWindowName("vtkSuperViewer by winston");
iren->Start();
renWin->Render();
//return 0;
}