使用Python+VTK获取3D体渲染模型任意角度切面(更新中)

2023-11-16

效果图

废话少说先上效果图,右边红色的plane是想要获取3D模型对应切面的平面,左边是这个切面的切片的图像。
效果图

实现目标

定义一个任意角度的切面,都能把体绘制模型的这个切面的图像获取,并且能够把这个切面图像转为numpy格式供其他逻辑继续处理。MPR三维重建只能获取xyz轴的切面无法满足任意角度切片的需求。

安装依赖

pip install vtk numpy opencv-python scipy

Code

体渲染的知识可以参考我上一篇文章:Python使用VTK对容积超声图像进行体绘制(三维重建)

import vtk
import numpy as np
import cv2
from vtkmodules.util.numpy_support import numpy_to_vtk, vtk_to_numpy
from scipy.ndimage import rotate # 3D旋转

# 定义原点vtk对象原点位置
origin = [0, 0, 0]
# 定义xyz旋转角度
x_angle = 0
y_angle = 0
z_angle = 0

# 导入3D模型, 根据自己场景调整, 最终类型是vtkImageData就可以
label_arr = np.load("./your_model.npy")
label_arr = rotate(label_arr, 180, axes=(0, 1), reshape=True, order=1, mode='constant', cval=0, prefilter=True)
label_arr = rotate(label_arr, -90, axes=(0, 2), reshape=True, order=1, mode='constant', cval=0, prefilter=True)

# numpy转为vtkTypeUInt8Array
vtk_data = numpy_to_vtk(label_arr.ravel(), array_type=vtk.VTK_UNSIGNED_CHAR)
# 获取模型尺寸
model_dims = label_arr.shape
# 定义一个vtkImageData数据对象, 作为vtkImageReslice的输入
image_data = vtk.vtkImageData()
# 设置vtkImageData的三维尺寸
image_data.SetDimensions(model_dims[2], model_dims[1], model_dims[0])
# 设置像素间隔
image_data.SetSpacing(1, 1, 1)
# 设置原点
image_data.SetOrigin(origin)
# 将数据导入vtkImageData数据对象
image_data.GetPointData().SetScalars(vtk_data)
# 定义vtkRenderer
renderer = vtk.vtkRenderer()
# 设置renderer相机焦点(x, y, z)
renderer.GetActiveCamera().SetFocalPoint((64, 90, 64))
# 设置renderer相机与焦点的距离(x, y, z + distance)
renderer.GetActiveCamera().SetPosition((64, 90, 630))
# 在水平面上旋转镜头10度
renderer.GetActiveCamera().Azimuth(-5)

# 创建一个vtkRenderWindow对象,用于显示vtkRenderer对象中的内容
render_window = vtk.vtkRenderWindow()
render_window.AddRenderer(renderer)
# 定义显示窗口尺寸
render_window.SetSize(640, 480)

# 创建一个vtkRenderWindowInteractor对象,用于处理交互事件
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(render_window)

# 定义xyz轴显示
axes = vtk.vtkAxesActor()
# 定义xyz轴长度
axes.SetTotalLength(250, 250, 250)
renderer.AddActor(axes)

# 定义一个平面与vtkImageReslice处于相同位姿,方便观察
plane_source = vtk.vtkPlaneSource()
# 设置原点
plane_source.SetOrigin(origin)
# 设置另外两个点, 三个点确定一个平面。同时定义方向与尺寸
plane_source.SetPoint1(168, 0, 0)
plane_source.SetPoint2(0, 168, 0)

# 使用vtkImageReslice获取切片
reslice = vtk.vtkImageReslice()
# 设置vtkImageReslice的输入
reslice.SetInputData(image_data)
# 设置插值方法
reslice.SetInterpolationModeToCubic()
# 设置间隔
reslice.SetOutputSpacing(1, 1, 1)
# 设置切片范围
reslice.SetOutputExtent(0, 128, 0, 128, 0, 0)
# 设置切片原点
reslice.SetResliceAxesOrigin(origin)

# 设置切片旋转角度
transform = vtk.vtkTransform()
transform.RotateX(x_angle)
transform.RotateY(y_angle)
transform.RotateZ(z_angle)

matrix = transform.GetMatrix()

reslice.SetResliceAxes(matrix)
reslice_axes = reslice.GetResliceAxes()

# 将平面与切片旋转角度保持一致
transform = vtk.vtkTransform()
transform.SetMatrix(reslice_axes)

transform_filter = vtk.vtkTransformPolyDataFilter()
transform_filter.SetInputConnection(plane_source.GetOutputPort())
transform_filter.SetTransform(transform)

mapper2 = vtk.vtkPolyDataMapper()
mapper2.SetInputConnection(transform_filter.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper2)
actor.GetProperty().SetColor(1, 0, 0)
renderer.AddActor(actor)

# 设置切片输出维度
reslice.SetOutputDimensionality(2)
# 必须执行Update(),否则无法获取切片
reslice.Update()

# 应用体绘制算法,生成三维模型
volume_mapper = vtk.vtkGPUVolumeRayCastMapper()
volume_mapper.SetInputData(image_data)

volume_property = vtk.vtkVolumeProperty()
opacity_transfer_function = vtk.vtkPiecewiseFunction()
opacity_transfer_function.AddPoint(15, 0.0)
opacity_transfer_function.AddPoint(255, 1.0)
volume_property.SetScalarOpacity(opacity_transfer_function)
color_transfer_function = vtk.vtkColorTransferFunction()
color_transfer_function.AddRGBPoint(0, 0.0, 0.0, 0.0)
color_transfer_function.AddRGBPoint(255, 1.0, 1.0, 1.0)
volume_property.SetColor(color_transfer_function)
volume_property.SetScalarOpacityUnitDistance(1)

volume = vtk.vtkVolume()
volume.SetMapper(volume_mapper)
volume.SetProperty(volume_property)


renderer.AddVolume(volume)
renderer.SetBackground(1.0, 1.0, 0.8)


# 将VTK图像数据转换为NumPy数组
vtk_image = reslice.GetOutput()
height, width, _ = vtk_image.GetDimensions()
sc = vtk_image.GetPointData().GetScalars()
numpy_array = np.array(vtk_to_numpy(sc))
img = numpy_array.reshape(height, width)

img = rotate(img, 180, axes=(0, 1), reshape=True, order=1, mode='constant', cval=0, prefilter=True)
img = cv2.resize(img, (480, 480), interpolation=cv2.INTER_CUBIC)
cv2.imshow('rotate', img)
interactor.Initialize()
render_window.Render()
interactor.Start()
cv2.waitKey(0)

其他需求

  1. Q: vtkImageReslice的切片图像能否显示在plane(vtkPlaneSource)上?
    A: 将vtkImageReslice转为纹理vtkTexture,然后设置为plane对应VtkActor的纹理。
  • 示例代码:
# 假设 reslice 是你的 vtkImageReslice 对象
reslice.Update()

# 创建纹理
texture = vtk.vtkTexture()
texture.SetInputData(reslice.GetOutput())

# 创建平面源
plane = vtk.vtkPlaneSource()

# 创建映射器并设置纹理坐标
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(plane.GetOutputPort())
mapper.SetScalarModeToUsePointData()

# 创建演员并设置纹理
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.SetTexture(texture)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Python+VTK获取3D体渲染模型任意角度切面(更新中) 的相关文章

  • Pygame读取MIDI输入

    我参考了Pygame MIDI 文档 https www pygame org docs ref midi html and 这段代码 https stackoverflow com questions 62983509 pygame mi
  • 打印 scrapy 请求的“响应”

    我正在尝试学习 scrapy 在遵循教程的同时 我正在尝试进行细微的调整 我想简单地从请求中获取响应内容 然后我会将响应传递到教程代码中 但我无法发出请求并获取响应内容 建议就好 from scrapy http import Respon
  • 如何计算正切和副法线?

    谈谈OpenGL着色语言 GLSL 中的凹凸贴图 镜面高光之类的东西 I have 顶点数组 例如 0 2 0 5 0 1 0 2 0 4 0 5 法线数组 例如 0 0 0 0 1 0 0 0 1 0 0 0 世界空间中点光源的位置 例如
  • Dask DataFrame 的逐行处理

    我需要处理一个大文件并更改一些值 我想做这样的事情 for index row in dataFrame iterrows foo doSomeStuffWith row lol doOtherStuffWith row dataFrame
  • 在 python-docx 中搜索和替换

    我有一个包含以下字符串的文档 模板 你好 我的名字是鲍勃 鲍勃是一个很好的名字 我想使用 python docx 打开此文档并使用 查找和替换 方法 如果存在 来更改每个字符串 Bob gt Mark 最后 我想生成一个新文档 其中包含字符
  • 无法包含外部 pandas 文档 Pycharm v--2018.1.2

    我无法包含外部 pandas 文档Pycharm v 2018 1 2 例如 numpy gt http docs scipy org doc numpy reference generated module name element na
  • 将一个时间序列插入到 pandas 中的另一个时间序列中

    我有一组定期测量的值 说 import pandas as pd import numpy as np rng pd date range 2013 01 01 periods 12 freq H data pd Series np ran
  • 使用Python将图像转换为十六进制格式

    我的下面有一个jpg文件tmp folder upload path tmp resized test jpg 我一直在使用下面的代码 Method 1 with open upload path rb as image file enco
  • Python 中的这种赋值方式叫什么? a = b = 真

    我知道关于元组拆包 http docs python org tutorial datastructures html tuples and sequences但是当一行中有多个等号时 这个赋值被称为什么 阿拉a b True 它总是让我有
  • Python unicode 字符代码?

    有没有办法将 Unicode 字符 插入 Python 3 中的字符串 例如 gt gt gt import unicode gt gt gt string This is a full block s unicode charcode U
  • 字典中列表中仅有的几个索引的总和

    如果我有这种类型的字典 a dictionary dog white 3 5 black 6 7 Brown 23 1 cat gray 5 6 brown 4 9 bird blue 3 5 green 1 2 yellow 4 9 mo
  • 使用循环将对象添加到列表(python)

    我正在尝试使用 while 循环将对象添加到列表中 基本上这就是我想做的 class x pass choice raw input pick what you want to do while choice 0 if choice 1 E
  • 使用 python 将文本发送到带有逗号分隔符的列

    如何使用分隔符 在 Excel 中将一列分成两列 并使用 python 命名标题 这是我的代码 import openpyxl w openpyxl load workbook DDdata xlsx active w active a a
  • urllib2.urlopen() 是否实际获取页面?

    当我使用 urllib2 urlopen 时 我在考虑它只是为了读取标题还是实际上带回整个网页 IE 是否真的通过 urlopen 调用或 read 调用获取 HTML 页面 handle urllib2 urlopen url html
  • Python Flask 是否定义了路由顺序?

    在我看来 我的设置类似于以下内容 app route test def test app route
  • WindowsError:[错误 5] 访问被拒绝

    我一直在尝试终止一个进程 但我的所有选项都给出了 Windows 访问被拒绝错误 我通过以下方式打开进程 一个python脚本 test subprocess Popen sys executable testsc py 我想杀死那个进程
  • Python模块单元测试的最佳文件结构组织?

    遗憾的是 我发现有太多方法可以在 Python 中保存单元测试 而且它们通常没有很好的文档记录 我正在寻找一种 终极 结构 它可以满足以下大部分要求 be discoverable by test frameworks including
  • CSV 在列中查找最大值并附加新数据

    大约两个小时前 我问了一个关于从网站读取和写入数据的问题 从那时起 我花了最后两个小时试图找到一种方法来从输出的 A 列读取最大日期值 将该值与刷新的网站数据进行比较 并将任何新数据附加到 csv 文件而不覆盖旧的或创建重复项 目前 100
  • 从 dask 数据框中的日期时间序列获取年份和星期?

    如果我有一个 Pandas 数据框和一个日期时间类型的列 我可以按如下方式获取年份 df year df date dt year 对于 dask 数据框 这是行不通的 如果我先计算 像这样 df year df date compute
  • 如何识别图形线条

    我有以下格式的路径的 x y 数据 示例仅用于说明 seq p1 p2 0 20 2 3 1 20 2 4 2 20 4 4 3 22 5 5 4 22 5 6 5 23 6 2 6 23 6 3 7 23 6 4 每条路径都有多个点 它们

随机推荐

  • 关于TextView和ImageView的背景及透明设置小结

    关于TextView和ImageView的背景及透明设置小结 关于ImageView的相关设置 设置背景颜色 ImageView setBackgroundColor android graphics Color parseColor f3
  • MySQL中Char和VarChar的区别

    VarChar VARCHAR类型用于存储可变长字符串 是最常见的字符串数据类型 它比定长类型更节省空间 因为它仅使用必要的空间 例如 越短的字符串使用越少的空间 有一种情况例外 如果MySQL表使用ROW FORMAT FIXED创建的话
  • linux开机自动挂载配置文件/etc/fstab

    如果我们想实现开机自动挂载某设备 只要修改 etc fstab文件即可 文件挂载的配置文件 etc fstab 查看此文件可知 每行定义一个要挂载的文件系统 其每行的格式如下 要挂载的设备或伪文件系统 挂载点 文件系统类型 挂载选项 转储频
  • Go []byte to a C *char

    https stackoverflow com questions 35673161 convert go byte to a c char ok b buf Bytes rc C the function unsafe Pointer b
  • c语言的标识符可分为哪3种字符,c语言标识符有哪三类?

    在计算机编程语言中 标识符是用户编程时使用的名字 用于给变量 常量 函数 语句块等命名 以建立起名称与使用之间的关系 标识符通常由字母和数字以及其它字符构成 c语言标识符的分类 C语言中标识符有三类 分别是 关键字 预定义标识符和用户标识符
  • MyBatis中resultMap解决映射关系(多对一、一对多)

    一 多对一映射处理 查询员工信息以及员工所对应的部门信息 public class Emp private Integer eid private String empName private Integer age private Str
  • 神经网络matlab工具箱有关参数设置

    1 常见参数 net trainParam epochs 最大训练次数 net trainParam goal 训练要求精度net trainParam lr 学习速率net trainParam show 显示训练迭代过程net trai
  • 如何使用远程仓库进行团队合作

    前言 如若我们的远程仓库又有了一名新的开发者 这时 新的开发者需要拉取远程仓库与其他开发者合作 文章目录 如何拉取远程仓库到本地仓库 git方法 clone远程分支 获取远程其他分支 Tortoise Git方法 clone远程分支 VS2
  • K8S部署前后端分离项目并支持Mysql和Redis数据持久化保存

    Springboot Vue Mysql Redis 文章目录 前端 1 default conf文件 2 创建Dockerfile 生成镜像 依赖nginx挂载配置文件 3 执行完以上步骤后 进行build tag push远程仓库 4
  • 软件质量管理-考试复习总结

    1 软件工程发展 软件开发的四大本质难题 不可见性 复杂性 一致性 可变性 除了不可见性以外 其他三个本质难题因项目而异 四大本质难题互动促进 可以缓解 但是不能彻底解决 软件危机 落后的软件生产方式无法满足迅速增长的计算机软件需求 从而导
  • cartographer-ros阅读梳理(一)数据接收部分

    一 前言 前段时间去忙了些杂活项目 调调代码测测算法 这几天闲下来准备硕士开题的事情 SLAM方面能开展的工作大家都大同小异 之前在梳理实验室程序的时候遇到一些阻碍 有一部分是引用的cartographer的东西 师兄把那部分的代码阉的千奇
  • upload-labs靶场-Pass-04关-思路以及过程

    开始前的小准备 upload labs靶场 是PHP环境运行的 所以我准备了一个PHP脚本和一张图片 图片好准备 PHP脚本如果不想写的话可以用我的这个获取当前时间的PHP脚本 还需要准备一个 htaccess下面的 脚本 是你上传文件的名
  • Python+Selenium- 环境搭建

    一 Selenium 简介 Selenium是目前最流行的web自动化测试工具 也常用于网络爬虫 已经更新到3以上的版本 1 组件 它提供了以下web自动化测试组件 Selenium IDE Firefox浏览器的一个插件 提供简单的脚本录
  • mysql 触发器 sql_mysql动态SQL的运用 (trigger、function、procedure)

    mysql中 当你在trigger function中编写动态的sql时 编译时就会出现 Error 1336 Dynamic SQL is not allowed in stored function or trigger trigger
  • Linq使用方法

    Linq是一种面向对象的查询方式 它和SQL语句及其类似 sql写法 select from 表 Linq写法 from n in 数据源 select n 为什么不跟sql写法一样将select一同写在语句的开头呢 主要是当时做IDE时考
  • elasticsearch安装部署和期间遇到的问题和解决

    因为工作需要用到elasticsearch 最近在测试环境部署单机版的elasticsearch服务 可以说是相当的波折 一个问题解决一个问题又来 都要吐血了已经 还好最终都得以解决 解决后那一刻真尼玛的爽啊啊啊 问题列表 elastics
  • 将本地项目上传到gitlab

    1 安装git https git scm com downloads 2 新建工程 3 创建密钥 a 桌面右键 b cd ssh 如果提示 No such file or directory 你可以手动的创建一个 ssh文件夹即可 mkd
  • 日本“性爱机器人”上线1小时被抢空

    来源 正商参阅 局座召忠 李开复 蒋东平网络等 日本 妻子 机器人被哄抢 不要房车不要彩礼 日本研发出一款 美女机器人 将其命名为 妻子 光看她的外形 你能识别出她其实只是一个机器人吗 60分钟售出万台 第一点就是人们所关注的价格方面 在日
  • node.js 环境安装(windows)

    准备需要安装的电脑 下载node js的安装包 地址 http nodejs cn download 下载的安装包双击打开 依次按照下图指示执行 下图点击接受 后下一步 下图 根据实际情况选择安装位置 如果记不住建议选择默认位置 直接点击n
  • 使用Python+VTK获取3D体渲染模型任意角度切面(更新中)

    目录 效果图 实现目标 安装依赖 Code 其他需求 效果图 废话少说先上效果图 右边红色的plane是想要获取3D模型对应切面的平面 左边是这个切面的切片的图像 实现目标 定义一个任意角度的切面 都能把体绘制模型的这个切面的图像获取 并且