第32卷第6期武汉理工大学学报#信息与管理工程版Vo.l32No.62010年12月JOURNALOFWUT(INFORMATION&MANAGEMENTENGINEERING)Dec.2010文章编号:1007-144X(2010)06-0918-04文献标志码:A基于VTK的恒牙三维重建冷栋1,周廷美1,杨俊2(1.武汉理工大学机电工程学院,湖北武汉430070;2.武汉大学口腔医院,湖北武汉430079)摘要:三维重建是计算机图形学的一个重要研究领域。针对牙体形态的测量问题,研究了恒牙的三维重建,采用面绘制的方法,构建了恒牙的三维可视化模型。借助三维可视化工具包VTK的强大功能,在VS2008的编程环境中,使用轮廓拼接法,完成了单颗恒牙的三维重建。关键词:三维重建;VTK;轮廓拼接法中图分类号:TP391.7DO:I10.3963/.jissn.1007-144X.2010.06.016近年来,具有无损、空间分辨率高(达到微米数量级)等优点的显微CT技术逐渐应用于实验牙髓病学领域。其以优质的断层图像,为准确真实的三维重建提供了保证,使得在三维重建图形上进行定点测量成为可能,被誉为牙髓病学研究/金标准0。三维重建是计算机可视化的重要研究领域之一[1]。国外学者在这方面已经做了许多研究,LORENSEN等[2]提出了MC(marchingcube)算法;NIELSON等[3]提出了MT(marchingtetrahedra)算法;LIN[4]采用从轮廓出发的B样条插值重建算法,得到了整体光滑的表面。国内也有许多学者作了很多有益的探索。西北工业大学谢红研究了用于自由曲面的基于面片拼接的三角曲面模型重建算法[5]。三维重建的方法一般划分为面绘制和体绘制两大类。面绘制因绘制速度快于体绘制而在实际应用中采用较广。1VTK简介VTK(visualizationtoolkit)是一个用于科学计算的可视化工具包,可用于医学图像可视化的C++类库,在处理CT扫描数据方面具有强大的功能[6-8]。VTK在可视化算法、可移植性、可扩充性等方面都有着独特之处,其主要采用管道路径体系结构,在流水线的体系结构上设置了面绘制和体绘制两种绘制流程,并分别采用相应的可视化算法。VTK最显著的特点就是管道化,即一个VTK程序就是一个完整的渲染管道,渲染管道的前段称为可视化模型管道,由数据源、读取器和过滤器等部分组成。如在制作某些渲染节目时,渲染管道的后段为图形模型管道,由演员、光线、照相机、属性、映射器、绘制器和绘制窗口等组成,利用渲染管道VTK可完成点线面的三维重建[9]。由于VTK功能强大,目前已经广泛应用于可视化的各个领域。加州大学伯克利分校利用VTK开发了一个系统进行医学领域研究的实时仿真及可视化系统;斯坦福大学利用VTK开发了一个用于教学的虚拟动物资源库,学生能通过该资源库系统去探索这些动物的内部结构,从而取代传统的动物实验[10]。在国内,VTK则被广泛应用于医学领域的CT三维重建以及模拟手术。2恒牙的三维重建2.1恒牙三维重建的流程及体数据的获取采用VTK进行恒牙三维重建的流程如图1图1采用VTK进行恒牙三维重建的流程图收稿日期:2010-09-09.作者简介:冷栋(1985-),男,湖北武汉人,武汉理工大学机电工程学院硕士研究生.第32卷第6期冷栋,等:基于VTK的恒牙三维重建919所示。重建的第一步是读取断层图片数据,并将其转换为开发工具VTK所支持的一种数据表达形式;然后根据其物理结构建立起相应的模型(CT数据建立的是比较抽象的等值面模型);最后将物理组件与抽象的模型结合在一起,建立CT数据的可视化界面,以帮助用户正确理解图像数据。待处理的是结构点阵数据,其拓扑和几何都是隐含的,因此只需要知道数据的维数、数据源和数据空间,并输入读取数据对象的CT数据的一些参数,如图片之间的间距、图片上像素之间的间距以及所读取图片的起始片,如从第1张图片到第100张图片等。读者便可以利用VTK中的vtk-BMPReader很方便地读取CT图片数据,读取数据的代码如下所示:vtkBMPReader*bmpreader=vtkBMPRead-er::New();//创建一个读取对象。bmpreader-SetFilePrefix(E:\\tooth1\\a);//设置读取路径,文件名为a。bmpreader-SetFilePattern(%s%d.bmp);//系列断层图片后缀为.bmp。bmpreader-SetDataScalarTypeToUnsigned-Char();bmpreader-SetDataByteOrderToLittleEndian();bmpreader-Allow8BitBMPOn();//读取8位的系列断层BMP图片。bmpreader-SetFileNameSliceOffset(0.037);//系列CT断层图片层间距为0.037。bmpreader-SetFileNameSliceSpacing(1);//连续读取系列断层图片。bmpreader-SetNumberOfScalarComponents(3);//设置为三维体数据。bmpreader-SetDataSpacing(3.2,3.2,3.2);bmpreader-SetDataOrigin(0.0,0.0,0.0);//设置原点位置在原点。bmpreader-SetDataExtent(0,900,0,900,1,864);//设置阈值与图片起始序号。bmpreader-Update()。2.2体数据预处理由于CT断层图片中包含了噪声信号,这些噪声信号在生成体数据过程中得以保留,从而严重影响了三维重建效果。体数据中噪声信号影响反求建模得到的表面模型质量,因此必须对体数据进行数据处理,以使表面模型变得光滑、真实[11]。笔者采用高斯滤波器去除体数据噪声。高斯滤波实质上是一种信号滤波器,其用途是信号的平滑处理。用于后期应用的数字图像,其噪声是最大的问题,由于误差会累计传递等原因,前期的处理不当往往会造成后期图像的失真,因此很多时候需要用高斯滤波器对图像进行处理,以得到信噪比SNR较高的图像(反映真实信号)。与此相关的高斯拉普拉斯变换,是为了得到较好的图像边缘,即先对图像做高斯平滑滤波,剔除噪声,然后求二阶导数,用二阶导数的过零点确定边缘。滤波器通过建立数学模型,将图像数据进行能量转化,能量低的就会被排除掉,噪声属于低能量部分从而被剔除。编程运算是一个模板运算,以图像的八连通区域为例,中间点的像素值就等于八连通区的像素值的均值,这样可达到平滑的效果,采用高斯滤波器,系统函数是平滑的,从而可避免振铃现象。高斯模板是通过采样二维高斯函数得到的,如式(1)所示:122G(x,y)=exp-x+y=2PR22R211exp-x2exp-y2(1)222PR2R2PR2PR高斯滤波器是最常用的低通平滑滤波器,然而在高斯平滑过程中,去除高频噪声的同时也会对图像边沿产生影响,丢失边缘的某些细节,因此标准差R不能太大,也不能太小。太大会破坏图像的真实性,计算量变大,影响重建速度;太小则无法去掉体数据中的大量噪声信号。同时由于体数据是三维的,因而需要设置3个方向的标准差。经过多次实验,R=1.5是比较合适的。高斯滤波代码如下:vtkImageGaussianSmooth*smooth=vtkIm-ageGaussianSmooth::New();smooth-SetInput((vtkDataObject*)bm-preader-GetOutput());//读入体数据。smooth-SetDmiensionality(3);//设置为三维高斯滤波。smooth-SetStandardDeviations(1.5,1.5,1.5);//设置3个方向的标准差均为1.5。2.3表面重构2.3.1轮廓拼接法重建在计算机图形学领域,面绘制算法发展到今天已经相当成熟。该算法将感兴趣的部分以等值面的方式抽取出来,通过变换光照效果生成高质920武汉理工大学学报#信息与管理工程版2010年12月量的三维图像,并可以方便地对其进行观察和分析。面绘制方法实质是在等值面抽取过程中设置阈值,再根据阈值对体数据逐个处理,生成数据量极大的三角面片,然后利用三角面片构造物体的表面模型。轮廓拼接法是最早用于进行表面绘制的方法,它首先将每张图片的轮廓提取出来,然后以提取后的轮廓点为顶点,并以三角形的形式将每张图片的轮廓线连接起来,从而拼接出物体表面[12]。该方法较适用于断层扫描数据且断层间等值面变化较小或大致相似的情况。2.3.2轮廓拼接法算法轮廓拼接法建模依照给定的阈值从断层图像中逐一提取闭合的边界轮廓线,然后将相邻切片的等值线相连接,从而形成曲面网格逼近等值表面。这个过程对相邻断层图像而言是独立的。轮廓拼接法最为关键的一步是在相邻断层图像之间按照一定规则,建立插值点对。在图2中,假设相邻两断层图像中对应轮廓特征点集分别为:A={Aj0[j[m}和B={Bi0[i[n}其中:m\3,n\3,且轮廓线上的点按逆时针顺排列;A为上轮廓Ca的点集;B为下轮廓Cb的点集;m和n相差不应太大。图2在相邻的切片间建立插值点对通过对应轮廓间建立插值点对,绘制三角形面片,在轮廓Ca和轮廓Cb之间建立一个类圆柱表面。为了利用基本三角面片来构造实体的表面,采用如下方式进行拼接:首先,在轮廓Ca上选取一点Aj,令j=0,j+1=1,依次顺延,然后在轮廓Cb上选取与A0距离之和最短的两个点Bi、Bi+1,连接A0Bi、A0Bi+1、BiBi+1,构成一个基本三角面片(A0、Bi、Bi+1),再以Bi+1为起始点,在轮廓Ca上寻找除已经找到的点以外与之距离最短的点A1,分别连接3个点构成三角面片(A0、A1、Bi+1),接着以A1为起始点在轮廓Cb上寻找除已经找到的点以外与之距离最短的点,这样循环进行,直到对应轮廓上所有的点都被遍历过一遍。2.3.3轮廓拼接法代码轮廓拼接法代码如下:vtkContourFilter*skinExtractor=vtkContourF-ilter::New();//实例化一个对象。skinExtractor-SetInputConnection(bmpread-er-GetOutputPort());//读入体数据。skinExtractor-SetValue(0,100);//设置轮廓线提取阈值为100,以便提取断层图像轮廓线,进而得到轮廓点数据。vtkPolyDataNormals*skinNormals=vtkPoly-DataNormals::New();skinNormals-SetInputConnection(skinExtractor-GetOutputPort());//输入轮廓点数据,进行构造等值面。skinNormals-SetFeatureAngle(60.0)。2.4绘制与显示通过上面的程序代码,基本可以完成三维表面重建,三维重建结果显示的部分代码如下:vtkRenderer*aRenderer=vtkRenderer::New();//创建绘制者。vtkRenderWindow*renWin=vtkRenderWin-dow::New();//创建绘制窗口。renWin-AddRenderer(aRenderer);//将绘制者加入绘制窗口。vtkActor*skin=vtkActor::New();//创建演员。skin-SeMtapper(skinMapper);vtkRenderWindowInteractor*iren=vtkRende-rWindowInteractor::New();//创建交互对象,以便于交互操作,如鼠标、键盘等。iren-SetRenderWindow(renWin);vtkPolyDataMapper*skinMapper=vtkPolyDa-taMapper::New();//创建