1.vtkVolume
vtkVolume类似于几何渲染vtkActor,用来表示渲染场景中的对象。除了存储基本的变换信息(平移、旋转、缩放等)外,还存储了两个重要的对象。这两个对象是vtkAbstractVolumeMapper对象和vtkVolumeProperty对象。
- void SetMapper(vtkAbstractVolumeMapper* mapper); 该函数用于连接vtkAbstractVolumeMapper对象,并根据不同的体画算法获取内部生成的图元数据。具体的体画Mapper如下所示:
- void SetProperty(vtkVolumeProperty* property) 该函数用于设置VTKVolumeProperty对象。其中vtkVolumeProperty设置颜色、不透明的颜色、不透明函数、阴影和其他信息。在身体绘制中,颜色和不透明度决定了最终的显示结果。
2.VTKVolumeProperty——传输函数的不透明度
不透明度传输函数分段线性标量映射函数可以将光投影过程中的采样点灰度值映射到不同的不透明度值,并决定了最终的颜色值。标准的不透明度设置代码如下:
///添加灰度不透明度属性 vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New(); compositeOpacity->AddPoint(70, 0.0); compositeOpacity->AddPoint(90, 0.4); compositeOpacity->AddPoint(180, 0.6); volumeProperty->SetScalarOpacity(compositeOpacity);
VTKVolumeProperty通过以下函数设置和获得不透明度函数:void SetScalarOpacity(vtkPiecewiseFuntion* function); vtkPiecewiseFunction* GetScalarOpacity(int Index);
vtkPiecewiseFunction类别定义标量线性分段函数,支持两种设置方方第一种是直接添加断点;第二种是直接添加一个线段,即添加两个断点。
- [1 ]直接添加断点
- 函数驱动如下:
- int AddPoint(double x,double y);第一个参数x是自变量,指灰度值;y这里指的是不同亮度的映射值。执行成功后,返回当前添加的断点index索引值(从0开始),否则返回-1.
- [2] 直接添加线段 其核心是添加两个断点。函数设置如下
void AddSegment(double x1,double y1,double x2, double y2);
加两个断点(x1,y1)/(x2,y二、形成线段。 请注意,在添加线段时,如果在更改线段中有断点,则将清除断点。如果以这种方式设置不透明度传输函数,上述代码应重写为:compositeOpacity->AddSegment(70, 0, 90, 0.4); compositeOpacity->AddSegment(90, 0.4, 180, 0.6); compositeOpacity->AddSegment(180, 0.6, 255, 1.0); volumeProperty->SetScalarOpacity(compositeOpacity)
- [3] 删除断点操作 vtkPiecewiseFunction该类还包括删除断点函数。具体如下: int RemovePoint(double x); //删除自变量值为x的断点; void RemoveAllPoints(); //删除所有断点;
- 上述代码中有三个不透明度断点(70,0.00)、(90,0.40)、(180,0.60)。当灰度值小于70时,不透明导读应设置为0;当灰度值介于70时90点,线性映射0.00.40之间;当灰度值介于90180点,现在映射0.400.60;当灰度值大于180度时,不透明度映射到0.601.00值。如果图像的灰度范围为0255,上述代码使用三个断点将整个灰度范围 分为 四段处理。
- [5]Clamping标志 vtkPiecewiseFunction中有个Clamping标志,当Clamping当标志为真实时,对于小于所有断点最小灰度值的灰度值,其映射为与最小灰度值断点相对应的映射值;对于大于所有断点最大灰度值的灰度值,其映射值为与最大灰度值断点相对应的映射值。如下图所示:
3.不同透明度传输函数对应的体画实验
#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2); VTKMODULE_INIT(vtkRenderingVolumeOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <vtkSmartPointer.h>
#include <vtkStructuredPointsReader.h>
#include <vtkStructuredPoints.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkVolumeProperty.h>
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkVolume.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCamera.h>
int main()
{
vtkSmartPointer<vtkStructuredPointsReader> reader =
vtkSmartPointer<vtkStructuredPointsReader>::New();
reader->SetFileName("data/mummy.128.vtk");
reader->Update();
vtkSmartPointer<vtkGPUVolumeRayCastMapper> volumeMapper1 =
vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
volumeMapper1->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkGPUVolumeRayCastMapper> volumeMapper2 =
vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
volumeMapper2->SetInputData(reader->GetOutput());
/****************************************************************/
vtkSmartPointer<vtkVolumeProperty> volumeProperty1 =
vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty1->SetInterpolationTypeToLinear(); //设置线性插值
volumeProperty1->ShadeOn();//开启阴影功能
volumeProperty1->SetAmbient(0.4);//设置环境温度系数
volumeProperty1->SetDiffuse(0.6);//设置漫反射系数
volumeProperty1->SetSpecular(0.2);//设置镜面反射系数
vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity1 =
vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity1->AddPoint(70, 0.0);
compositeOpacity1->AddPoint(90, 0.4);
compositeOpacity1->AddPoint(180, 0.6);
volumeProperty1->SetScalarOpacity(compositeOpacity1);
vtkSmartPointer<vtkVolumeProperty> volumeProperty2 =
vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty2->SetInterpolationTypeToLinear(); //设置线性插值
volumeProperty2->ShadeOn();//开启阴影功能
volumeProperty2->SetAmbient(0.4);//设置环境温度系数
volumeProperty2->SetDiffuse(0.6);//设置漫反射系数
volumeProperty2->SetSpecular(0.2);//设置镜面反射系数
vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity2 =
vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity2->AddPoint(100, 0.0);
compositeOpacity2->AddPoint(140, 0.4);
compositeOpacity2->AddPoint(180, 0.6);
volumeProperty2->SetScalarOpacity(compositeOpacity2);
//
vtkSmartPointer<vtkPiecewiseFunction> gradientOpacity =
vtkSmartPointer<vtkPiecewiseFunction>::New();
gradientOpacity->AddPoint(10, 0.0);
gradientOpacity->AddPoint(90, 0.5);
gradientOpacity->AddPoint(100, 1.0);
volumeProperty1->SetGradientOpacity(gradientOpacity);
volumeProperty2->SetGradientOpacity(gradientOpacity);
vtkSmartPointer<vtkColorTransferFunction> color =
vtkSmartPointer<vtkColorTransferFunction>::New();
color->AddRGBPoint(0, 0, 0, 0);
color->AddRGBPoint(64, 1.0, 0.52, 0.3);
color->AddRGBPoint(190.0, 1.00, 1.00, 1.00);
color->AddRGBPoint(220.0, 0.20, 0.20, 0.20);
volumeProperty1->SetColor(color);
volumeProperty2->SetColor(color);
/****************************************************************/
vtkSmartPointer<vtkVolume> volume1 =
vtkSmartPointer<vtkVolume>::New();
volume1->SetMapper(volumeMapper1);
volume1->SetProperty(volumeProperty1);
vtkSmartPointer<vtkVolume> volume2 =
vtkSmartPointer<vtkVolume>::New();
volume2->SetMapper(volumeMapper2);
volume2->SetProperty(volumeProperty2);
//
double View1[4] = {
0, 0, 0.5, 1 };
double View2[4] = {
0.5, 0, 1, 1 };
vtkSmartPointer<vtkRenderer> render1 =
vtkSmartPointer<vtkRenderer>::New();
render1->AddVolume(volume1);
render1->SetViewport(View1);
render1->SetBackground(1, 1, 0);
vtkSmartPointer<vtkRenderer> render2 =
vtkSmartPointer<vtkRenderer>::New();
render2->AddVolume(volume2);
render2->SetViewport(View2);
render2->SetBackground(0, 1, 0);
vtkSmartPointer<vtkRenderWindow> rw =
vtkSmartPointer<vtkRenderWindow>::New();
rw->AddRenderer(render1);
rw->AddRenderer(render2);
rw->SetSize(640, 320);
rw->SetWindowName("Differ Gray Opacity Function");
vtkSmartPointer<vtkRenderWindowInteractor> rwi =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
rwi->SetRenderWindow(rw);
render1->GetActiveCamera()->SetPosition(0, -1, 0);
render1->GetActiveCamera()->SetFocalPoint(0, 0, 0);
render1->GetActiveCamera()->SetViewUp(0, 0, 1);
render1->GetActiveCamera()->Azimuth(30);
render1->GetActiveCamera()->Elevation(30);
render1->ResetCamera();
render2->SetActiveCamera(render1->GetActiveCamera());
rw->Render();
rwi->Start();
return 0;
}
左视图采用的不透明度设置参数如下:vtkSmartPointer compositeOpacity1 = vtkSmartPointer::New(); compositeOpacity1->AddPoint(70, 0.0); compositeOpacity1->AddPoint(90, 0.4); compositeOpacity1->AddPoint(180, 0.6); volumeProperty1->SetScalarOpacity(compositeOpacity1); 右视图采用的不透明度设置参数如下: vtkSmartPointer compositeOpacity2 = vtkSmartPointer::New(); compositeOpacity2->AddPoint(100, 0.0); compositeOpacity2->AddPoint(140, 0.4); compositeOpacity2->AddPoint(180, 0.6); volumeProperty2->SetScalarOpacity(compositeOpacity2);