首页 新闻 会员 周边 捐助

python vtk dicom 三维重建肺部组织如何正确提取

0
悬赏园豆:5 [待解决问题]

开发环境
python 3.10.11
vtk 9.3.0

目前重建出来的图

代码

0.读取DICOM数据

reader = vtk.vtkDICOMImageReader()
reader.SetDirectoryName(path)
reader.Update()


#  --------- 绘制肺部 ------------


# 1. 阈值粗分割(-1000 ~ -200 HU)
threshold = vtk.vtkImageThreshold()
threshold.SetInputConnection(reader.GetOutputPort())
threshold.ThresholdBetween(-1000, -200)
threshold.ReplaceInOn()
threshold.SetInValue(1)  # 肺部标记为1
threshold.ReplaceOutOn()
threshold.SetOutValue(0) # 非肺部标记为0
threshold.Update()
print('1. 阈值粗分割(-1000 ~ -200 HU)')

# 3. 提取最大连通域(去除气管)
# connectivity = vtk.vtkImageConnectivityFilter()
# connectivity.SetInputConnection(threshold.GetOutputPort())
# connectivity.SetExtractionModeToLargestRegion()
# connectivity.Update()
# print('3. 提取最大连通域(去除气管)')

# 2. 去噪(开运算:先腐蚀后膨胀)
erode = vtk.vtkImageContinuousErode3D()
erode.SetInputConnection(threshold.GetOutputPort())
erode.SetKernelSize(2,2,2)
erode.Update()
print('2. 去噪(开运算:先腐蚀)vtkImageContinuousErode3D')
dilate = vtk.vtkImageContinuousDilate3D()
dilate.SetInputConnection(erode.GetOutputPort())
dilate.SetKernelSize(2,2,2)
dilate.Update()
print('2. 去噪(开运算:后膨胀)vtkImageContinuousDilate3D')



#  ----- 绘制肺部结束 -------

# print(dilate.GetOutputPort().GetNumberOfPoints())
# 1.面绘制 等面值
marching_cubes = vtk.vtkMarchingCubes()
marching_cubes.SetInputConnection(dilate.GetOutputPort())
# 空气:-1000
# 脂肪:-50~-100
# 水/软组织:0~100
# 骨骼:300~2000
# marching_cubes.SetValue(0,300) # 300对应骨骼
# marching_cubes.SetValue(1,75) # -300对应软组织
marching_cubes.SetValue(0, 0.5)  # 适应浮点数据
# marching_cubes.SetValue(1, 1.5)
marching_cubes.Update()
print('1.面绘制 等面值')

# 检查是否有面数据生成
if marching_cubes.GetOutput().GetNumberOfPoints() == 0:
    raise ValueError("Marching Cubes未生成任何数据,请检查前面的处理步骤。")

# 2. 创建平滑过滤器
smoother = vtk.vtkSmoothPolyDataFilter()
smoother.SetInputConnection(marching_cubes.GetOutputPort())
smoother.SetNumberOfIterations(50)
# print('2. 创建平滑过滤器')
# 2.1 创建颜色查找表
# lookup_table = vtk.vtkLookupTable()
# lookup_table.SetNumberOfTableValues(2)  # 对应2个阈值
# lookup_table.SetTableValue(0, 1, 0, 0)  # 阈值100 → 红色
# lookup_table.SetTableValue(1, 0, 1, 0)  # 阈值200 → 绿色
# lookup_table.Build()

# 3.创建 Mapper 并启用颜色映射
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(smoother.GetOutputPort())
# 关闭mapper颜色映射 不然 actor 设置颜色会失效
# mapper.ScalarVisibilityOff()
# mapper.SetLookupTable(lookup_table)
mapper.ScalarVisibilityOff()  # 启用标量着色
print('3.创建 Mapper 并启用颜色映射')

# 创建并配置一个可视化对象
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# 设置颜色 (如何开启了 mapper.ScalarVisibilityOn ,就会失效)
actor.GetProperty().SetColor(1,1,1) 
# 设置透明度
actor.GetProperty().SetOpacity(1)
print('创建并配置一个可视化对象')

# 渲染设置
renderer = vtk.vtkRenderer()
render_window = vtk.vtkRenderWindow()
render_window.AddRenderer(renderer)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(render_window)

renderer.AddActor(actor)
renderer.SetBackground(0, 0, 0)
render_window.SetSize(800, 600)
render_window.Render()
interactor.Start()
zpaustin的主页 zpaustin | 初学一级 | 园豆:48
提问于:2025-04-10 15:17
< >
分享
所有回答(1)
0

3. 提取最大连通域(去除气管)

connectivity = vtk.vtkImageConnectivityFilter()

connectivity.SetInputConnection(threshold.GetOutputPort())

connectivity.SetExtractionModeToLargestRegion()

connectivity.Update()

这个忘记恢复了。。。

zpaustin | 园豆:48 (初学一级) | 2025-04-10 16:47
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册