VTK从分割好的体数据获取等值面的方法(MarchingCube)

vtk里面从分割好的体数据获取等值面的方法基本上都是基于MarchingCube的方法,有很多相关函数,一般从标记图像中获取等值面的方法为vtkDiscreteMarchingCubes。图像经过等值面提取后,会生成包含大量边的polyData,此时数据量很大且可能不够平滑,一般会对网络进行平滑和抽取,对应类:vtkWindowedSincPolyDataFilter,vtkDecimatePro。其中,vtkDecimatePro只能对三角片组成的网络处理,因此在进行抽取前,可以用vtkTriangleFilter对网络进行三角化。

一个等值面提取的程序如下:

#include <vtkSmartPointer.h>
#include "vtkCamera.h"
#include "vtkColorTransferFunction.h"
#include "vtkDICOMImageReader.h"
#include "vtkImageData.h"
#include "vtkPiecewiseFunction.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkVolume.h"
#include "vtkVolumeProperty.h"
#include "vtkSmartVolumeMapper.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include <vtkActor.h>
#include <vtkMarchingCubes.h>
#include <vtkStripper.h>
#include <vtkPolyDataMapper.h>
#include <vtkVolumeMapper.h>
#include <vtkDecimatePro.h>
#include <vtkPolyDataNormals.h>
#include <vtkSmoothPolyDataFilter.h>
#include <vtkTriangleFilter.h>
#include <vtkDataSetReader.h>
#include <vtkQuadricDecimation.h>
#include <vtkQuadricClustering.h>
#include <vtkImageMarchingCubes.h>
#include <vtkDiscreteMarchingCubes.h>
#include <vtkWindowedSincPolyDataFilter.h>


using namespace std;

int main()
{
	string DataPath = "E:\\数据集\\3Dircadb1\\3Dircadb1.8\\MASKS_DICOM\\liver";

	//Read Volume
	vtkSmartPointer<vtkDICOMImageReader> dicomReader = vtkSmartPointer<vtkDICOMImageReader>::New();
	dicomReader->SetDirectoryName(DataPath.c_str());
	dicomReader->Update();
	
	vtkSmartPointer<vtkImageData> LiverVolume = vtkSmartPointer<vtkImageData>::New();
	LiverVolume = dicomReader->GetOutput();

	vtkSmartPointer<vtkSmartVolumeMapper> LiverVolumeMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
	LiverVolumeMapper->SetInputConnection(dicomReader->GetOutputPort());

	//set volume property
	vtkSmartPointer<vtkColorTransferFunction> ColorTf = vtkSmartPointer<vtkColorTransferFunction>::New();
	ColorTf->AddRGBSegment(0, 0, 0, 0, 255, 1, 1, 1);

	vtkSmartPointer< vtkPiecewiseFunction> OpacityFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
	OpacityFun->AddPoint(0, 0);
	OpacityFun->AddPoint(255, 1);

	vtkSmartPointer<vtkVolumeProperty> VolumPro = vtkSmartPointer<vtkVolumeProperty>::New();
	VolumPro->SetColor(ColorTf);
	VolumPro->SetScalarOpacity(OpacityFun);
	VolumPro->SetInterpolationTypeToLinear();

	vtkSmartPointer<vtkVolume> LiverVolumActor = vtkSmartPointer<vtkVolume>::New();
	LiverVolumActor->SetMapper(LiverVolumeMapper);
	LiverVolumActor->SetProperty(VolumPro);
	
	//get mesh
	vtkSmartPointer<vtkDiscreteMarchingCubes> ImageMC = vtkSmartPointer<vtkDiscreteMarchingCubes>::New();
	ImageMC->SetInputConnection(dicomReader->GetOutputPort());
	ImageMC->SetValue(0, 255);
	ImageMC->Update();

	vtkSmartPointer<vtkWindowedSincPolyDataFilter> DataSmooth = vtkSmartPointer<vtkWindowedSincPolyDataFilter>::New();
	DataSmooth->SetInputConnection(ImageMC->GetOutputPort());
	DataSmooth->SetFeatureAngle(120);
	DataSmooth->SetNumberOfIterations(55);
	DataSmooth->SetPassBand(0.001);
	DataSmooth->BoundarySmoothingOff();
	DataSmooth->FeatureEdgeSmoothingOff();
	DataSmooth->NonManifoldSmoothingOn();
	DataSmooth->NormalizeCoordinatesOn();
	DataSmooth->Update();
	
	vtkSmartPointer<vtkTriangleFilter> LiverTriangle = vtkSmartPointer<vtkTriangleFilter>::New();
	LiverTriangle->SetInputConnection(DataSmooth->GetOutputPort());

	//reduce mesh
	vtkSmartPointer<vtkDecimatePro> ReduceMesh = vtkSmartPointer<vtkDecimatePro>::New();
	ReduceMesh->SetInputConnection(LiverTriangle->GetOutputPort());
	ReduceMesh->SetTargetReduction(0.95);
	ReduceMesh->PreserveTopologyOn();

	vtkSmartPointer<vtkWindowedSincPolyDataFilter> LiverSmooth = vtkSmartPointer<vtkWindowedSincPolyDataFilter>::New();
	LiverSmooth->SetInputConnection(ReduceMesh->GetOutputPort());
	LiverSmooth->SetNumberOfIterations(10);
	LiverSmooth->SetFeatureAngle(120);

	vtkSmartPointer<vtkDecimatePro> ReduceMesh2 = vtkSmartPointer<vtkDecimatePro>::New();
	ReduceMesh2->SetInputConnection(LiverSmooth->GetOutputPort());
	ReduceMesh2->SetTargetReduction(0.3);
	ReduceMesh2->PreserveTopologyOn();

	vtkSmartPointer<vtkWindowedSincPolyDataFilter> LiverSmooth2 = vtkSmartPointer<vtkWindowedSincPolyDataFilter>::New();
	LiverSmooth2->SetInputConnection(ReduceMesh->GetOutputPort());
	LiverSmooth2->SetNumberOfIterations(15);
	LiverSmooth2->SetFeatureAngle(120);

	vtkSmartPointer<vtkPolyDataNormals> LiverNormal = vtkSmartPointer<vtkPolyDataNormals>::New();
	LiverNormal->SetInputConnection(LiverSmooth2->GetOutputPort());

	vtkSmartPointer<vtkPolyDataMapper> LiverPolyMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	LiverPolyMapper->SetInputConnection(LiverNormal->GetOutputPort());

	vtkSmartPointer<vtkActor> LiverPolyAct = vtkSmartPointer<vtkActor>::New();
	LiverPolyAct->SetMapper(LiverPolyMapper);
	LiverPolyAct->GetProperty()->SetColor(0.93, 0.9, 0.6);
	LiverPolyAct->GetProperty()->SetDiffuse(0.7);
	LiverPolyAct->GetProperty()->SetSpecular(0.4);


	//render tools
	vtkSmartPointer<vtkRenderer> VolumeRender = vtkSmartPointer<vtkRenderer>::New();
	VolumeRender->AddVolume(LiverVolumActor);
	VolumeRender->SetViewport(0, 0, 0.5, 1);
	VolumeRender->ResetCamera();

	vtkSmartPointer<vtkRenderer> MeshRender = vtkSmartPointer<vtkRenderer>::New();
	MeshRender->AddActor(LiverPolyAct);
	MeshRender->SetViewport(0.5, 0, 1, 1);
	MeshRender->SetActiveCamera(VolumeRender->GetActiveCamera());
	MeshRender->SetBackground(1, 1, 1);

	vtkSmartPointer<vtkRenderWindow> RendWin = vtkSmartPointer<vtkRenderWindow>::New();
	RendWin->SetSize(1200, 400);
	RendWin->AddRenderer(VolumeRender);
	RendWin->AddRenderer(MeshRender);

	vtkSmartPointer<vtkRenderWindowInteractor> RendWinIt = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	RendWinIt->SetRenderWindow(RendWin);

	RendWin->Render();
	RendWinIt->Start();
	

}

结果如下:左边是体数据绘制,右边是提取的等值面经过抽取和平滑后的结果

 

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,让我来回答你的问题。 首先,让我们来简单了解一下Marching Cubes算法是什么。Marching Cubes算法是一种绘制技术,将三维数据转换为表网格,从而实现可视化的目的。这个算法可以用于任何三维数据集,包括医学图像、地质勘探数据、气象数据等等。在Marching Cubes算法中,我们需要输入一个三维的数据集,然后根据这个数据集的数值,生成一个表网格。 接下来,我们来谈一下使用vtk实现Marching Cubes算法绘制自由信息的步骤: 1. 首先,我们需要读取VOF场数据集。我们可以使用vtkImageData类来读取VOF场数据集,然后使用vtkContourFilter类将数据集转化为等值vtkContourFilter类可以根据一组等值线来绘制出等值等值线是一条连接相同数值的点的线,等值则是由多个等值线构成的。 2. 然后,我们需要根据VOF场数据集的数值,计算出等值的位置和法向量。这个过程可以使用Marching Cubes算法来实现。Marching Cubes算法将三维数据集划分为一个个小的立方,然后根据每个立方的数值和边界情况,决定等值的位置和法向量。 3. 最后,我们可以使用vtkActor和vtkRenderer类来将等值添加到场景中,并使用vtkRenderWindow类将场景渲染到屏幕上。vtkActor类表示一个三维模型,可以设置其颜色、材质等属性。vtkRenderer类表示一个渲染器,可以设置其渲染的视角、光照等属性。vtkRenderWindow类表示一个窗口,可以将渲染结果显示在屏幕上。 总之,使用vtk实现Marching Cubes算法绘制自由信息的步骤包括读取数据集、计算等值位置和法向量、添加等值到场景中以及渲染场景。需要注意的是,这个过程可能会比较复杂,需要一定的编程技巧和经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值