-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathQSliceViewWidget.py
executable file
·114 lines (98 loc) · 3.98 KB
/
QSliceViewWidget.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import sys
import vtk
from QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PySide2.QtCore import Qt, QSize
from PySide2.QtWidgets import (QDesktopWidget,
QApplication,
QWidget,
QSlider,
QVBoxLayout)
class QSliceViewWidget(QWidget):
"""
sagittal
coronal
transverse
"""
def __init__(self, orientation='transverse', parent=None):
super(QSliceViewWidget, self).__init__(parent)
# set up vtk pipeline and create vtkWidget
colors = vtk.vtkNamedColors()
self.orientation = orientation
self.viewer = vtk.vtkImageViewer2()
self.orientations = {'coronal': 0,
'sagittal': 1,
'transverse': 2}
self.viewer.SetSliceOrientation(self.orientations[self.orientation])
# get&set the camera
self.camera = self.viewer.GetRenderer().GetActiveCamera()
ras = [[-1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, -1.0]]
self.camera.SetPosition(ras[self.orientations[self.orientation]])
self.camera.ParallelProjectionOn()
self.iren = vtk.vtkGenericRenderWindowInteractor()
self.iren.SetRenderWindow(self.viewer.GetRenderWindow())
kw = {
'rw': self.viewer.GetRenderWindow(),
'iren': self.iren
}
self.vtkWidget = QVTKRenderWindowInteractor(parent, **kw)
# create QSlider
self.sliderWidget = QSlider(Qt.Horizontal)
# create the MainLayout of the whole widget
self.MainLayout = QVBoxLayout()
self.MainLayout.addWidget(self.sliderWidget)
self.MainLayout.addWidget(self.vtkWidget)
self.setLayout(self.MainLayout)
# set the signal and slot
self.sliderWidget.valueChanged.connect(self.slider_changed)
def set_data_reader(self, reader, use_port=False):
self.viewer.SetInputData(reader.GetOutput())
matrix = reader.GetSFormMatrix()
self.viewer.GetImageActor().PokeMatrix(matrix)
def slider_offset(self, offset):
self.sliderWidget.setMaximum(self.viewer.GetSliceMax())
self.sliderWidget.setMinimum(self.viewer.GetSliceMin())
mid = (self.viewer.GetSliceMax()-self.viewer.GetSliceMin())/2
self.sliderWidget.setValue(mid)
def start_render(self):
# initiate slider
self._init_slider()
# set InteractorStyle
interactor_style = vtk.vtkInteractorStyleImage()
self.vtkWidget.SetInteractorStyle(interactor_style)
# start render and interactor
self.vtkWidget.Initialize()
self.vtkWidget.Start()
# set camera
self.viewer.GetRenderer().ResetCamera()
def _init_slider(self):
self.sliderWidget.setMaximum(self.viewer.GetSliceMax())
self.sliderWidget.setMinimum(self.viewer.GetSliceMin())
mid = (self.viewer.GetSliceMax()-self.viewer.GetSliceMin())/2
self.sliderWidget.setValue(mid)
# signal and slot
def slider_changed(self):
self.viewer.SetSlice(self.sliderWidget.value())
if __name__ == '__main__':
app = QApplication(sys.argv)
# raise the error log
log_file = 'log.txt'
with open(log_file, 'wb') as f:
f.truncate()
file_output_window = vtk.vtkFileOutputWindow()
file_output_window.SetFileName(log_file)
vtk.vtkFileOutputWindow.SetInstance(file_output_window)
# 'coronal': 0,
# 'sagittal': 1,
# 'transverse': 2
SingleView = QSliceViewWidget(orientation='coronal')
file_name = "test_data.nii.gz"
reader = vtk.vtkNIFTIImageReader()
reader.SetFileName(file_name)
reader.Update()
SingleView.set_data_reader(reader)
SingleView.start_render()
SingleView.resize(QSize(800, 600))
SingleView.show()
sys.exit(app.exec_())