PolyDataContourToImageData 3D集合图像转换成等效3D二值图像

一:主要的知识点

1、说明

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

2、知识点纪要

本段代码主要涉及的有①三维图形转换为3D体素数据

二:代码及注释

python 复制代码
import math

import vtkmodules.vtkRenderingOpenGL2
import vtkmodules.vtkInteractionStyle
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkFiltersCore import vtkCutter, vtkStripper
from vtkmodules.vtkCommonDataModel import vtkImageData, vtkPlane
from vtkmodules.vtkIOXML import vtkXMLPolyDataWriter
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_CHAR
from vtkmodules.vtkFiltersModeling import vtkLinearExtrusionFilter
from vtkmodules.vtkImagingStencil import vtkImageStencil, vtkPolyDataToImageStencil
from vtkmodules.vtkIOImage import vtkMetaImageWriter, vtkPNGWriter


def main():
    # 创建一个3D图形
    sphereSource = vtkSphereSource()
    sphereSource.SetPhiResolution(30)
    sphereSource.SetThetaResolution(30)
    sphereSource.SetCenter(40, 40, 40)
    sphereSource.SetRadius(20)

    # 切割数据集的"刀"
    # 首先先定义这个刀是什么,需要使用隐函数定义
    cutPlane = vtkPlane()
    cutPlane.SetOrigin(sphereSource.GetCenter())
    cutPlane.SetNormal(0, 0, 1)

    circleCutter = vtkCutter()
    circleCutter.SetInputConnection(sphereSource.GetOutputPort())
    circleCutter.SetCutFunction(cutPlane)

    stripper = vtkStripper()
    stripper.SetInputConnection(circleCutter.GetOutputPort())
    stripper.Update()

    circle = stripper.GetOutput()
    # 写入vtp文件
    polyDataWriter = vtkXMLPolyDataWriter()
    polyDataWriter.SetInputData(circle)
    polyDataWriter.SetFileName("circle.vtp")
    polyDataWriter.SetCompressorTypeToNone()  # 不适用任何压缩
    polyDataWriter.SetDataModeToAscii()  # 设置输出文件中的数据以ASCII(文本)格式存储
    polyDataWriter.Write()

    # 准备一个体素数据
    whiteImage = vtkImageData()
    bounds = [0] * 6
    circle.GetBounds(bounds)
    spacing = [0.5, 0.5, 0.5]
    whiteImage.SetSpacing(spacing)

    # 计算这个体素数据的维度
    dim = [0] * 3
    for i in range(3):
        dim[i] = int(math.ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i])) + 1
        if dim[i] < 1:
            dim[i] = 1
    whiteImage.SetDimensions(dim)  # 算是设置了图像体素的数量
    # SetExtent 设置了图像的索引范围 确保了生成的 3D 图像的体素网格是最小且精确的,既不浪费内存,又能完整地覆盖输入的几何体
    whiteImage.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1)
    origin_shift = 5 * 0.5
    origin = [0] * 3
    origin[0] = bounds[0] - origin_shift
    origin[1] = bounds[2] - origin_shift
    origin[2] = bounds[4] - origin_shift
    # 上述添加origin_shift是为了vtkImageData能够完全包裹住mesh
    whiteImage.SetOrigin(origin)
    # AllocateScalars # 为图像的体素数据分配内存。VTK_UNSIGNED_CHAR(无符号字符,范围 0-255),1 表示每个体素有一个分量(即灰度值)
    whiteImage.AllocateScalars(VTK_UNSIGNED_CHAR, 1)

    # 将 整个 3D 图像(体素网格)预先填充为前景值(即白色)
    # inval = 255
    outval = 0
    # count = whiteImage.GetNumberOfPoints()
    # for i in range(count):
    #     whiteImage.GetPointData().GetScalars().SetTuple1(i, inval)

    # 上述for循环的简便替代方法
    whiteImage.GetPointData().GetScalars().Fill(255)

    extrude = vtkLinearExtrusionFilter()
    extrude.SetInputData(circle)
    extrude.SetScaleFactor(1.0)  # 设置挤压的比例因子
    extrude.SetExtrusionTypeToVectorExtrusion()  # 设置为向量挤压,而非几何体表面的法线定义
    extrude.SetVector(0, 0, 1)  # 设置挤压的向量
    extrude.Update()

    pol2stenc = vtkPolyDataToImageStencil()
    pol2stenc.SetInputConnection(extrude.GetOutputPort())
    pol2stenc.SetTolerance(0)  # 帮助过滤垂直面
    pol2stenc.SetOutputOrigin(origin)
    pol2stenc.SetOutputSpacing(spacing)
    pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent())
    pol2stenc.Update()

    imgstenc = vtkImageStencil()
    """
    tkImageStencil 是另一个关键过滤器,它接收一个图像作为输入,并根据一个模板(Stencil)修改该图像的像素值。
    """
    imgstenc.SetInputData(whiteImage)
    imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
    imgstenc.ReverseStencilOff()
    imgstenc.SetBackgroundValue(outval)
    imgstenc.Update()

    imageWriter = vtkMetaImageWriter()
    imageWriter.SetFileName('labelImage.mhd')
    imageWriter.SetInputConnection(imgstenc.GetOutputPort())
    imageWriter.Write()

    imageWriter = vtkPNGWriter()
    imageWriter.SetFileName('labelImage.png')
    imageWriter.SetInputConnection(imgstenc.GetOutputPort())
    imageWriter.Write()

if __name__ == '__main__':
    main()
相关推荐
想会飞的蒲公英2 小时前
计算机怎样读取中文文本:编码、清洗与标准化
人工智能·python·自然语言处理
SeaTunnel3 小时前
从 Python Script 地狱到标准化数据集成框架
大数据·开发语言·python·程序员·代码·seatunnel
深度研习笔记3 小时前
OpenCV工业视觉实战09|项目EXE打包+工控机无环境部署+后台常驻运行,彻底脱离Python环境,完成项目最终交付
python·opencv·webpack
CCPC不拿奖不改名4 小时前
大模型推理架构与开源生态知识整理
数据库·windows·python·架构·langchain·开源·github
Marst Code4 小时前
(python)2026Plotly 库评估:交互式可视化到底值不值得引入?
开发语言·python
databook4 小时前
当散点图不够用时:用 t-SNE 可视化多维数据
python·数据分析·数据可视化
我的xiaodoujiao7 小时前
快速学习Python基础知识详细图文教程9--函数进阶
开发语言·python·学习·测试工具
weixin_408099677 小时前
2026 图片去水印 API 接口完全指南:一键去除图片水印(附 Python/Java/PHP/C# 示例)
java·python·php·图片处理·api调用·图片去水印·石榴智能
去码头整点薯条ing7 小时前
某当网登录滑块【协议+OCR】
爬虫·python·ocr
赶紧写完去睡觉8 小时前
Anaconda 创建虚拟环境与使用
python·pycharm·conda