MarchingCubes(MC)算法是面繪製算法中的經典算法,它是W.Lorensen等人於1987年提出來的一種體素級重建方法。MC算法也被稱為“等值面提取”(IsosurfaceExtraction)算法。
算法介紹,VTK實現,
算法介紹
·醫學圖像三維重建的方法主要有兩大類:一類是三維面繪製,另一類是三維體繪製。體繪製能夠更真實地反映物體結構,但由於其運算量大,即使利用高性能的計算機也無法滿足實際套用中互動操作的需要。因此,面繪製是目前醫學圖像三維重建的主流算法。··MarchingCubes(MC)算法是面繪製算法中的經典算法,它是W.Lorensen等人於1987年提出來的一種體素級重建方法。因其原理簡單容易實現,得到了廣泛的套用。
·MC算法實際上是一個分而治之的方法,因為其將等值面的抽取分布於每一個體素(voxel)中進行。對於每個被處理的體素,以三角面片來逼近其內部的等值面。每個體素是一個小立方體(cube),在構造三角面片的處理過程中對每個體素都“掃描”一遍,就好像是一個處理器在這些體素上移動一樣,也因此而得名。··在等值面抽取的過程中將一系列二維切片數據看做是一個三維的數據場,從中將具有某種閾值的物質抽取出來,以某種拓撲形式連線成三角面片,所以MC算法也被稱為“等值面提取”(IsosurfaceExtraction)算法。··在醫學套用上,採用MC算法可以重建人體外部輪廓、內部組織器官,使醫生能夠直接在三維圖像上觀察感興趣的器官與周圍組織的空間關係。
·在MC算法中,假定原始數據是離散的三維空間規則數據場,用於醫療診斷的斷層掃描(CT)圖像就屬於這一類型。··MC算法的基本思想是逐個處理數據場中的立方體,找出與等值面相交的立方體,採用線性插值計算出等值面與立方體邊的交點。根據立方體每一頂點與等值面的相對位置,將等值面與立方體邊上的交點按一定方式連線生成等值面,作為等值面在該立方體內的一個逼近表示。··因而,MC算法中每一單元內等值面抽取的兩個主要計算:
(1)體素中由三角面片逼近的等值面計算;
(2)三角面片各頂點法向量計算。
VTK實現
reader=vtkDICOMImageReader::New();//打開CT圖像檔案
reader->SetDataByteOrderToLittleEndian();
shrink=vtkImageShrink3D::New();
shrink->SetShrinkFactors(0,0,0);//調節繪製圖像的精細程度
shrink->AveragingOn();
skinExtractor=vtkContourFilter::New();
skinExtractor->SetlnputConnection(shrink->GetOutputPort());
skinExtractor->SetValue(0,400);//調整閾值,400以上是骨組織
sphere=vtkSphereSource::New();
sphere->SetThetaResolution(100);
sphere->SetPhiResolution(100);
sphere->SetRadius(2);
deci=vtkDecimatePro::New();
deci->SetlnputConnection(sphere->GetOutputPort());
deci->SetTargetReduction(0.3);
smooth--vtkSmoothPolyDataFilter::New();
smooth->SetlnputConnection(deci->GetOutputPort());
smooth->SetNumberOflterations(200);
skinNormals=vtkPolyDataNormals::New0;
skinNormals->SetlnputConnection(smooth->GetOutputPort());
skinNormals->SetFeatureAngle(60.0);
stripper=vtkStripper::New();
stripper->Setlnput(skinNormals->GetOutput());
skinMapper =vtkPolyDataMappe::New();
skinMapper->Setlnput(stripper->GetOutput());
skinMapper->ScalarVisibilityOff();
∥在構造函式中把各個vtk對象連成通道
coneActor=vtkActor::New();
coneActor->SetMapper(skinMapper);
coneActor->GetProperty()->SetAmbient(0.5);
coneActor->GetPropertY()->SetAmbientColor(0.1,0.2,0.6);
coneActor->GetProperty()->SetDiffuse(1);
coneActor->GetProperty()->SetDiffuseColor(0.3,0.6,0.2);
coneActor->GetProperty()->SetSpecular(0.6);
coneActor->GetProperty()->SetSpecularColor(0.8,0.3,0.5);
coneActor->GetProperty()->SetSpecularPower(1);
aCamera=vtkCamera::New();
aCamera->SetViewUp(0,0,0);
aCamera->SetPosition(1,1,1);
aCamera->SetFocalPoim(99,99,40);
renderer=vtkRenderer::New();
renderer->AddActor(coneActor);