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()
相关推荐
傻啦嘿哟1 小时前
某招聘平台爬虫:爬取招聘岗位数据,分析各城市薪资水平
开发语言·爬虫·python
2501_933670791 小时前
2026秋招量化分析岗技能栈:Python、SQL、统计建模、回测项目怎么准备
开发语言·python·sql
2601_962077601 小时前
python Dejavu库快速识别音频指纹实例探究
python·音乐识别·dejavu库·音频指纹识别·实例探究
科技苑1 小时前
如何用Python编程实现一个简单的Web爬虫?
人工智能·python
dayDayupbetter2 小时前
Visual C++ 2010安装与使用高手秘籍
python
隐擎fox2 小时前
深入理解网络传输层安全:TLS 指纹识别(JA3/JA4)原理与 Python 协议层检测实战
爬虫·python·网络协议·安全·网络安全·https
医疗信息化王工2 小时前
DataForge:基于 Python 的数据库批量导出 Excel 工具——从架构到部署的全流程实战
数据库·python·excel
小玮看世界3 小时前
[Python]从合并区间到传感器融合区:合并区间在传感器区域融合的实际落地
开发语言·python
Java陈序员3 小时前
轻量运维面板!一款现代化的服务器控制面板工具!
运维·服务器·python·react.js·github
2601_962097363 小时前
1. 使用 C 或 C++ 扩展 Python
python·api·c·引用计数·扩展模块