网站空间已过期,wordpress 彩色标签云插件,六安市民网,成都网站设计开发做得好1,确定包含等值面的体元
首先介绍一下 体元的概念#xff0c;体元是三维图像中由相邻的八个体素点组成的正方体方格#xff0c;英语也叫 Cube#xff0c;体元中角点函数值分为两种情况#xff0c;一种是大于等于给定等值面的值 C0 ,则将角点设为 1 称该角点在等值面内部体元是三维图像中由相邻的八个体素点组成的正方体方格英语也叫 Cube体元中角点函数值分为两种情况一种是大于等于给定等值面的值 C0 ,则将角点设为 1 称该角点在等值面内部否则设为0在等值面之外
一般来说会出现一个角点在内一个角点在外则角点之间的连线(也就是体元的边)必然与等值面相交根据这个原理就能判断等值面与哪些体元相交。
——————————————————————————————————————
三维空间中平行且相邻的两个二维图像每个图像中的正方形四个像素顶点组成一个基本的像素图像单元组成一个基本的三维图像单元。下图中由6个这样的基本三维图像单元 vtkImageData结构由尺寸、间距和原点来定义。尺寸标注是沿着每个主轴的体素或像素的数量。原点是数据的第一个切片的左下角的世界坐标位置。间距是沿三个主要轴的像素之间的距离。
原点是数据集左下角的世界坐标位置。
尺寸是沿着三个主要轴的体素或像素的数量。
间距是体素的高度、长度和宽度或相邻像素之间的距离这取决于是将数据视为相同的方框还是连续函数中的样本点。 ——————————————————————————————————————————
Marching Cubes算法根据一个立方体的8个顶点判断这8个顶点的每个顶点在等值面的内部还是外部每个顶点只有“在等值面内”和“在等值面外”这两种状态设为0和1从而根据这8个顶点的状态建立一个包含共256种状态的查找表根据平面对称性、中心对称性256种最终降到15种。 顶点值高于等值在表面的内部等于等值在表面上低于等值在表面外。 体元的每个顶点有两种状态总共有256种可以制作一个查找表(look up table)
但由于反转状态不变所以可以减少一半为128种。
再根据旋转不变形又可以减少到14种情况。 可以认为这14中类似于基经过旋转反转可以得到256种状态对应的结果Triangulated Cubes 根据每个顶点的状态我们可以为每类制作一个8位索引Cube Numbering 索引指向边表给出了边的交叉情况。
相交边的编码——通过编码记录对应的cube相交边的编号
二进制00000010
十进制2
Table[256]表示哪些边有交点
Table[2]0x1030000 0010 0000 0011
表示0,1,9号边上有交点
为了避免每次转化成二进制进行解码可以直接记录与哪些边有交点之后直接查表即可。
Table2[256][16]
Table2[2](0, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
因为每个正方体中最多有1个或4个三角形所以线性插值就足够了。 2确定等值面与体元边界的交点
找到含有等值面的体元之后接下来就是确定等值面与体元边界的交点体元间的数值都是呈线性变化求交点时一般采用的是线性插值如 Case0 中等值面的两个端点 一个在外为( 标记0) 一个在内 ( 标记为1 ) 则交点为0.5 3求等值面的法向量
以上步骤 123 为实现 MC 算法步骤流程但利用 VTK 不需要这么繁琐主要算法步骤都已经封装到 vtkMarchingCube 类中使用 vtkMarchingCube 时需要设置三个参数
SetValue(int i,double value) 设置第i 个等值面的值b(提醒一下医学图像中的灰度值范围不是 0-256 而是0-65326但大部分取值范围都在0-1000。SetNumberofContours(int number)设置等值面的个数ComputerNormalsOn() 设置计算等值面的法向量提高渲染质量 上面这张图显示的就是 vtk 呈像的基本流程下面是仿照官网写的用面绘制来对图像重建的代码部分
#includevtkRenderWindow.h
#includevtkRenderWindowInteractor.h
#includevtkDICOMImageReader.h
#includevtkMarchingCubes.h
#includevtkPolyDataMapper.h
#includevtkStripper.h
#includevtkActor.h
#includevtkProperty.h
#includevtkCamera.h
#includevtkOutlineFilter.h
#includevtkOBJExporter.h
#includevtkRenderer.h
#includevtkMetaImageReader.h
#includevtkInteractorStyleTrackballCamera.h#includeiostream
#includestring.h
//需要进行初始化否则会报错
#include vtkAutoInit.h
#includevtkRenderingVolumeOpenGL2ObjectFactory.h
#includevtkRenderingOpenGL2ObjectFactory.husing namespace std;
int main()
{///Marching Cube; vtkObjectFactory::RegisterFactory(vtkRenderingOpenGL2ObjectFactory::New());vtkObjectFactory::RegisterFactory(vtkRenderingVolumeOpenGL2ObjectFactory::New());vtkSmartPointervtkRenderer ren vtkSmartPointervtkRenderer::New();vtkSmartPointervtkRenderWindow renWin vtkSmartPointervtkRenderWindow::New();//WINDOWrenWin-AddRenderer(ren);vtkSmartPointervtkRenderWindowInteractor iren vtkSmartPointervtkRenderWindowInteractor::New();//wininteratcor;iren-SetRenderWindow(renWin);vtkSmartPointervtkDICOMImageReader reader vtkSmartPointervtkDICOMImageReader::New();reader-SetDirectoryName(E:/DIcom_Data/DICOM);reader-SetDataByteOrderToLittleEndian();reader-Update();/*vtkDICOMImageReader *reader vtkDICOMImageReader::New();reader-SetDirectoryName(E:/Coding Pra/VTK/VTK_Examples_StandardFormats_Input_DicomTestImages/DICOM);reader-SetDataByteOrderToLittleEndian();reader-Update();*/cout 读取数据完毕 endl;cout The width is reader-GetWidth() endl;cout The height is reader-GetHeight() endl;cout The depth is reader-GetPixelSpacing() endl;cout The Output port is reader-GetOutputPort() endl;vtkSmartPointervtkMarchingCubes marchingcube vtkSmartPointervtkMarchingCubes::New();marchingcube-SetInputConnection(reader-GetOutputPort());//获得读取的数据的点集marchingcube-SetValue(0, 200);//Setting the threshold;marchingcube-ComputeNormalsOn();//计算表面法向量;vtkSmartPointervtkStripper Stripper vtkSmartPointervtkStripper::New();Stripper-SetInputConnection(marchingcube-GetOutputPort());//获取三角片vtkSmartPointervtkPolyDataMapper Mapper vtkSmartPointervtkPolyDataMapper::New();//将三角片映射为几何数据Mapper-SetInputConnection(Stripper-GetOutputPort());Mapper-ScalarVisibilityOff();//vtkSmartPointervtkActor actor vtkSmartPointervtkActor::New();//Created a actor;actor-SetMapper(Mapper);//获得皮肤几何数据actor-GetProperty()-SetDiffuseColor(1, .49, .25);//设置皮肤颜色actor-GetProperty()-SetSpecular(0.3);//反射率actor-GetProperty()-SetOpacity(1.0);//透明度actor-GetProperty()-SetSpecularPower(20);//反射光强度actor-GetProperty()-SetColor(1, 0, 0);//设置角的颜色actor-GetProperty()-SetRepresentationToWireframe();//线框//vtkSmartPointervtkCamera camera vtkSmartPointervtkCamera::New();//Setting the Camera;//camera-SetViewUp(0, 0, -1);//设置相机向上方向//camera-SetPosition(0, 1, 0);//位置世界坐标系相机位置//camera-SetFocalPoint(0, 0, 0);//焦点世界坐标系控制相机方向//camera-ComputeViewPlaneNormal();//重置视平面方向基于当前的位置和焦点vtkSmartPointervtkOutlineFilter outfilterline vtkSmartPointervtkOutlineFilter::New();outfilterline-SetInputConnection(reader-GetOutputPort());vtkSmartPointervtkPolyDataMapper outmapper vtkSmartPointervtkPolyDataMapper::New();outmapper-SetInputConnection(outfilterline-GetOutputPort());vtkSmartPointervtkActor OutlineActor vtkSmartPointervtkActor::New();OutlineActor-SetMapper(outmapper);OutlineActor-GetProperty()-SetColor(0, 0, 0);//线框颜色ren-AddActor(actor);ren-AddActor(OutlineActor);//ren-SetActiveCamera(camera);//设置渲染器的相机ren-ResetCamera();ren-ResetCameraClippingRange();//camera-Dolly(1.5);//使用Dolly()方法延伸着视平面法向移动相机ren-SetBackground(1, 1, 1);//设置背景颜色renWin-SetSize(1000, 600);vtkInteractorStyleTrackballCamera *style vtkInteractorStyleTrackballCamera::New();iren-SetInteractorStyle(style);renWin-Render();iren-Initialize();iren-Start();vtkSmartPointervtkOBJExporter porter vtkSmartPointervtkOBJExporter::New();porter-SetFilePrefix(E:/ceshi/aaa/regist_after/polywrite.obj);//重建图像输出porter-SetInput(renWin);porter-Write();return EXIT_SUCCESS;
} 上面就是 VTK 基于 Marching Cube算法实现的重建效果
体绘制重建
体绘制时分为两部分
1定义 vtkVoluemRayCastMapper 对象
体绘制中最常用的方法 vtkVolumeRayCastMapper() 光线投影体绘制时首先定义一个Mapper 然后接受两个输入
SetInput(vtkImageDate *) 用于设置输入图像数据SetVolumeRayCastFunction(vtkVolumeRayCastFunction *) 用于设置光线投影函数类型
2利用 vtkVolumeProperty 定义体绘制属性
SetScalarOpacity() 设置灰度不透明函数SetColor() 颜色传输函数
3 定义 vtkVolume 对象接收 Mapper对象和 Property 对象
SetMapper()接受 Mapper 对象SetProperty() 接受 Property 对象
vtk 中体绘制 核心就是改变 Mapper 和 vtkVolumeRayCastFunction() 上面中vtkColumeRayCastMapper 只是 VolumeMapper 其中的一种且投影函数类 vtkVolumeRayCastFunction 一共有三个子类
vtkVolumeRayCastCompositeFunctionvtkVolumeRayCasMIPFunction、vtkVolumeRayCastIsosurfaceFunction因此其细分的话vtk中的体绘制也不止一种
而下面这个是最常用到的vtkVolumeRayCastMapper vtkVolumeRayCastCompositeFunction
//体绘制#includevtkRenderWindowInteractor.h
#includevtkDICOMImageReader.h
#includevtkCamera.h
#includevtkActor.h
#includevtkRenderer.h
#includevtkVolumeProperty.h
#includevtkProperty.h
#includevtkPolyDataNormals.h
#includevtkImageShiftScale.h
#include vtkVolumeRayCastMapper.h
#includevtkPiecewiseFunction.h
#includevtkColorTransferFunction.h
#includevtkVolumeRayCastCompositeFunction.h
#includevtkRenderWindow.h
#includevtkImageCast.h
#includevtkVolumeRayCastCompositeFunction.h
#includevtkOBJExporter.h
#includevtkOutlineFilter.h
#includevtkPolyDataMapper.h#includevtkInteractorStyleTrackballCamera.h
#includevtkRenderingVolumeOpenGL2ObjectFactory.h
#includevtkRenderingOpenGL2ObjectFactory.h
#includevtkMetaImageReader.h#includevtkLODProp3D.h//体绘制加速//Gpu光照映射
#includevtkGPUVolumeRayCastMapper.h#includeiostreamint main()
{vtkObjectFactory::RegisterFactory(vtkRenderingOpenGL2ObjectFactory::New());vtkObjectFactory::RegisterFactory(vtkRenderingVolumeOpenGL2ObjectFactory::New());//定义绘制器vtkRenderer *aRenderer vtkRenderer::New();//指向指针vtkSmartPointervtkRenderWindow renWin vtkSmartPointervtkRenderWindow::New();renWin-AddRenderer(aRenderer);vtkRenderWindowInteractor *iren vtkRenderWindowInteractor::New();iren-SetRenderWindow(renWin);//读取数据/*vtkDICOMImageReader *reader vtkDICOMImageReader::New();reader-SetDirectoryName(E:/Coding Pra/VTK/VTK_Examples_StandardFormats_Input_DicomTestImages/DICOM);reader-SetDataByteOrderToLittleEndian();*/vtkSmartPointervtkDICOMImageReader reader vtkSmartPointervtkDICOMImageReader::New();reader-SetDirectoryName(E:/DIcom_Data/DICOM);reader-SetDataByteOrderToLittleEndian();//图像数据预处理类型转换:通过 vtkimageCast 将不同类型数据集转化为 vtk 可以处理的数据集vtkImageCast *cast_file vtkImageCast::New();cast_file-SetInputConnection(reader-GetOutputPort());cast_file-SetOutputScalarTypeToUnsignedShort();cast_file-Update();//透明度映射函数定义vtkPiecewiseFunction *opacityTransform vtkPiecewiseFunction::New();opacityTransform-AddPoint(0, 0.0);opacityTransform-AddPoint(20, 0.0);opacityTransform-AddPoint(200, 1.0);opacityTransform-AddPoint(300, 1.0);//颜色映射函数定义,梯度上升的vtkColorTransferFunction *colorTransformFunction vtkColorTransferFunction::New();colorTransformFunction-AddRGBPoint(0.0, 0.0, 0.0, 0.0);colorTransformFunction-AddRGBPoint(64.0, 0.0, 0.0, 0.0);colorTransformFunction-AddRGBPoint(128.0, 1.0, 0.0, 0.0);colorTransformFunction-AddRGBPoint(192.0, 1.0, 0.0, 0.0);colorTransformFunction-AddRGBPoint(255.0, 1.0, 0.0, 0.0);vtkPiecewiseFunction *gradientTransform vtkPiecewiseFunction::New();gradientTransform-AddPoint(0, 0.0);gradientTransform-AddPoint(20, 2.0);gradientTransform-AddPoint(200, 0.1);gradientTransform-AddPoint(300, 0.1);//体数据属性vtkVolumeProperty *volumeProperty vtkVolumeProperty::New();volumeProperty-SetColor(colorTransformFunction);volumeProperty-SetScalarOpacity(opacityTransform);volumeProperty-SetGradientOpacity(gradientTransform);volumeProperty-ShadeOn();//应用volumeProperty-SetInterpolationTypeToLinear();//直线间样条插值volumeProperty-SetAmbient(0.4);//环境光系数volumeProperty-SetDiffuse(0.6);//漫反射volumeProperty-SetSpecular(0.2);volumeProperty-SetSpecularPower(10);//高光强度计算光照效应利用 vtkBolumeRayCaseMapper进行计算//vtkVolumeRayCastMapper *volunemapper vtkVolumeRayCastMapper::New();//vtkVolumeRayCastCompositeFunction *compositeFunction vtkVolumeRayCastCompositeFunction::New();//光纤映射类型定义vtkSmartPointervtkVolumeRayCastCompositeFunction compositecast vtkSmartPointervtkVolumeRayCastCompositeFunction::New();//Mapper定义,vtkSmartPointervtkVolumeRayCastMapper hiresMapper vtkSmartPointervtkVolumeRayCastMapper::New();hiresMapper-SetInputData(cast_file-GetOutput());hiresMapper-SetVolumeRayCastFunction(compositecast);vtkSmartPointervtkLODProp3D prop vtkSmartPointervtkLODProp3D::New();prop-AddLOD(hiresMapper,volumeProperty,0.0);////volunemapper-SetVolumeRayCastFunction(compositeFunction);//载入体绘制方法//volunemapper-SetInputConnection(cast_file-GetOutputPort());//vtkFixedPointVolumeRayCastMapper *fixedPointVolumeMapper vtkFixedPointVolumeRayCastMapper::New()//fixedPointVolumeMapper-SetInput()vtkVolume *volume vtkVolume::New();volume-SetMapper(hiresMapper);volume-SetProperty(volumeProperty);//设置体属性double volumeView[4] { 0,0,0.5,1 };vtkOutlineFilter *outlineData vtkOutlineFilter::New();//线框outlineData-SetInputConnection(reader-GetOutputPort());vtkPolyDataMapper *mapOutline vtkPolyDataMapper::New();mapOutline-SetInputConnection(outlineData-GetOutputPort());vtkActor *outline vtkActor::New();outline-SetMapper(mapOutline);outline-GetProperty()-SetColor(0, 0, 0);//背景纯黑色aRenderer-AddVolume(volume);aRenderer-AddActor(outline);aRenderer-SetBackground(1, 1, 1);aRenderer-ResetCamera();//重设相机的剪切范围aRenderer-ResetCameraClippingRange();renWin-SetSize(800, 800);renWin-SetWindowName(测试);vtkRenderWindowInteractor *iren2 vtkRenderWindowInteractor::New();iren2-SetRenderWindow(renWin);//设置相机跟踪模式vtkInteractorStyleTrackballCamera *style vtkInteractorStyleTrackballCamera::New();iren2-SetInteractorStyle(style);renWin-Render();iren2-Initialize();iren2-Start();vtkOBJExporter *porter vtkOBJExporter::New();porter-SetFilePrefix(E:/ceshi/aaa/regist_after/esho.obj);porter-SetInput(renWin);porter-Write();porter-Update();return EXIT_SUCCESS;} 上面是体绘制的结果相对来说体绘制需要计算资源更大些 vtk 在这方面有所考虑提供了vtKGPUVolumeRayCastMapper GUP 加速的光线投射算法。