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()
相关推荐
秋刀鱼 ..2 小时前
第二届电力电子技术与电网系统国际学术会议(PETGS 2026)
大数据·python·计算机网络·数学建模·机器人·制造
quikai19812 小时前
python练习第四组
开发语言·前端·python
BoBoZz192 小时前
ExtractLargestIsosurface 提取最大连通域
python·vtk·图形渲染·图形处理
爱笑的眼睛113 小时前
从零构建与深度优化:PyTorch训练循环的工程化实践
java·人工智能·python·ai
古城小栈3 小时前
Spring Boot 4.0 虚拟线程启用配置与性能测试全解析
spring boot·后端·python
liliangcsdn3 小时前
如何使用pytorch模拟Pearson loss训练模型
人工智能·pytorch·python
MediaTea3 小时前
Python 的设计哲学P08:可读性与人类语言
开发语言·python
qq_251533593 小时前
如何使用 Python 正则表达式去除空格/制表符/换行符?
开发语言·python·正则表达式
酌沧3 小时前
大模型量化技术全解析
人工智能·python·算法