VTK—体绘制初步理解

VTK—体绘制


VTK主要提供了三种体绘制技术,除了光线投射法外,还有二维纹理映射和基于VolumePro硬件辅助的体绘制。

光线投射法是一种基于图像空间扫描的,生成高质量图像的典型的体绘制算法,基本思想是从图像平面的每个像素都沿着视线方向发出一条射线,此射线穿过体数据集,按一定步长进行采样,由内插计算每个采样点的颜色值和不透明度,然后由前向后或由后向前逐点计算累计的颜色值 和不透明度值,直至光线完全被吸收或穿过物体。该方法能很好地反映物质边界的变化,使用Phong模型,引入镜面反射、漫反射和环境反射能得到很好的光照 效果,在医学上可将各组织器官的性质属性、形状特征及相互之间的层次关系表现出来,从而丰富了图像的信息。

二维纹理映射与光线投射法不同,它是基 于物体空间扫描的,也就是对物体空间的数据点加以处理,计算每个数据点对屏幕像素的贡献并加以合成,形成最终的图像。它的绘制速度比光线投射法快上 5~10倍,但是成像质量远不及采用三线性插值的光线投射法精确,当视角改变时还会产生伪迹。

基于VolumePro硬件辅助的体绘制方法,成像质量虽然不及光线投射法,但是要比二维纹理映射好。利用VolumePro硬件支持的体绘制速度是最快的,一般每秒至少20帧画面,但目前只支持平行投影且价格昂贵。

每种技术各有其优点和缺点,开发人员应该根据实际需要进行选择。就目前看来,VTK中的光线投射法是应用最多的。这是因为不仅它的成像质量是最好的,而且 随 着计算机技术的发展和算法的不断改进,其绘制能力也在不断提高。二维纹理映射受限于其成像质量和图形硬件,VolumePro更是由于其价格原因使用较 少。


下面说一下Ray Casting 体绘制算法 :


The four basic steps of volume ray casting: (1) Ray Casting (2) Sampling (3) Shading (4) Compositing.


In its basic form, the volume ray casting algorithm comprises four steps:
Ray casting. For each pixel of the final image, a ray of sight is shot ("cast") through the volume. At this stage it is useful to consider the volume being touched and enclosed within a bounding primitive, a simple geometric object — usually a cuboid — that is used to intersect the ray of sight and the volume.
Sampling. Along the part of the ray of sight that lies within the volume, equidistant sampling pointssamples are selected. As in general the volume is not aligned with the ray of sight, sampling points usually will be located in between voxels. Because of that, it is necessary to trilinearly interpololate the values of the samples from its surrounding voxels. or
Shading. For each sampling point, the gradient is computed. These represent the orientation of local surfaces within the volume. The samples are then shaded, i. e. coloured and lighted, according to their surface orientation and the source of light in the scene.
Compositing. After all sampling points have been shaded, they are composited along the ray of sight, resulting in the final colour value for the pixel that is currently being processed. The composition is derived directly from the rendering equation and is similar to blending acetate sheets on an overhead projector. It works back-to-front, i. e. computation starts with the sample farthest from the viewer and ends with the one nearest to him. This work flow direction ensures that masked parts of the volume do not affect the resulting pixel.
光线投射方法是基于图像序列的直接体绘制算法。从图像的每一个像素,沿固定方向(通常是视线方向)发射一条光线,光线穿越整个图像序列,并在这个过程中,对图像序列进行采样获取颜色信息,同时依据光线吸收模型将颜色值进行累加,直至光线穿越整个图像序列,最后得到的颜色值就是渲染图像的颜色。

在VTK中光线投射的实现流程如下:
1 重建流程

和面绘制类似,首先利用vtkDICOMImageReader将位于同一目录下的DICOM格式的CT断层图片读入,然后根据骨骼和皮肤的不同灰度值进行分类,用vtkPiecewiseFunction对骨骼和皮肤赋予不同的不透明度值,用vtkColorTransferFunction对骨骼和皮肤赋以不同的颜色。vtkFixedPointVolumeRayCastMapper对三维数据进行光线投射算法的计算,从而获得二维投影中每个像素点的颜色值,然后映射到vtkVolume代表的三维几何实体。通过vtkVolumeProperty对vtkVolume对象进行属性设置。最后将volume加人到vtkRenderer中,通过vtkRenderWindow进行显示,通过vt.kRenderWindowInteractor处理用户的交互操作。

2 基于光线投射算法的体绘制的主要实现过程

(1)建立一个vtkDICOMImageReader读取对象,通过其SetDirectoryName设定DICOM CT断层文件目录,调用Update方法将数据读入。

(2)对骨骼和皮肤赋以不同的不透明度值。根据本文采用的数据源,将骨骼的灰度阈值设定为1300,皮肤的灰度阈值设定为750。建立不透明度函数的对象vtkPiecewiseFunction,通过其AddPoint方法确定不透明函数的拐点以及其对应的不透明度,将骨骼的不透明度设定为1.0(即完全不透明),将皮肤的不透明度设定为(100.0一RaySkinTransparency)/100,这里RaySkinTransparency被设定为50。

(3)建立色彩传递函数对象vtkColorTransferFunction,通过其AddRGBPoint方法对骨骼和皮肤赋以不同的颜色。我们把骨骼设定为白色(1,1,1),把皮肤设定为红色(1,0,0)。

(4)建立vtkFixedPointVolumeRayCastMapper对象对三维数据进行体绘制运算。利用其GetOutput方法从vtkDICOMImageReader读取对象中获得数据。

(5)建立vtkVolume对象,通过其SetMapper方法利用流水线获得vtkFixedPointVolumeRayCastMapper的输出。

(6)建立绘制者vtkRenderer和绘制窗口vtkRenderWindow,通过vtkRenderer的AddVolume方法将vtkVolume对象添加,利用vtkRenderWindow的AddRenderer方法将建立的vtkRenderer对象添加到绘制窗口中,再调用Render方法进行绘制。

(7)建立vtkRenderWindowlnteractor对象,通过其SetRenderWindow方法将vtkRenderWindow设定为交互的绘制窗口,使用户可以对绘制结果进行交互操作。

PS:在这一段需要说一个问题 就是一般CT或MRI 得到的dcm文件类型是short或char(我也不确定)但是在VTK中vtkVolumeRayCastMapper的map类型必须是UnsignedChar/UnsignedShort 因此需要通过vtkImageShiftScale()做变换。
// 下面是我程序的一个片段,提到这一点 希望对大家有用(我是通过ITK gdcmIO读的dcm文件//序列 要显示必须借助VTK 因此有connector)
vtkImageShiftScale *scale=vtkImageShiftScale::New();
scale->SetInput(connector->GetOutput());
scale->SetOutputScalarTypeToUnsignedChar();
scale->Update();

vtkVolumeRayCastMapper *volumeMapper = vtkVolumeRayCastMapper::New();
volumeMapper->AutoAdjustSampleDistancesOff();
volumeMapper->SetInput(scale->GetOutput());


最后附上一段关于体绘制的理解:

M.Levoy 在文章 “Display of surfaces from volume data”( 文献【 14 】 ) 中提到 “volume rendering describes a wide range of techniques for generating images from three-dimensional scalar data” 。

体绘制的核心在于 “ 展示体细节!而不是表面细节 ” 。我给出的定义是:依据三维体数据,将所有体细节同时展现在二维图片上的技术,称之为体绘制技术。利用体绘制技术,可以在一幅图像中显示多种物质的综合分布情况,并 且可以通过不透明度的控制,反应等值面的情况。

例如, CT 图片中展示 的是人体的肌肉和骨骼信息,而不是表面信息(那是照片)。所以理解体绘制和面绘制技术的区别的 , 一个很直观 的比喻是:普通照相机照出的相片和 CT 仪器拍出的 CT 照片,虽然 都是二维图片,但是展现的对象是不同的!

体绘制的目标是在一副图片上展示 空间体细节。举例而言,你面前有一间房子,房子中有家具、家电,站在房子外面只能看到外部形状,无法观察到房子的布局或者房子中的物 体;假设房子和房子中的物体都是半透明的,这样你就可以同时查看到所有的细节。这就是体绘制所要达到的效果。

尽管光照模型通常用于面绘制,但是并不意味着体绘制技术中不能使用光照模型。实际上 , 体绘制技术 以物体对光的吸收原理为理论基础,在实现方式上,最终要基于透明度合成计算模型。此外,经典的光照模型,例如 phong 模型, cook-torrance 模型都可以 做为体绘制技术的补充,完善体绘制效果,增强真实感。

posted on 2012-10-18 12:57  |残阳|露  阅读(3638)  评论(0编辑  收藏  举报

导航