0 前言
三维重建主要有面绘制和体绘制两种方法,其中面绘制又包含轮廓连接法、移动立方体法等;而绘制的主要方法为光线投射法。本文简要对这些方法的具体实现做一个总结。
实验环境:Win8.1 + VTK-6.2.0 + Qt5.2.1
1 面绘制
根据参考资料[12]的说明,面绘制分为体素级重建和切片级重建两大类型,由于后者效果不理想,现在主要使用的是前者,例如Marching Cubes方法。
1.1 vtkMarchingCubes
具体实现见参考资料[1][5]。由于参考资料[1]是Python版本,而参资料[5]是C++版本,后者在使用指针变量时没有很好的处理内存释放的问题,并且版本过旧。鉴于此,这里对参考资料[5]进行修改,除了解决内存管理的问题外,主要使其适应6.2.0版本的VTK:
#define vtkRenderingCore_AUTOINIT 4(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingFreeTypeOpenGL,vtkRenderingOpenGL)
#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL)
#include "vtkVolume16Reader.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkMarchingCubes.h"
#include "vtkStripper.h"
#include "vtkActor.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkCamera.h"
#include "vtkBoxWidget.h"
#include "vtkSmartPointer.h"
#include "vtkTriangleFilter.h"
#include "vtkMassProperties.h"
int main( int argc, char *argv[] )
{
//读取二维切片数据序列
vtkSmartPointer< vtkVolume16Reader >reader =
vtkSmartPointer< vtkVolume16Reader >::New();
reader->SetDataDimensions(64, 64); //设置像素
reader->SetDataByteOrderToLittleEndian();
reader->SetFilePrefix("E:\\VTK\\vtkdata-5.10.1\\Data\\headsq\\quarter");//设置读取路径
reader->SetImageRange(1, 93);
reader->SetDataSpacing(3.2, 3.2, 1.5);
reader->Update();
//抽取等值面为骨头的信息
vtkSmartPointer< vtkMarchingCubes > boneExtractor =
vtkSmartPointer< vtkMarchingCubes >::New();
boneExtractor->SetInputConnection( reader->GetOutputPort() );
boneExtractor->SetValue(0, 500); //设置提取的等值信息
boneExtractor->Update();
//剔除旧的或废除的数据单元,提高绘制速度(可略去这一步)
vtkSmartPointer< vtkStripper > boneStripper =
vtkSmartPointer< vtkStripper >::New(); //三角带连接
boneStripper->SetInputConnection( boneExtractor->GetOutputPort());
boneStripper->Update();
//建立映射
vtkSmartPointer< vtkPolyDataMapper > boneMapper =
vtkSmartPointer< vtkPolyDataMapper >::New();
boneMapper->SetInputData(boneStripper->GetOutput());
//建立角色
vtkSmartPointer< vtkActor > bone =
vtkSmartPointer< vtkActor >::New();
bone->SetMapper(boneMapper);
bone->GetProperty()->SetDiffuseColor(.1, .94, .52);
bone->GetProperty()->SetSpecular( .3 );
bone->GetProperty()->SetSpecularPower( 20 );
//定义绘制器
vtkSmartPointer< vtkRenderer > aRenderer =
vtkSmartPointer< vtkRenderer >::New();
//定义绘制窗口
vtkSmartPointer< vtkRenderWindow > renWin =
vtkSmartPointer< vtkRenderWindow >::New();
renWin->AddRenderer( aRenderer );
//定义窗口交互器
vtkSmartPointer< vtkRenderWindowInteractor > iren =
vtkSmartPointer< vtkRenderWindowInteractor >::New();
iren->SetRenderWindow( renWin );
//创建一个camera
vtkSmartPointer< vtkCamera > aCamera =
vtkSmartPointer< vtkCamera >::New();
aCamera->SetViewUp(0,0,-1);
aCamera->SetPosition(0,1,0);
aCamera->SetFocalPoint(0,0,0);
aRenderer->AddActor( bone );
aRenderer->SetActiveCamera( aCamera );
aRenderer->ResetCamera();
aCamera->Dolly(1.5);
aRenderer->SetBackground(0,0,0);
aRenderer->ResetCameraClippingRange();
iren->Initialize();
iren->Start();
return 0;
}
1.2 vtkContourFilter
具体见参考资料[6]。
2 体绘制
根据参考资料[8][9]的说明,VTK中的三维体绘制方法包括三种:a)光线投射法;b)三维纹理映射法;c)基于硬件的VolumePro体绘制方法。
其中,光线投射法又包含3种实现方法:
vtkVolumeRayCastIsosurfaceFunction // 使用等值面进行体绘制
vtkVolumeRayCastMIPFunction // 使用最大密度投射法进行体绘制
vtkVolumeRayCastCompositeFunction // 使用alpha合成法进行体绘制
参考资料
[5]VTK 面绘制
[7]VTK中的体绘制方法
[8]【VTK】三维体绘制方法
[9]VTK体绘制方法介绍
[10]基于VTK与Qt的体绘制程序
[11]VTK—体绘制初步理解
[12]吴建帅. 基于统计学的三维重建体积计算方法研究. 内蒙古科技大学, 2014年