DiscreteMarchingCubes离散等值面提取算法

一:主要的知识点

1、说明

本文只是教程内容的一小段,因博客字数限制,故进行拆分。主教程链接:vtk教程------逐行解析官网所有Python示例-CSDN博客

2、知识点纪要

本段代码主要涉及的有①vtkImageData的基本信息及基本使用

二:代码及注释

python 复制代码
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import vtkLookupTable, vtkMinimalStandardRandomSequence
from vtkmodules.vtkCommonDataModel import vtkImageData, vtkSphere
from vtkmodules.vtkFiltersGeneral import vtkDiscreteFlyingEdges3D, vtkDiscreteMarchingCubes
from vtkmodules.vtkImagingCore import vtkImageThreshold
from vtkmodules.vtkImagingHybrid import vtkSampleFunction
from vtkmodules.vtkImagingMath import vtkImageMathematics
from vtkmodules.vtkRenderingCore import (
    vtkActor,
    vtkPolyDataMapper,
    vtkRenderWindow,
    vtkRenderWindowInteractor,
    vtkRenderer
)
 
 
def main():
    n = 20
    radius = 8
 
    """
    这里只创建了一个空壳的vtkImageData,因为这里不需要直接设置范围
    在 VTK 里,vtkImageData 自己本身可以设置 extent(索引范围) 和 spacing(体素间距),然后你才能在它里面放数据
    但是在本示例代码中,sampler 已经 决定了采样范围和分辨率
    SetModelBounds(-50, 50, -50, 50, -50, 50) = 空间边界
    SetSampleDimensions(100, 100, 100) = 每个方向的体素数量
    
    当 sampler.Update() 时,它会 创建一个新的 vtkImageData,范围就是 [-50,50]³  
    也就是说,这里的 vtkImageData 是 sampler 输出的结果,范围由 sampler 决定
    """
    blob_image = vtkImageData()
 
    max_r = 50 - 2.0 * radius
    random_sequence = vtkMinimalStandardRandomSequence()
    random_sequence.SetSeed(5071)
    for i in range(0, n):
        sphere = vtkSphere()
        sphere.SetRadius(radius)
        x = random_sequence.GetRangeValue(-max_r, max_r)
        random_sequence.Next()
        y = random_sequence.GetRangeValue(-max_r, max_r)
        random_sequence.Next()
        z = random_sequence.GetRangeValue(-max_r, max_r)
        random_sequence.Next()
 
        sphere.SetCenter(int(x), int(y), int(z))
 
        """
        创建一个 采样器 (vtkSampleFunction)
        它的作用是:在给定的空间范围内,均匀采样某个 隐式函数 (implicit function),
        并把结果存成 vtkImageData(体素格子)
        """
        sample = vtkSampleFunction()
        sample.SetImplicitFunction(sphere)
        """
        指定采样结果的标量类型。
        这里设置为 float,表示每个体素的值是浮点数(而不是整型)。
        好处是可以表示连续的函数值,而不仅仅是 0/1
        """
        sample.SetOutputScalarTypeToFloat()
        """
        指定采样网格的分辨率。
        在 X、Y、Z 三个方向各采样 100 个点 → 得到 100万 个体素。
        分辨率越高,结果越精细,但内存和计算也更大
        """
        sample.SetSampleDimensions(100, 100, 100)
        """
        设置采样空间的边界框(bounding box)
        也就是说,它会在这个立方体范围内均匀布置采样点,然后对球体函数进行采样
        """
        sample.SetModelBounds(-50, 50, -50, 50, -50, 50)
 
        """
        整段代码的含义是
        如果某个体素值 ≤ radius² → 说明它在球体内 → 标记为 i+1
        如果 > radius² → 说明它在球体外 → 标记为 0
        """
        thres = vtkImageThreshold()
        thres.SetInputConnection(sample.GetOutputPort())
        """
        表示保留所有 距离平方 ≤ radius² 的体素,也就是在球体内的体素
        """
        thres.ThresholdByLower(radius * radius)
        thres.ReplaceInOn()
        thres.ReplaceOutOn()
        thres.SetInValue(i + 1)
        thres.SetOutValue(0)
        thres.Update()
 
        if i == 0:
            blob_image.DeepCopy(thres.GetOutput())
 
        # 图像的像素级处理
        max_value = vtkImageMathematics()
        max_value.SetInputData(0, blob_image)
        max_value.SetInputData(1, thres.GetOutput())
        """
        做"逐体素最大值"运算.也就是说,球体之间的标签会取最大值,避免覆盖
        """
        max_value.SetOperationToMax()
        """
        Modified
        强制标记这个 filter 已经被修改,确保在调用 Update() 时重新执行图像运算,而不是复用旧缓存
        """
        max_value.Modified()
        max_value.Update()
 
        blob_image.DeepCopy(max_value.GetOutput())
 
    discrete = vtkDiscreteFlyingEdges3D()
    discrete.SetInputData(blob_image)
    """
    GenerateValues  指定要生成的等值面范围
    GenerateValues(numContours, rangeStart, rangeEnd) 的含义是:
    在 [rangeStart, rangeEnd] 之间 平均分布 numContours 个等值面值
    """
    discrete.GenerateValues(n, 1, n)
 
    lut = vtkLookupTable()
    lut.SetNumberOfColors(n)
    lut.SetTableRange(0, n - 1)
    """
    指定查找表的标量映射是线性的(而不是对数)
    """
    lut.SetScaleToLinear()
    lut.Build()
    """
    SetTableValue  把第 0 号颜色设为 (R=0, G=0, B=0, A=1),也就是 黑色,不透明
    """
    lut.SetTableValue(0, 0, 0, 0, 1)
 
    random_sequence = vtkMinimalStandardRandomSequence()
    random_sequence.SetSeed(5071)
    for i in range(1, n):
        r = random_sequence.GetRangeValue(0.4, 1)
        random_sequence.Next()
        g = random_sequence.GetRangeValue(0.4, 1)
        random_sequence.Next()
        b = random_sequence.GetRangeValue(0.4, 1)
        random_sequence.Next()
        lut.SetTableValue(i, r, g, b, 1.0)
 
    mapper = vtkPolyDataMapper()
    mapper.SetInputConnection(discrete.GetOutputPort())
    mapper.SetLookupTable(lut)
    mapper.SetScalarRange(0, lut.GetNumberOfColors())
 
    # Create the RenderWindow, Renderer and both Actors
    #
    ren = vtkRenderer()
    ren_win = vtkRenderWindow()
    ren_win.AddRenderer(ren)
    ren_win.SetWindowName('DiscreteMarchingCubes')
 
    iren = vtkRenderWindowInteractor()
    iren.SetRenderWindow(ren_win)
 
    actor = vtkActor()
    actor.SetMapper(mapper)
 
    ren.AddActor(actor)
 
    colors = vtkNamedColors()
    ren.SetBackground(colors.GetColor3d('Burlywood'))
 
    ren_win.Render()
 
    iren.Start()
 
 
if __name__ == '__main__':
    main()
相关推荐
小途软件19 小时前
用于机器人电池电量预测的Sarsa强化学习混合集成方法
java·人工智能·pytorch·python·深度学习·语言模型
扫地的小何尚19 小时前
NVIDIA RTX PC开源AI工具升级:加速LLM和扩散模型的性能革命
人工智能·python·算法·开源·nvidia·1024程序员节
wanglei20070820 小时前
生产者消费者
开发语言·python
清水白石00820 小时前
《从零到进阶:Pydantic v1 与 v2 的核心差异与零成本校验实现原理》
数据库·python
昵称已被吞噬~‘(*@﹏@*)’~20 小时前
【RL+空战】学习记录03:基于JSBSim构造简易空空导弹模型,并结合python接口调用测试
开发语言·人工智能·python·学习·深度强化学习·jsbsim·空战
2501_9418779820 小时前
从配置热更新到运行时自适应的互联网工程语法演进与多语言实践随笔分享
开发语言·前端·python
酩酊仙人21 小时前
fastmcp构建mcp server和client
python·ai·mcp
且去填词21 小时前
DeepSeek API 深度解析:从流式输出、Function Calling 到构建拥有“手脚”的 AI 应用
人工智能·python·语言模型·llm·agent·deepseek
rgeshfgreh1 天前
Python条件与循环实战指南
python
rgeshfgreh1 天前
通达信LC1文件结构解析指南
python