首先是安装VTK,具体过程我就不叙述了,网上有很多安装教程
接下来是运行例子:
#include "stdafx.h"
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL)
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkStructuredPoints.h>
#include <vtkImageReader.h>
#include <vtkVolumeRayCastCompositeFunction.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkVolumeRayCastMapper.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVolumeProperty.h>
#include <vtkAxesActor.h>
#include <vtkImageShiftScale.h>
#include <vtkImageCast.h>
#include <vtkFixedPointVolumeRayCastMapper.h>
#include <vtkDICOMImageReader.h>
#include <vtkContourFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkPolyDataMapper.h>
#include <vtkOutlineFilter.h>
#include <vtkCamera.h>
#include "vtkInteractorStyleTrackballCamera.h"
void main()
{
vtkRenderer *aRenderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(aRenderer);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
vtkDICOMImageReader *v = vtkDICOMImageReader::New();//vtkDicomImageReader用于读取医学DICOM图像
v->SetDataByteOrderToLittleEndian();//设置为小端字节序
v->SetDirectoryName("D:\\project_vtk\\vtk_rebuilding_CT\\data");//文件目录路径
v->SetDataSpacing(3.2, 3.2, 1.5);//设置数据间距
//已知500对应病人的皮肤,抽取值为500的等值面。然后通过vtkPolyDataNormals在面上产生法线
vtkContourFilter *skinExtractor = vtkContourFilter::New();//过滤器vtkContourFilter用于从数据中抽取一系列等值面
skinExtractor->SetInputConnection(v->GetOutputPort());
skinExtractor->SetValue(0, 500);//对抽取等值面进行设置,表示从第0个抽取值开始,设为500
vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New();//在面上产生法线,使渲染过程中的表面着色光滑些
skinNormals->SetInputConnection(skinExtractor->GetOutputPort());
skinNormals->SetFeatureAngle(60.0);//设置特征角度
vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New();
skinMapper->SetInputConnection(skinNormals->GetOutputPort());
skinMapper->ScalarVisibilityOff();
vtkActor *skin = vtkActor::New();
skin->SetMapper(skinMapper);
//产生一个围绕着数据的框架
vtkOutlineFilter *outlineData = vtkOutlineFilter::New();
outlineData->SetInputConnection(v->GetOutputPort());
vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New();
mapOutline->SetInputConnection(outlineData->GetOutputPort());
vtkActor *outline = vtkActor::New();
outline->SetMapper(mapOutline);
outline->GetProperty()->SetColor(0, 0, 0);
//新建相机实例
vtkCamera *aCamera = vtkCamera::New();
aCamera->SetViewUp(2, -1, -1); //取得摄像机方向0,0,-1 0,-1,-1 2,-1,-1
aCamera->SetPosition(0, 1, 0); //光源位置
aCamera->SetFocalPoint(0, 0, 0); //取焦点坐标
aRenderer->AddActor(outline);
aRenderer->AddActor(skin);
aRenderer->SetActiveCamera(aCamera);
aRenderer->ResetCamera();
aCamera->Dolly(1.5);//将相机靠近焦点,以放大图像
aRenderer->SetBackground(1, 1, 1);//设置背景为白色
renWin->SetSize(600, 500);
//由于Dolly()方法移动了相机,所以要重设相机的剪切范围
aRenderer->ResetCameraClippingRange();
//设置交互方式
//vtkInteractorStyleTrackballCamera *style =vtkInteractorStyleTrackballCamera::New();
//iren->SetInteractorStyle(style);
iren->Initialize();
iren->Start();
v->Delete();
skinExtractor->Delete();
skinNormals->Delete();
skinMapper->Delete();
skin->Delete();
outlineData->Delete();
mapOutline->Delete();
outline->Delete();
aCamera->Delete();
iren->Delete();
renWin->Delete();
aRenderer->Delete();
}
其中
aCamera->SetViewUp(2, -1, -1); //取得摄像机方向0,0,-1 0,-1,-1 2,-1,-1
这是设置不同的视角:
aCamera->SetViewUp(0, 0, -1);
结果:
aCamera->SetViewUp(0, -1, -1);
结果:
aCamera->SetViewUp(2, -1, -1);
结果:
可以看出需要设置不同的角度才能看到不同的切面图,接下来希望可以加入交互操作,只要用鼠标旋转一下窗口就可以看到重建后的医学图片的不同视角
至于数据我是在github上下载的,大家也可以在github中找到关于医学图像的数据