VTK修炼之道60:体绘制_体绘制管线图形渲染管线
1.几何渲染与体绘制
1.1 几何渲染
前面练习的渲染技术都是几何渲染技术。所谓的几何渲染技术,就是通过绘制几何图元(顶点、线段、面片等)来渲染数据,例如:绘制图像需要在空间中建立一个四边形图元,然后以纹理映射的方式将该图像贴图到该图元上进行渲染;而三维模型的绘制通常会分解为一系列的多边形面片进行绘制。这种通过生成中间几何图元来进行渲染的方法称为几何渲染。几何渲染的速度比较快,但是不能显示体数据的内部细节。例如:在渲染人的三维CT体数据时,通过几何渲染只能在切片图像之间进行切换,而不能对体数据内部细节进行立体观察。1.2 体绘制
体绘制技术,更多的时候,我们把它称为三维重建(区别于投影图像的三维重建),是一种直接利用体数据来生成二维图像的绘制技术。与面绘制不同,体绘制不需要提取体数据内部的等值面,它是对三维体数据进行采样和合成的过程。体数据能过通过设置不透明度值来显示体数据内部的不同成分和细节,例如显示人体CT图像的不同器官和组织。
2.图形渲染管线
在进行体绘制管线学习之前,很有必要回顾一下前面的VTK可视化管线的基本组成。我习惯把渲染窗口vtkRenderWindow看做一个剧院,剧院中一般需要灯光(vtkLight)、相机(vtkCamera)和舞台(vtkRenderer)来呈现精彩的演出。舞台上负责表演的自然就是演员(vtkActor),而且演员往往不止一个,可以根据需要为舞台加入更多的演员(vtkActor)。每个演员又各具特色,而用来表示其特色的则是vtkProperty(负责控制值颜色、材质和不透明度等);每个vtkActor的数据和渲染信息存储在一个vtkMapper对象中,负责将原始数据转换为渲染所需要的图元数据。
3.体绘制管线
从可视化管线的组成上来讲,体绘制的渲染管线与几何渲染管线基本一致,先通过一个实例进行初步认识:#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); VTK_MODULE_INIT(vtkRenderingVolumeOpenGL); //错误:no override found for 'vtkRayCastImageDisplayHelper'. VTK_MODULE_INIT(vtkRenderingFreeType); VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h> #include <vtkStructuredPoints.h> #include <vtkStructuredPointsReader.h> #include <vtkFixedPointVolumeRayCastMapper.h> #include <vtkColorTransferFunction.h> #include <vtkPiecewiseFunction.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkVolumeProperty.h> #include <vtkAxesActor.h> #include <vtkOrientationMarkerWidget.h>int main(int argc, char *argv[]) {vtkSmartPointer<vtkStructuredPointsReader> reader =vtkSmartPointer<vtkStructuredPointsReader>::New();reader->SetFileName("mummy.128.vtk");reader->Update();vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> volumeMapper =vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New();volumeMapper->SetInputData(reader->GetOutput());//设置光线采样距离//volumeMapper->SetSampleDistance(volumeMapper->GetSampleDistance()*4);//设置图像采样步长//volumeMapper->SetAutoAdjustSampleDistances(0);//volumeMapper->SetImageSampleDistance(4);/*************************************************************************/vtkSmartPointer<vtkVolumeProperty> volumeProperty =vtkSmartPointer<vtkVolumeProperty>::New();volumeProperty->SetInterpolationTypeToLinear();volumeProperty->ShadeOn(); //打开或者关闭阴影测试volumeProperty->SetAmbient(0.4);volumeProperty->SetDiffuse(0.6); //漫反射volumeProperty->SetSpecular(0.2); //镜面反射//设置不透明度vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =vtkSmartPointer<vtkPiecewiseFunction>::New();compositeOpacity->AddPoint(70, 0.00);compositeOpacity->AddPoint(90, 0.40);compositeOpacity->AddPoint(180, 0.60);volumeProperty->SetScalarOpacity(compositeOpacity); //设置不透明度传输函数//compositeOpacity->AddPoint(120, 0.00);//测试隐藏部分数据,对比不同的设置//compositeOpacity->AddPoint(180, 0.60);//volumeProperty->SetScalarOpacity(compositeOpacity);//设置梯度不透明属性vtkSmartPointer<vtkPiecewiseFunction> volumeGradientOpacity =vtkSmartPointer<vtkPiecewiseFunction>::New();volumeGradientOpacity->AddPoint(10, 0.0);volumeGradientOpacity->AddPoint(90, 0.5);volumeGradientOpacity->AddPoint(100, 1.0);volumeProperty->SetGradientOpacity(volumeGradientOpacity);//设置梯度不透明度效果对比//设置颜色属性vtkSmartPointer<vtkColorTransferFunction> color =vtkSmartPointer<vtkColorTransferFunction>::New();color->AddRGBPoint(0.000, 0.00, 0.00, 0.00);color->AddRGBPoint(64.00, 1.00, 0.52, 0.30);color->AddRGBPoint(190.0, 1.00, 1.00, 1.00);color->AddRGBPoint(220.0, 0.20, 0.20, 0.20);volumeProperty->SetColor(color);/********************************************************************************/vtkSmartPointer<vtkVolume> volume =vtkSmartPointer<vtkVolume>::New();volume->SetMapper(volumeMapper);volume->SetProperty(volumeProperty);vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();ren->SetBackground(0, 1, 0);ren->AddVolume(volume);vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(ren);rw->SetSize(640, 480);rw->Render();rw->SetWindowName("VolumeRendering PipeLine");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);/********************************************************************************///vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();//axes->SetScale(10);//vtkSmartPointer<vtkOrientationMarkerWidget> widget =// vtkSmartPointer<vtkOrientationMarkerWidget>::New();//widget->SetOutlineColor(1, 1, 1);//widget->SetViewport(0, 0, 0.2, 0.2);//widget->SetOrientationMarker(axes);//widget->SetInteractor(rwi);//widget->SetEnabled(1);//widget->InteractiveOn();ren->ResetCamera();rw->Render();rwi->Start();return 0; }
#vtkVolumeRayCastMapper:
vtkVolumeRayCastMapper定义了一个光线投影体绘制Mapper,其主要接受如下两个输入。SetInputData(vtkImageData*):该函数用于设置输入图像数据。SetVolumeRayCastFunction(vtkVolumeRayCastFunction*):该函数用于设置光线透射函数类型。vtkVolumeRayCastCompositeFunction是vtkVolumeRayCastFunction的子类,定义了光线经过体数据后的颜色计算方式。需要注意的是,这个类备受很多科研人员职责,在VTK7.0.0之后会被移除。这里我采用vtkFixedPointVolumeRayCastMapper以避免如下错误:#vtkVolumeProperty:该类定义了体绘制属性,设置标量不透明度传输函数、梯度不透明度函数、颜色传输函数、阴影。vtkVolumeProperty用于设置体绘制的属性,决定体绘制的渲染效果,其中:
- SetScalarOpacity(vtkPiecewiseFunction* function):该类用于设置灰度不透明度函数。
- SetColor(vtkColorTransferFunction *function):该类用于设置颜色传输函数。
#vtkVolume:vtkVolume与几何渲染中的vtkActor作用一致,需要设置如下两个输入:
- void SetMapper(vtkAbstractVolumeMapper* mapper):该函数用于设置Mapper对象。
- void SetProperty(vtkVolumeProperty* property):该函数用于设置属性对象。
#定义vtkRenderer、vtkRenderWindow、vtkRenderWindowInteractor对象,建立可视化管线。体绘制渲染结果如下:
4.图形渲染管线与体绘制渲染管线对比
通过上面代码可以看出,体绘制渲染管线与几何渲染管线的组成是比较一致的,都需要vtkRenderWindow、vtkRenderer、vtkActor/vtkVolume、vtkMapper等对象。它们不同之处在于:
- 几何渲染中,通常使用vtkActor来渲染几何图像数据,使用vtkImageActor来渲染图像数据;而在体绘制中,则使用vtkVolume渲染数据。
- 在几何渲染中,通常采用vtkPolyDataMapper实现输入数据向图元数据的转换;在体绘制中,则采用vtkVolumeRayCastMapper,要切记的是,这个类是与体绘制的算法相关的,不同的体绘制算法会有不同的Mapper类。
更一般的,几何图像渲染管线与体绘制的渲染管线对比图如下:虚线部分表示两者不同之处,从上图我们能够看出来,两种渲染方式不同点主要在Mapper和Actor对象上。
5.no override found for 'vtkRayCastImageDisplayHelper'修订
体绘制过程中,出现如下错误:这也是一个初始化的问题,解决办法如下:VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);
6.参看资料
1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3. 张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.
VTK修炼之道60:体绘制_体绘制管线图形渲染管线相关推荐
- VTK修炼之道63:纹理映射体绘制_二维纹理映射
1.纹理映射体绘制 基于软件实现的光线投影体绘制算法计算量非常大,不利于进行实时渲染.因此,目前体绘制经常使用图形硬件利用纹理映射来加速. 其主要原理是将三维体数据作为纹理装载入硬件缓存中,利用硬件来 ...
- VTK修炼之道64:纹理映射体绘制_三维纹理映射
1.三维纹理映射 目前市面上的能多先科都是支持三维纹理映射的.利用三维纹理映射,将体数据映射至一组与视图平面平行的多边形,避免了二维纹理映射方法中因为纹理图像的切换造成的瑕疵.VTK中三维纹理映射体绘 ...
- VTK修炼之道3_VTK体系结构2
上一篇博客主要介绍了VTK的构架以及Render Engine.接触过VTK的同学都知道,VTK主要有Pipeline和Render Engine两部分构成,这里详细介绍了Pipeline部分内容. ...
- VTK修炼之道70:体绘制讨论_光照阴影、VTKLODProp3D
1.光照与阴影 通过VTKVolumeProperty可以设置体绘制阴影效果(Shading).阴影效果主要受环境光系数.散射光系数.反射光系数和高光强度四个参数影响. vtkVolumeProper ...
- VTK修炼之道67:体绘制讨论_不透明度传输函数
1.vtkVolume vtkVolume类似于几何渲染中的vtkActor,用于表示渲染场景中的对象.除了存储基本变换信息(平移.旋转.缩放等),其内部还存储了两个重要对象.这两个对象分别是vtkA ...
- VTK修炼之道62:体绘制_固定点光线投影体绘制与GPU加速光线投影体绘制
1.固定点光线投影算法 vtkFixedPointVolumeRayCastMapper是一个较好的vtkVolumeRayCastMapper的替代者.该类能够实现基于Alpha合成的体绘制方法和最 ...
- VTK修炼之道69:体绘制讨论_颜色传输函数
1.颜色传输函数 颜色传输函数与不透明度传输函数的使用类似,二者的不同之处在于颜色传输函数是将一个标量值映射为颜色值.这个颜色值可以是RGB值,也可以是HSV值. VTK颜色传输函数采用VTKColo ...
- VTK修炼之道61:体绘制_光线投影+最大密度投影+等值面法
1.vtkVolumeMapper vtkVolumeMapper是所有体绘制Mapper类的虚基类,提供接口函数,并由其子类实现具体功能.该类的继承关系如下图所示: 应该掌握一些常用的体绘制类. 2 ...
- VTK修炼之道68:体绘制讨论_梯度不透明度传输函数
1.梯度不透明度函数 梯度不透明度函数是将梯度模值映射为一个不透明度乘子,从而增强过渡区域的显示效果. 该函数也是使用vtkPiecewiseFunction类.例如,在不同材料的临界区域,如空气到软 ...
最新文章
- https协议必须使用443端口吗_http、https、http2、websocket之间的关系
- [k8s] 第十章 DashBoard
- C++对象模型1——类对象的sizeof、static成员、对象模型、this指针
- mysql 导入mongodb_mysql数据库迁移导入到mongodb详细教程
- 使用Xpath+多进程爬取诗词名句网的史书典籍类所有文章。update~
- 手动用hibernate-validator校验入参
- jQuery动画高级用法(上)——详解animation中的.queue()函数
- 如何使用Swift Playgrounds制作东西
- ehcache使用_Java 程序员如何使用 Shiro 框架
- Atitit mysql insert perf enhance 批量插入数据库性能 目录 1.1. 案一:使用ignore关键字	1 2. 异步插入	2 2.1. 其它关键:DELAYED 做为
- Atitit mybatis快速开发 的sql api接口
- 北风网66jquery
- 深度学习-模型预测(论文笔记)
- 三角函数之和差化积/积化和差/倍角公式(汇总)
- 【云流送技术】为手办行业可以带来哪些变革
- html 滑动拼图验证,vue登录滑动拼图验证
- ちょっとした難しい言葉まとめ③
- 坐在宝座上圣洁羔羊(儿童诗班)
- 在项目中使用Liquibase
- vue中实现汉字转化拼音