一:主要的知识点
1、说明
本文只是教程内容的一小段,因博客字数限制,故进行拆分。主教程链接:vtk教程——逐行解析官网所有Python示例-CSDN博客
2、知识点纪要
本段代码主要涉及的有①vtkPointInterpolator点差值,②vtkResampleWithDataSet数据的采样
二:代码及注释
from vtkmodules.vtkCommonColor import vtkNamedColors from vtkmodules.vtkIOGeometry import vtkSTLReader from vtkmodules.vtkIOInfovis import vtkDelimitedTextReader from vtkmodules.vtkFiltersGeneral import vtkTableToPolyData import numpy as np from vtkmodules.vtkCommonDataModel import vtkImageData from vtkmodules.vtkFiltersPoints import vtkGaussianKernel, vtkPointInterpolator from vtkmodules.vtkFiltersCore import vtkResampleWithDataSet from vtkmodules.vtkRenderingCore import ( vtkActor, vtkPointGaussianMapper, vtkPolyDataMapper, vtkRenderWindow, vtkRenderWindowInteractor, vtkRenderer ) """ vtkFiltersPoints 是 VTK(Visualization Toolkit)中一个专门用于处理和分析**点云数据(Point Cloud Data)**的模块 该模块中包含的过滤器主要关注对 3D 空间中一组离散点进行处理、插值、连接、过滤和分析,而不需要依赖于这些点之间的拓扑连接(即不需要边或面) """ def main(): colors = vtkNamedColors() """ vtkDelimitedTextReader 用于读取分隔符文本文件,输出一个vtkTable对象 """ points_fn = "Data/sparsePoints.txt" probe_fn = "Data/InterpolatingOnSTL_final.stl" points_reader = vtkDelimitedTextReader() points_reader.SetFileName(points_fn) # DetectNumericColumnsOn 在读取数据时,要检查文件中的每一列 # 如果一列中的所有数据都可以被识别为数字(整数或浮点数),那么 VTK 就会将该列的数据存储为数值类型 # 如果不开启,所有数据都会默认被档位字符串存储 points_reader.DetectNumericColumnsOn() # SetFieldDelimiterCharacters 指定列与列之间的分隔符 points_reader.SetFieldDelimiterCharacters('\t') # SetHaveHeaders 设置为True,是告诉阅读器,第一行不该被视为数据,而是每一列的名称 points_reader.SetHaveHeaders(True) """ vtkTableToPolyData 主要功能是将表格数据 (vtkTable) 转换为 3D 几何体数据 表中的每一行数据转换为 3D 空间中的一个点 (x,y,z) """ table_points = vtkTableToPolyData() table_points.SetInputConnection(points_reader.GetOutputPort()) table_points.SetXColumn("x") # 设置作为 X 坐标的列的名称 table_points.SetYColumn("y") # 设置作为 Y 坐标的列的名称 table_points.SetZColumn("z") # 设置作为 Z 坐标的列的名称 table_points.Update() # 最终输出:一个 vtkPolyData 对象,其中包含所有的 3D 坐标点。 # 此外,表中剩余的列(如 'val' 标量数据)会自动作为点数据 (PointData) 附着到这些点上 points = table_points.GetOutput() points.GetPointData().SetActiveScalars('val') range = points.GetPointData().GetScalars().GetRange() stl_reader = vtkSTLReader() stl_reader.SetFileName(probe_fn) stl_reader.Update() surface = stl_reader.GetOutput() bounds = np.array(surface.GetBounds()) dims = np.array([101, 101, 101]) box = vtkImageData() box.SetOrigin(bounds[::2]) box.SetDimensions(dims) box.SetSpacing((bounds[1::2] - bounds[:-1:2]) / (dims - 1)) """ vtkGaussianKernel VTK 中用于**点插值(Point Interpolation)的核函数(Kernel Function)**之一 在进行插值时,核函数负责定义如何根据周围的源数据点来计算目标点上的数值 该类的核心作用是计算权重:给定一个目标点和一个源数据点,它计算一个权重值,这个权重值反映了源数据点对目标点的影响程度 """ gaussian_kernal = vtkGaussianKernel() gaussian_kernal.SetSharpness(2) gaussian_kernal.SetRadius(12) """ vtkPointInterpolator VTK 中用于实现**点插值(Point Interpolation)**的核心过滤器 主要功能是:将稀疏的源数据点上的属性(如标量、颜色、向量)平滑地映射(插值)到一个更密集的目标数据集上 具体来说是解决数据稀疏性和空间连续性之间的矛盾,将一组离散、稀疏的测量数据,转换为一个在空间上连续、可读的数据场 使用案例: 假设你在一个城市中设置了 50 个温度传感器来测量实时气温。如果你想知道两传感器之间某个具体地点的温度,或者想生成一张覆盖整个城市、颜色连续的温度云图,该怎么办? 运用 vtkPointInterpolator: 源数据:50 个点的 (x,y) 坐标和测量温度 T(稀疏点集)。 目标数据:一张覆盖城市区域的密集 2D 网格(例如 1000×1000 个点)。 插值:vtkPointInterpolator 使用高斯核。对于密集网格上的每个点,它根据周围 50 个传感器的距离和温度,计算出一个平滑的、估计的温度值。 结果:你得到了一张在空间上连续的温度图,可以用来生成漂亮的颜色云图,分析热岛效应等。 """ interpolator = vtkPointInterpolator() interpolator.SetInputData(box) interpolator.SetSourceData(points) interpolator.SetKernel(gaussian_kernal) """ vtkResampleWithDataSet 用于在两个数据集之间进行数据传输(Data Transfer)或重采样(Resampling) 将一个“源数据集”(Source Data)上的属性数据(如标量、向量)采样或复制到另一个“输入数据集”(Input Data)的几何体上 vtkResampleWithDataSet 使用 surface 的几何体结构,到 interpolator 创建的 3D 场数据中去采样属性值 """ resample = vtkResampleWithDataSet() resample.SetSourceConnection(interpolator.GetOutputPort()) resample.SetInputData(surface) mapper = vtkPolyDataMapper() mapper.SetInputConnection(resample.GetOutputPort()) mapper.SetScalarRange(range) actor = vtkActor() actor.SetMapper(mapper) """ vtkPointGaussianMapper 专门用于**渲染点云(Point Cloud)**的映射器(Mapper) 将 3D 空间中的离散点,渲染为具有平滑、高斯衰减效果的 2D 形状(通常称为 Splat 或 点图元),从而提高点云的可视化效果和感知深度 """ point_mapper = vtkPointGaussianMapper() point_mapper.SetInputData(points) point_mapper.SetScalarRange(range) point_mapper.SetScaleFactor(0.6) # 设置渲染出的 2D 圆片(Splat)在屏幕上的相对大小。这个值越大,点图元就越大。 point_mapper.EmissiveOff() # 禁用圆片材质的自发光属性。这意味着圆片的最终亮度将完全取决于场景中的光源 point_mapper.SetSplatShaderCode( "//VTK::Color::Impl\n" "float dist = dot(offsetVCVSOutput.xy,offsetVCVSOutput.xy);\n" "if (dist > 1.0) {\n" " discard;\n" "} else {\n" " float scale = (1.0 - dist);\n" " ambientColor *= scale;\n" " diffuseColor *= scale;\n" "}\n" ) # 定制着色器代码 point_actor = vtkActor() point_actor.SetMapper(point_mapper) renderer = vtkRenderer() renWin = vtkRenderWindow() renWin.AddRenderer(renderer) iren = vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) renderer.AddActor(actor) renderer.AddActor(point_actor) renderer.SetBackground(colors.GetColor3d('SlateGray')) renWin.SetSize(640, 480) renWin.SetWindowName('PointInterpolator') renderer.ResetCamera() renderer.GetActiveCamera().Elevation(-45) iren.Initialize() renWin.Render() iren.Start() if __name__ == '__main__': main()