#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkPiecewiseFunction.h"
#include "vtkColorTransferFunction.h"
#include "vtkVolumeProperty.h"
#include "vtkVolumeRayCastIsosurfaceFunction.h"
#include "vtkVolumeRayCastCompositeFunction.h"
#include "vtkVolumeRayCastMapper.h"
#include "vtkVolume.h"
#include "vtkImageCast.h"
#include "vtkBMPReader.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkVolume16Reader.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkOutlineFilter.h"
#include "vtkCamera.h"
#include "vtkProperty.h"
#include "vtkPolyDataNormals.h"
#include "vtkContourFilter.h"
#include "vtkMarchingCubes.h"
#include "vtkDecimatePro.h"
#include "vtkStripper.h"
#include "vtkImageShrink3D.h"
#include "vtkSmoothPolyDataFilter.h"
#include "vtkTriangleFilter.h"
#include "vtkFeatureEdges.h"
#include "vtkPolyDataWriter.h"
#include "vtkImageData.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include <vtkPolyDataConnectivityFilter.h>
#include <stdlib.h>
#include <vtkSmartPointer.h>
int main()
{
vtkRenderer *aRenderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(aRenderer);
///
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
vtkBMPReader *reader = vtkBMPReader::New();
reader->SetDataExtent(0, 512, 0, 512, 1, 80);
reader->SetFilePrefix("G:\\spine\\原始掩膜图\\IM");
reader->SetFilePattern("%s%d.bmp");
reader->SetDataSpacing(1, 1, 1);//像素间的间隔
reader->SetAllow8BitBMP(16);//很重要
reader->Update();
//reader->Allow8BitBMPOff();
/************************************************************************/
//---------------------------二次重采样(降采样)-------------------------
/*
重采样是按照图像的像素位置和间距重新采样,然后重新构成新图像。重采样
会改变图像的维数,分为降采样和增采样,vtkImageShrink3D用来实现降采样操作,
vtkImageMagnify用来实现升采样操作。
*/
vtkImageShrink3D *shrink = vtkImageShrink3D::New();
shrink->SetInput((vtkDataObject *)reader->GetOutput());
//采样因子
/*
对读入的数据采用vtkImageShrink3D进行subsampling(二次抽样),可以使加速
读入数据。一般使用方法:SetShrinkFactors(3,3,3)和AveragingOn。
SetShrinkFactors方法 定义了x,y,z 抽样精密度 如果都是0,没必要用这个函数。
如果subsampling得值过大,那么rendering的结果较差。可以使用一些平滑函数
进行优化,减少数据的梯度感和粗糙感。如高斯平滑函数。
*/
shrink->SetShrinkFactors(4, 4, 1);
//shrink->AveragingOn();
//----------------------------------------------------------------------------
//--------------------------提取等值面-----------------------------------------
/*
在MC方法中, 假定原始数据是离散的三维空间规则数据场。用于医疗诊断的断层
扫描仪( CT ) 及核磁共振仪( MRI ) 等产生的图象均属于这一类型。为了在这一
数据场中构造等值面, 用户应先给出所求等值面的值, 设为C0。MC 方法首先找出
该等值面经过的体元的位置, 求出该体元内的等值面并计算出相关参数, 以便由
常用的图形软件包或图形硬件提供的面绘制功能绘制出等值面。由于这一方法是
逐个体元依次处理的, 因此被称为Marching Cubes方法。
参考网址:http://blog.csdn.net/wp_veil/article/details/7047537
*/
vtkMarchingCubes *skinExtractor = vtkMarchingCubes::New();
skinExtractor->SetInputConnection(shrink->GetOutputPort());
//计算体素的等值面 可以提取多个等值面
//最主要的提取工作就在这里进行,等值面的值取的好,模型效果就好
//等值面的值取的越大,留得细节就越少
//skinExtractor->GenerateValues(3, 175, 1000);
skinExtractor->SetValue(0, 175);
//----------------------------------------------------------------------------
//-----------------------减少模型的三角面片-----------------------------------
vtkDecimatePro *deci = vtkDecimatePro::New();
deci->SetInputConnection(skinExtractor->GetOutputPort());
//将原先的三角面片减少到原来的百分之三十
deci->SetTargetReduction(0.3);
//----------------------------------------------------------------------------
//---------------------平滑生成的模型,使之看起来更精细------------------------
vtkSmoothPolyDataFilter *smooth = vtkSmoothPolyDataFilter::New();
smooth->SetInputConnection(deci->GetOutputPort());
//设置Laplace平滑的迭代次数,平滑次数越多,耗费时间越长
smooth->SetNumberOfIterations(100);
//----------------------------------------------------------------------------
//---------------------------计算模型等值面的法向量----------------------------
vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New();
skinNormals->SetInputConnection(smooth->GetOutputPort());
skinNormals->SetFeatureAngle(60.0);
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
/*
用 Marching Cubes 算法对所读取的数据进行处理了首先利用vtkMarchingCubes 类来提
取出某一CT 值的等值面但这时的等值面其实仍只是一些三角面片还必须由vtkStripper类
将其拼接起来形成连续的等值面这样就把读取的原始数据经过处理转换为应用数据也即由
原始的点阵数据转换为多边形数据然后由vtkPolyDataMapper 将其映射为几何数据并将其
属性赋给窗口中代表它的演员将结果显示出来。
*/
vtkStripper *stripper = vtkStripper::New();
stripper->SetInput(skinNormals->GetOutput());
//----------------------------------------------------------------------------
//保存为VTK格式
/*vtkPolyDataWriter *wSP = vtkPolyDataWriter::New();
wSP->SetInput(connectivityFilter->GetOutput());
wSP->SetFileName("D:\\CT1\\骨盆.vtk");
wSP->Write();
wSP->Delete();*/
/************************************************************************/
/* 显示相关,可视化模型 */
/************************************************************************/
vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New();
skinMapper->SetInput(stripper->GetOutput());
skinMapper->ScalarVisibilityOff();
vtkActor *skin = vtkActor::New();
skin->SetMapper(skinMapper);
skin->GetProperty()->SetDiffuseColor(1, 0.49, 0.25);
skin->GetProperty()->SetSpecular(.3);
skin->GetProperty()->SetSpecularPower(20);
vtkCamera *aCamera = vtkCamera::New();
aCamera->SetViewUp(0, 0, -1);
aCamera->SetPosition(0, 1, 0);
aCamera->SetFocalPoint(0, 0, 0);
aCamera->ComputeViewPlaneNormal();
aRenderer->AddActor(skin);
aRenderer->SetActiveCamera(aCamera);
aRenderer->ResetCamera();
aCamera->Dolly(1.5);
aRenderer->SetBackground(1, 1, 1);
renWin->SetSize(640, 480);
aRenderer->ResetCameraClippingRange();
iren->Initialize();
iren->Start();
shrink->Delete();
smooth->Delete();
deci->Delete();
stripper->Delete();
skinExtractor->Delete();
skinNormals->Delete();
skinMapper->Delete();
skin->Delete();
aCamera->Delete();
iren->Delete();
renWin->Delete();
aRenderer->Delete();
reader->Delete();
return EXIT_SUCCESS;
}
VTK利用BMP图像序列生成表面模型
最新推荐文章于 2022-12-27 16:07:44 发布