Python VTK管线中如何插入转换得到的VTK数组实现DICOM体绘制?
解决方案
核心实现代码
你不需要再调用vtkDICOMImageReader,直接把转换好的VTK数组绑定到vtkImageData对象即可接入VTK管线,修改后的完整实现如下:
import vtk import pydicom from vtk.util import numpy_support # 读取DICOM并转换为VTK数组 file_path = r"C:\Users\I_0001" dicom_data = pydicom.read_file(file_path) pixel_array = dicom_data.pixel_array dims = pixel_array.shape # numpy数组转VTK数组 vtk_array = numpy_support.numpy_to_vtk( num_array=pixel_array.ravel(), deep=True, array_type=vtk.VTK_FLOAT ) # 创建vtkImageData对象作为管线输入 image_data = vtk.vtkImageData() # 适配维度顺序:numpy输出顺序为(行数, 列数),VTK要求顺序为(列数, 行数, 层数) if len(dims) == 2: # 单张DICOM image_data.SetDimensions(dims[1], dims[0], 1) else: # DICOM序列 image_data.SetDimensions(dims[2], dims[1], dims[0]) image_data.GetPointData().SetScalars(vtk_array) # 配置空间参数(体绘制必须配置,否则显示比例异常) spacing_x, spacing_y = dicom_data.PixelSpacing spacing_z = getattr(dicom_data, 'SliceThickness', 1.0) image_data.SetSpacing(float(spacing_x), float(spacing_y), float(spacing_z)) origin = [float(x) for x in dicom_data.ImagePositionPatient] image_data.SetOrigin(origin) # 接入管线两种方式二选一: ## 方式1:适配原有SetInputConnection(xxx.GetOutputPort())写法 producer = vtk.vtkTrivialProducer() producer.SetOutput(image_data) mapper = vtk.vtkDataSetMapper() mapper.SetInputConnection(producer.GetOutputPort()) ## 方式2:直接用SetInputData,不需要额外封装 # mapper = vtk.vtkDataSetMapper() # mapper.SetInputData(image_data)
补充说明
- 你之前调用
vtkDICOMImageReader报错是因为SetDirectoryName仅接收存放DICOM序列的文件夹路径,如果你要读取单个DICOM文件,需要调用SetFileName接口传入单个文件路径。 - 如果是读取DICOM序列而非单个文件,需要先用pydicom按切片位置排序所有DICOM的像素数组,拼接成三维numpy数组后再做转换,否则三维体数据的层顺序会出错。
内容的提问来源于stack exchange,提问作者user42
相关产品推荐
相关产品推荐

