news 2026/6/23 21:23:54

SmoothDiscreteMarchingCubes 多边形网格数据的平滑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SmoothDiscreteMarchingCubes 多边形网格数据的平滑

一:主要的知识点

1、说明

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

2、知识点纪要

本段代码主要涉及的有①vtkSampleFunction函数采样器,②vtkWindowedSincPolyDataFilter 多边形网格的平滑滤波器


二:代码及注释

import vtkmodules.vtkRenderingOpenGL2 from vtkmodules.vtkCommonColor import vtkNamedColors from vtkmodules.vtkCommonCore import vtkLookupTable, vtkMinimalStandardRandomSequence from vtkmodules.vtkCommonDataModel import vtkImageData, vtkSphere from vtkmodules.vtkFiltersCore import vtkWindowedSincPolyDataFilter from vtkmodules.vtkFiltersGeneral import 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 max_r = 50 - 2.0 * radius blob_image = vtkImageData() random_sequence = vtkMinimalStandardRandomSequence() random_sequence.SetSeed(5071) for i in range(0, n): sphere = vtkSphere() 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 创建一个 函数采样器,它会在一个三维规则网格里对隐函数(比如球、平面、布尔组合)进行采样, 生成 vtkImageData 格式的体数据 指定要采样的隐函数,这里是一个 vtkSphere 隐函数的规则是: 点在球面上 → 函数值 = 0 点在球内 → 函数值 < 0 点在球外 → 函数值 > 0 如果设置的隐函数是一个平面呢? 在平面上:值 = 0 在平面的一边:值 = 正数 在另一边:值 = 负数 """ sampler = vtkSampleFunction() sampler.SetImplicitFunction(sphere) sampler.SetOutputScalarTypeToFloat() sampler.SetModelBounds(-50, 50, -50, 50, -50, 50) sampler.SetSampleDimensions(100, 100, 100) thres = vtkImageThreshold() thres.SetInputConnection(sampler.GetOutputPort()) thres.ThresholdByLower(radius * radius) """ SetInValue(i+1) 所有符合阈值条件的(即球体内部的)体素值替换为当前的循环索引 i 加 1 SetOutValue(0):将所有不符合阈值条件的(即球体外部的)体素值替换为0 """ thres.SetInValue(i + 1) thres.SetOutValue(0) """ ReplaceInOn() 启用对符合阈值条件的体素的替换 ReplaceOutOn() 启用对不符合阈值条件的体素的替换 """ thres.ReplaceInOn() thres.ReplaceOutOn() """ 启用对符合阈值条件的体素的替换 """ 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() max_value.Modified() max_value.Update() blob_image.DeepCopy(max_value.GetOutput()) discrete = vtkDiscreteMarchingCubes() discrete.SetInputData(blob_image) discrete.GenerateValues(n, 1, n) smoothing_iterations = 15 pass_band = 0.01 feature_angle = 120.0 """ vtkWindowedSincPolyDataFilter 多边形网格的平滑滤波器 普通的平滑算法(比如 vtkSmoothPolyDataFilter,基于 Laplacian 平滑)在迭代多次后,会让模型逐渐 变小,因为顶点会不断往邻居点的“平均位置”收缩。 而 vtkWindowedSincPolyDataFilter 使用频域滤波的思想,通过 Sinc 函数 + 窗口函数来控制平滑程度,使得模型不会过度收缩,同时还能去掉高频噪声 """ smoother = vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(discrete.GetOutputPort()) smoother.SetNumberOfIterations(smoothing_iterations) smoother.BoundarySmoothingOff() # 是否对边界也进行平滑 smoother.SetFeatureAngle(feature_angle) smoother.FeatureEdgeSmoothingOff() # 是否允许锐利特征边界被平滑 """ 设置滤波器的通带宽度(0~2之间的浮点数),值越小平滑越强 """ smoother.SetPassBand(pass_band) """ NonManifoldSmoothingOn 对非流行网格也进行平滑 """ smoother.NonManifoldSmoothingOn() """ NormalizeCoordinatesOn 启用后,滤波器会 在内部把坐标归一化到一个标准范围([-1,1] 或 [0,1] 之类的范围) 再进行计算, 最后再还原回原始范围 """ smoother.Update() lut = vtkLookupTable() lut.SetNumberOfColors(n) lut.SetTableRange(0, n - 1) lut.SetRampToLinear() lut.Build() # 构建查找表 lut.SetTableValue(0, 0, 0, 0, 1) # 设置索引为0的颜色值为纯黑色+不透明 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(smoother.GetOutputPort()) mapper.SetLookupTable(lut) mapper.SetScalarRange(0, lut.GetNumberOfColors()) ren = vtkRenderer() ren_win = vtkRenderWindow() ren_win.AddRenderer(ren) ren_win.SetWindowName('SmoothDiscreteMarchingCubes') 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()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/19 18:34:55

禁用MinIO后的7种企业级替代方案评测

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 构建存储方案决策助手&#xff0c;功能&#xff1a;1. 通过问卷收集企业存储需求 2. 基于机器学习推荐最适合的存储方案 3. 提供详细对比参数表 4. 生成迁移路线图。包含性能测试模…

作者头像 李华
网站建设 2026/6/14 18:58:25

document.querySelector在电商网站中的5个实战应用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个模拟电商网站&#xff0c;展示document.querySelector的5个典型应用场景&#xff1a;1. 获取商品列表&#xff1b;2. 实现购物车数量更新&#xff1b;3. 添加收藏功能&…

作者头像 李华
网站建设 2026/6/23 1:02:32

企业级应用:OpenJDK1.8在生产环境中的部署实践

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个企业级OpenJDK1.8部署检查工具&#xff0c;包含以下功能&#xff1a;1) 验证OpenJDK1.8的完整性&#xff1b;2) 检查系统兼容性&#xff1b;3) 自动配置安全参数&#xff1…

作者头像 李华
网站建设 2026/6/22 21:40:20

Homebrew实战:从安装到开发环境搭建全流程

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个macOS开发环境配置工具&#xff0c;使用Homebrew作为基础包管理器。需要实现&#xff1a;1.自动安装Homebrew 2.批量安装开发工具链(git, node, python等) 3.配置VS Code开…

作者头像 李华
网站建设 2026/6/23 7:51:58

企业级Git仓库SSH连接安全最佳实践

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个企业SSH连接管理方案&#xff0c;包含&#xff1a;1. 自动化脚本批量验证Git服务器主机密钥&#xff1b;2. 团队共享known_hosts文件的安全分发机制&#xff1b;3. 密钥轮换…

作者头像 李华