注意的是:VTK中不同的vtkVolumeMapper支持不同的数据类型。比如vtkVolumeRayCastMapper和vtkVolumeTextureMapper2D只能支持单分组VTK_UNSIGNED_CHAR和VTK_UNSIGNED_SHORT类型数据,因此当读入其他类型的图像数据时,需要对数据进行转换,比如采用vtkImageCast或者vtkImageScale:而vtkVolumeTextMapper3D则支持任意数据类型,但是必须是单分组数据或者多元独立数据。vtkFixedPointVolumeRayCastMapper灵活性最高,可以支持所有类型数据,最高四元数据。
使用vtkFixedPointVolumeRayCastMapper类
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkActor.h"
#include "vtkSmartPointer.h"
#include "vtkProperty.h"
#include "vtkCamera.h"
#include "vtkDICOMImageReader.h"
#include "vtkImageCast.h"
#include "vtkPiecewiseFunction.h"
#include "vtkColorTransferFunction.h"
#include "vtkVolumeProperty.h"
#include "vtkVolumeRayCastCompositeFunction.h"
#include "vtkVolumeRayCastMapper.h"
#include "vtkVolume.h"
#include "vtkAutoInit.h"
#include "vtkFixedPointVolumeRayCastMapper.h"
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);
int main()
{
std::string str = "F:\\CT3";
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
reader->SetDirectoryName(str.c_str());
reader->Update();
vtkSmartPointer<vtkPiecewiseFunction> opacityFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
opacityFun->AddPoint(120,0.0);
opacityFun->AddPoint(250,1.0);
opacityFun->AddPoint(520,1.0);
opacityFun->AddPoint(650,0.0);
vtkSmartPointer<vtkColorTransferFunction> TransferFun = vtkSmartPointer<vtkColorTransferFunction>::New();
TransferFun->AddRGBPoint(120, 255 / 255.0, 98 / 255.0, 98 / 255.0);
TransferFun->AddRGBPoint(250, 255 / 255.0, 255 / 255.0, 180 / 255.0);
TransferFun->AddRGBPoint(520, 1.0, 1.0, 1.0);
TransferFun->AddRGBPoint(650, 1.0, 1.0, 1.0);
vtkSmartPointer<vtkPiecewiseFunction> grideFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
grideFun->AddPoint(120, 2.0);
grideFun->AddPoint(250, 2.0);
grideFun->AddPoint(520, 0.1);
grideFun->AddPoint(650, 0.1);
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetColor(TransferFun);
volumeProperty->SetScalarOpacity(opacityFun);
volumeProperty->SetGradientOpacity(grideFun);
volumeProperty->ShadeOn();
volumeProperty->SetAmbient(0.2);
volumeProperty->SetDiffuse(0.9);
volumeProperty->SetSpecular(0.2);
volumeProperty->SetSpecularPower(10);
vtkSmartPointer<vtkVolumeRayCastCompositeFunction> rayCastFun = vtkSmartPointer<vtkVolumeRayCastCompositeFunction>::New();
vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> mapper1 = vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New();
mapper1->SetInputConnection(reader->GetOutputPort());
mapper1->SetAutoAdjustSampleDistances(0);
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(mapper1);
volume->SetProperty(volumeProperty);
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
ren->AddVolume(volume);
ren->SetBackground(1.0,1.0,1.0);
vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
renwin->AddRenderer(ren);
renwin->SetSize(740, 480);
vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renwin);
iren->Initialize();
renwin->Render();
iren->Start();
return 0;
}
使用tkVolumeRayCastCompositeFunction类
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkActor.h"
#include "vtkSmartPointer.h"
#include "vtkProperty.h"
#include "vtkCamera.h"
#include "vtkDICOMImageReader.h"
#include "vtkImageCast.h"
#include "vtkPiecewiseFunction.h"
#include "vtkColorTransferFunction.h"
#include "vtkVolumeProperty.h"
#include "vtkVolumeRayCastCompositeFunction.h"
#include "vtkVolumeRayCastMapper.h"
#include "vtkVolume.h"
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);
int main()
{
std::string str = "F:\\CT3";
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
reader->SetDirectoryName(str.c_str());
reader->SetDataByteOrderToLittleEndian();// 小端字节序
reader->Update();
vtkSmartPointer<vtkImageCast> imageCast = vtkSmartPointer<vtkImageCast>::New();
imageCast->SetInputConnection(reader->GetOutputPort());
imageCast->SetOutputScalarTypeToUnsignedShort();
imageCast->Update();
vtkSmartPointer<vtkPiecewiseFunction> opacityFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
opacityFun->AddPoint(120,0.0);
opacityFun->AddPoint(250,1.0);
opacityFun->AddPoint(520,1.0);
opacityFun->AddPoint(650,0.0);
vtkSmartPointer<vtkColorTransferFunction> TransferFun = vtkSmartPointer<vtkColorTransferFunction>::New();
TransferFun->AddRGBPoint(120, 255 / 255.0, 98 / 255.0, 98 / 255.0);
TransferFun->AddRGBPoint(250, 255 / 255.0, 255 / 255.0, 180 / 255.0);
TransferFun->AddRGBPoint(520, 1.0, 1.0, 1.0);
TransferFun->AddRGBPoint(650, 1.0, 1.0, 1.0);
vtkSmartPointer<vtkPiecewiseFunction> grideFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
grideFun->AddPoint(120, 2.0);
grideFun->AddPoint(250, 2.0);
grideFun->AddPoint(520, 0.1);
grideFun->AddPoint(650, 0.1);
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetColor(TransferFun);
volumeProperty->SetScalarOpacity(opacityFun);
volumeProperty->SetGradientOpacity(grideFun);
volumeProperty->ShadeOn();
volumeProperty->SetAmbient(0.2);
volumeProperty->SetDiffuse(0.9);
volumeProperty->SetSpecular(0.2);
volumeProperty->SetSpecularPower(10);
vtkSmartPointer<vtkVolumeRayCastCompositeFunction> rayCastFun = vtkSmartPointer<vtkVolumeRayCastCompositeFunction>::New();
vtkSmartPointer<vtkVolumeRayCastMapper> mapper1 = vtkSmartPointer<vtkVolumeRayCastMapper>::New();
mapper1->SetVolumeRayCastFunction(rayCastFun);
mapper1->SetInputConnection(imageCast->GetOutputPort());
mapper1->SetAutoAdjustSampleDistances(0);
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(mapper1);
volume->SetProperty(volumeProperty);
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
ren->AddVolume(volume);
ren->SetBackground(1.0,1.0,1.0);
vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
renwin->AddRenderer(ren);
renwin->SetSize(740, 480);
vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renwin);
iren->Initialize();
renwin->Render();
iren->Start();
return 0;
}
使用vtkPiecewiseFunction 设置不透明度和梯度不透明vtkTransferFunctiony设置颜色传输。