VTK修炼之道67:体绘制讨论_不透明度传输函数
来源:互联网 发布:安卓软件效果器 编辑:程序博客网 时间:2024/05/16 14:51
1.vtkVolume
vtkVolume类似于几何渲染中的vtkActor,用于表示渲染场景中的对象。除了存储基本变换信息(平移、旋转、缩放等),其内部还存储了两个重要对象。这两个对象分别是vtkAbstractVolumeMapper对象和vtkVolumeProperty对象。
1.1 void SetMapper(vtkAbstractVolumeMapper* mapper);
该函数用于连接vtkAbstractVolumeMapper对象,并根据不同的体绘制算法获取其内部生成的图元数据。具体的体绘制Mapper如下所示:
1.2 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类定义标量线性分段函数,其支持两种设置方式,第一种方式是直接添加断点;第二种是直接添加一条线段,即添加两个断点。2.1 直接添加断点
该函数驱动如下:int AddPoint(double x,double y);第一个参数x为自变量,这里是指灰度值;y则是映射值,这里指不同明度。执行成功后,返回当前添加的断点的index索引值(从0开始),否则返回-1.2.2 直接添加一条线段
其核心就是添加两个断点。其函数设置如下:void AddSegment(double x1,double y1,double x2, double y2);添加两个断点(x1,y1)/(x2,y2),组成一条线段。注意添加一条线段时,如果改线段内已经存在断点,则该断点会被清除。如果采用这种方式设置不透明度传输函数,则上面代码要重写为: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)2.3 删除断点操作
vtkPiecewiseFunction类中也包括了删除断点函数。具体如下:int RemovePoint(double x); //将自变量值为x的断点删除;
void RemoveAllPoints(); //删除所有断点;
2.4 实际意义
上面代码中设置了三个不透明度断点(70,0.00)、(90,0.40)、(180,0.60)。其意义是,当灰度值小于70时,不透明导读应设置为0;当灰度值介于70~90时,通过线性映射到0.0~0.40之间;当灰度值介于90~180时,现行映射至0.40~0.60;当灰度值大于180度时,不透明度映射到0.60~1.00的一个值。如果图像的灰度范围为0~255,那么上述代码利用三个断点将整个灰度范围分为四段处理。2.5 Clamping标志
vtkPiecewiseFunction中有个Clamping标志,当Clamping标志为真时,对于小于所有断点最小灰度值的灰度值,其映射为最小灰度值断点对应的映射值;对于大于所有断点最大灰度值的灰度值,其映射值为最大灰度值断点对应的映射值。如下图所示:
当Clamping标志为假时,所有位于断点灰度值范围之外的灰度对应映射值都为零。如下图所示:
3.不同不透明度传输函数对应的体绘制实验
代码如下:
#include <vtkAutoInit.h>VTK_MODULE_INIT(vtkRenderingOpenGL);VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);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("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;}
利用不透明度传输函数,可以有选择的对图像中的对象进行显示。对于不想看到的图像部分,只需将其对应的灰度范围的不透明度映射为0即可。下图即为该程序的输出成果:
左视图采用的不透明度设置参数如下:
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<vtkPiecewiseFunction> compositeOpacity2 =vtkSmartPointer<vtkPiecewiseFunction>::New();compositeOpacity2->AddPoint(100, 0.0);compositeOpacity2->AddPoint(140, 0.4);compositeOpacity2->AddPoint(180, 0.6);volumeProperty2->SetScalarOpacity(compositeOpacity2);
4.参看资料
1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3. 张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.
- VTK修炼之道67:体绘制讨论_不透明度传输函数
- VTK修炼之道68:体绘制讨论_梯度不透明度传输函数
- VTK修炼之道69:体绘制讨论_颜色传输函数
- VTK修炼之道70:体绘制讨论_光照&阴影、VTKLODProp3D
- VTK修炼之道60:体绘制_体绘制管线&图形渲染管线
- VTK修炼之道61:体绘制_光线投影+最大密度投影+等值面法
- VTK修炼之道63:纹理映射体绘制_二维纹理映射
- VTK修炼之道64:纹理映射体绘制_三维纹理映射
- VTK修炼之道65:体绘制裁剪_Cropping技术
- VTK修炼之道66:体绘制裁剪_Cripping技术
- VTK修炼之道62:体绘制_固定点光线投影体绘制与GPU加速光线投影体绘制
- VTK修炼之道1_初识VTK
- VTK修炼之道14:图像处理_创建
- VTK修炼之道31:图像二值化_阈值法
- VTK修炼之道32:边缘检测_梯度算子
- VTK修炼之道36:图像平滑_均值滤波器
- VTK修炼之道38:图像平滑_中值滤波器
- VTK修炼之道39:图像平滑_各向异性滤波
- 对象的解构赋值
- YUV444,YUV422P,YUVY,YUYV,UYVY,NV21,NV12
- Linux环境下如何安装nginx
- jbdm注意事项
- C++基本控制结构
- VTK修炼之道67:体绘制讨论_不透明度传输函数
- Java问题排查常用linux命令
- 碎知识总结
- HTML网页制作时需要注意的技巧
- jsp和controller数据交互工具类
- oracle笔记(6)----exists 和not exists、in、not in
- 数组的解构赋值
- ava自带的性能监测工具用法简介——jstack、jconsole、jinfo、jmap、jdb、jsta、jvisualvm
- 记录关于Android Studio导入github项目遇到的一个坑