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()
相关推荐
Sagittarius_A*4 小时前
形态学与多尺度处理:计算机视觉中图像形状与尺度的基础处理框架【计算机视觉】
图像处理·人工智能·python·opencv·计算机视觉
m0_561359675 小时前
使用PyQt5创建现代化的桌面应用程序
jvm·数据库·python
2301_790300965 小时前
用Python实现自动化的Web测试(Selenium)
jvm·数据库·python
自可乐5 小时前
LangGraph从入门到精通:构建智能Agent的完整指南
人工智能·python·机器学习
m0_561359675 小时前
使用Docker容器化你的Python应用
jvm·数据库·python
逻极5 小时前
Moltbot 快速入门指南(2026年1月最新版)
python·ai·aigc·智能助手·clawdbot·molbot
AAD555888995 小时前
基于Deformable-DETR的植物叶片病害检测
python
Cemtery1165 小时前
Day40 早停策略和模型权重的保存
人工智能·python·深度学习·机器学习
Jackson@ML5 小时前
[Kimi重磅出击!]用Kimi Code智能高效开发Web应用程序指南
ide·python·kimi code
u0109272715 小时前
使用Scrapy框架构建分布式爬虫
jvm·数据库·python