Marching Cubes

MarchingCubes建模是三维可视化库VTK建模算法之一。该建模方法采用空间分解的方法,对空间体元进行不断的切割处理,最后得到一个由规则体构成的非规则复杂物体的近似。这种方法包括有物体的内在信息,从而实现体数据的表达。


MC方法求等值面的算法流程:

① 将三维离散规则数据场分层读入内存;

② 扫描两层数据,逐个构造体元,每个体元中的8个角点取自相邻的两层;

③ 将体元每个角点的函数值与给定的等值面C作比较,根据比较结果,构造该体元的状态表;

④ 根据状态表,得到将与等值面有角点的体元边界;

⑤ 通过线性插值方法,计算出体元边界与等值面的交点;

⑥ 利用中心差分方法,求出体元各角点处的法向量,再通过线性插值方法,求出三角形各顶点处的法向量;

<7> 根据各三角面片各顶点的坐标值及法向量绘制等值面图像。


VTK官网给出的例子

#include "stdafx.h"

#include <vtkAutoInit.h>  
VTK_MODULE_INIT(vtkRenderingOpenGL2);  
VTK_MODULE_INIT(vtkInteractionStyle);  


#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkImageData.h>
#include <vtkSphereSource.h>
#include <vtkVoxelModeller.h>
#include <vtkRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkMarchingCubes.h>
#include <vtkPolyDataMapper.h>
#include <vtkDICOMImageReader.h>
#include <vtkRenderWindowInteractor.h>


int _tmain(int argc, _TCHAR* argv[])
{
	//  std::string folder = "C:\\Users\\yorktal03\\Desktop\\ZYH\\data\\MarchingMan";

	vtkSmartPointer<vtkSphereSource> sphere = vtkSphereSource::New();
	sphere->SetPhiResolution(20);
	sphere->SetThetaResolution(20);
	sphere->Update();
	
	double bounds[6];
	// GetBounds()
	// Return a pointer to the geometry bounding box in the form (xmin,xmax, ymin,ymax, zmin,zmax). 
	// THIS METHOD IS NOT THREAD SAFE. 
	sphere->GetOutput()->GetBounds(bounds);
	/*for (unsigned int i = 0; i < 6; i += 2)
	{
		double range = bounds[i + 1] - bounds[i];
		bounds[i] = bounds[i] - .1 * range;
		bounds[i + 1] = bounds[i + 1] + .1 * range;
	}*/

	vtkSmartPointer<vtkVoxelModeller> voxelModeller = vtkVoxelModeller::New();
	voxelModeller->SetSampleDimensions(50, 50, 20);
	voxelModeller->SetModelBounds(bounds);
	voxelModeller->SetScalarTypeToFloat();
	voxelModeller->SetMaximumDistance(.1);
	voxelModeller->SetInputConnection(sphere->GetOutputPort());
	voxelModeller->Update();
	
	vtkSmartPointer<vtkImageData> volume = vtkSmartPointer<vtkImageData>::New();
	volume->DeepCopy(voxelModeller->GetOutput());

	/*vtkSmartPointer<vtkDICOMImageReader> imgs = vtkDICOMImageReader::New();
	imgs->SetDirectoryName(folder.c_str());
	imgs->Update();	
	volume->DeepCopy(imgs->GetOutput());*/

	vtkSmartPointer<vtkMarchingCubes> surface = vtkMarchingCubes::New();
	surface->SetInputData(volume);
	surface->ComputeNormalsOn();
	surface->SetValue(0, 0.5);

	vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::New();
	mapper->SetInputConnection(surface->GetOutputPort());
	mapper->ScalarVisibilityOff();

	vtkSmartPointer<vtkActor> actor = vtkActor::New();
	actor->SetMapper(mapper);

	vtkSmartPointer<vtkRenderer> ren = vtkRenderer::New();
	ren->AddActor(actor);
	ren->SetBackground(0.1, .2, .3);

	vtkSmartPointer<vtkRenderWindow> renWin = vtkRenderWindow::New();
	renWin->AddRenderer(ren);
	renWin->Render();

	vtkSmartPointer<vtkRenderWindowInteractor> irenwin = vtkRenderWindowInteractor::New();
	irenwin->SetRenderWindow(renWin);
	irenwin->Start();

	return 0;
}
两种不同的输入数据,一种是绘制一个球体:


一种是从DICOM图像列;


读取图像然后显示图像好像没有什么麻烦,只是绘制立体图以及参数的设置还是需要学习的。


voxelModeller  :将无规则的数据集转化为体素表示。

体素(voxel),是体积元素(volumepixel)的简称。
vtkVoxelModeller默认输出的图像是 VTK_BIT 图像,但是MC不支持这个类型的图像,所以 SetScalarTypeToFloat() 得到一个Float的图像。


当然这边也有其他比较复杂的例子

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值