准备工作
最近需要开始捡起图像处理,厌倦了C++的各种编译,直接使用python vtk来实现,读取序列图像并显示。
pip install vtk
从多个单张dcm文件生成一个mhd/mha文件,作为程序的输入
代码实现
# -*- coding: UTF-8 -*-
import vtk
import sys
path = './mhd'
file_name = './mhd/1.mha'
reader = vtk.vtkMetaImageReader()
reader.SetFileName(file_name)
reader.Update()
def keyboard_callback_func(obj, event_id ):
print(obj.GetKeySym() )
cur_slice = viewer.GetSlice()
if( obj.GetKeySym() == 'Right'):
cur_slice = (cur_slice + 1) % (viewer.GetSliceMax()+1)
viewer.SetSlice( cur_slice )
if( obj.GetKeySym() == 'Left'):
cur_slice = (cur_slice + viewer.GetSliceMax()) % (viewer.GetSliceMax()+1)
viewer.SetSlice( cur_slice )
msg = (' %d / %d '% ( cur_slice + 1, viewer.GetSliceMax()+1 ) )
# print(msg)
sliceTextMapper.SetInput( msg)
viewer.Render()
# visualize
viewer = vtk.vtkImageViewer2()
viewer.SetInputConnection( reader.GetOutputPort() )
# viewer.SetSlice(1)
#slice status message
sliceTextProp = vtk.vtkTextProperty()
sliceTextProp.SetFontFamilyToCourier()
sliceTextProp.SetFontSize(20)
sliceTextProp.SetVerticalJustificationToBottom()
sliceTextProp.SetJustificationToLeft()
sliceTextMapper = vtk.vtkTextMapper()
cur_slice = viewer.GetSlice()
print('cur_slice = ' , cur_slice, ' viewer.GetSliceMax() = ' , viewer.GetSliceMax())
msg = (' %d / %d '% ( viewer.GetSlice() + 1, viewer.GetSliceMax()+1 ) )
sliceTextMapper.SetInput( msg)
sliceTextActor = vtk.vtkActor2D()
sliceTextActor.SetMapper(sliceTextMapper)
sliceTextActor.SetPosition(15, 10)
window_interactor = vtk.vtkRenderWindowInteractor()
viewer.SetupInteractor(window_interactor)
viewer.GetRenderer().AddActor2D(sliceTextActor)
#
window_interactor.AddObserver( vtk.vtkCommand.KeyPressEvent, keyboard_callback_func)
window_interactor.Initialize()
viewer.Render()
viewer.GetRenderer().ResetCamera()
viewer.Render()
window_interactor.Start()
代码说明
使用vtkImageViewer2可以非常方便的显示图片,详细可以参见其他文章
https://blog.csdn.net/shenziheng1/article/details/54565337
默认的vtkImageViewer2无法切换slice, 只能显示第一张slice。
使用 .AddObserver来对键盘操作进行响应。
C++中需要定义vtkCommandCallback 来进行实现,python可以直接设置回调函数即可。
window_interactor.AddObserver( vtk.vtkCommand.KeyPressEvent, keyboard_callback_func)
keyboard_callback_func 的实现非常简单,先获取当前的slice,然后设置为下一个slice,最后viewer.Render() 即可。
运行结果
运行结果如下(我使用的图片包含3个slice,左右键实现slice切换):