-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
204 lines (164 loc) · 8.17 KB
/
main.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
"""
Created on Mon Oct 22 15:07:58 2018
@author: domdo
"""
# External libraries
import sys
from PyQt5 import Qt
import time
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
# Own class objects
import mdf_reader
import mha_reader
import diagram_class
import interface
from vtk_class import vtk_pipeline
class MainWindow(Qt.QMainWindow):
def __init__(self, parent = None):
Qt.QMainWindow.__init__(self, parent)
# Adjust window size
self.resize(1400, 900)
# Time per image; playback speed is intitially set to this
# value but can be changed during visualization using the playback
# speed slider and the play/pause button. A frame rate
# of 21.5ms can only be achieved using a very dedicated hardware setup
self.t_ms = 21.5
# Dimension of vtk image data to be visualized. The source data
# will be interpolated to this size if variable "interpolation" is set to true,
# otherwise original image dimensions of source will be used. Can be
# changed during visualization using the UI
self.interpolation = False
self.dims = [25, 25, 25]
# Create diagram class objects. Functions:
# - analyze image values of image series to find adequate
# visualization parameters for sliders
# - draw image value histogram
# - draw lookup table curve
self.diag = diagram_class.plotDiagrams()
# Creation of vtk class object to invoke the buildup
# of visualization pipeline
self.vtk_pip = vtk_pipeline()
# Create QT display interfaces that show visualization pipeline óutput
self.frame = Qt.QFrame()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.setCentralWidget(self.frame)
# Defintion of standard min/max image values and the starting
# positions of the sliders (sl = slider, pos = position,
# bl = bolus, rm = roadmap, op = opacity, ri = ramp intervall,
# th = threshold). The values will be used if pre image analysis
# is deactivated.
self.default_min_value = 0.0
self.default_max_value = 0.1
self.min_value = self.default_min_value
self.max_value = self.default_max_value
self.sl_pos_th_bl = 0.3
self.sl_pos_th_rm = 0.3
self.sl_pos_op_bl = 0.3
self.sl_pos_op_rm = 0.3
self.sl_pos_ri_bl = 0.3
self.sl_pos_ri_rm = 0.3
self.updateVisualizationParameters()
# Setup of QT GUI
interface.initUI(self)
# Connect VTK pipeline renderer to QT frame display
self.vtkWidget.GetRenderWindow().AddRenderer(self.vtk_pip.ren)
# Disable all interface widgets until source data is successfully loaded
# (except load buttons)
interface.enableDisableButtons(self,False)
self.button_load_mdf_file.setEnabled(True)
self.button_load_mha_files.setEnabled(True)
self.button_saving_directory_screenshots.setEnabled(True)
self.combobox_pre_image_analysis.setEnabled(True)
# Set main window visible and access render window interactor
self.show()
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.vtk_pip.iren = self.iren
self.vtk_pip.vtk_widget = self.vtkWidget
self.iren.Initialize()
self.iren.Start()
# Create timer to constantly update VTK pipeline.
# Timer can be paused / started via the QT pause / play button
self.timer = Qt.QTimer(self)
self.timer.setSingleShot(False)
self.timer.timeout.connect(self.updateStatus)
self.previous_time = time.time()
# Create timer to constantly update the display of camera position
# and focal point on the visualization screen
self.timer_cp = Qt.QTimer(self)
self.timer_cp.setSingleShot(False)
self.timer_cp.timeout.connect(self.displayPos)
self.timer_cp.start(1)
# Defintion of directory variables
self.directory_output = None
self.directory_mha = None
self.directory_mdf = None
def updateStatus(self):
"""
This function updates the VTK pipeline by feeding the
volume mapper object the subsequent image data object.
It will be constantly invoked by the QT timer object.
The corresponding image data is aquired using the mdf / mha reader.
"""
# Defines number of image that will be visualized
self.image_count = self.image_count + 1
# Reset image count if out of boundary
# --> Image sequence restarts from the beginning
if self.image_count > self.number_of_total_images:
self.image_count = 1
if self.source_data_format == 'mha':
self.temporary_image = mha_reader.createVTKDataFromMHAFile(self.directory_mha, self.image_count, self.interpolation, self.dims)
if self.source_data_format == 'mdf':
self.temporary_image = mdf_reader.createVTKDataFromHDF(self.directory_mdf, self.image_count-1, self.interpolation, self.dims)
self.vtk_pip.volumeMapperBl.SetInputData(self.temporary_image)
# Buildup of roadmap. Gets deactivated if whole cycle has been
# completed
if self.checkbox_rm_buildup.isChecked() and \
self.rm_counter <= self.number_of_total_images:
self.vtk_pip.rmBuildup(self.temporary_image)
self.rm_counter = self.rm_counter+1
# Computation of real frame rate
self.label_frame_rate_display.setText(str(round(1.0 / (time.time() - self.previous_time), 2)))
self.previous_time = time.time()
# Update image count display
image_count = str(self.image_count) + ' / ' + str(self.number_of_total_images)
self.label_image_count_display.setText(str(image_count) )
# Save screenshots of visualized MPI data if checked
if self.checkbox_save_images.isChecked():
interface.screenshotAndSave(self)
# Render image
self.iren.Initialize()
self.iren.Start()
def displayPos(self):
"""
This function is constantly invoked by timer_cp and thereby
continously updates the camera whereabouts (camera position, focal
point)
"""
pos = self.vtk_pip.ren.GetActiveCamera().GetPosition()
fp = self.vtk_pip.ren.GetActiveCamera().GetFocalPoint()
text = 'Camera: ' + str( round(pos[0], 1)) + ', ' \
+ str( round(pos[1], 1)) + ', ' + str( round(pos[2], 1)) \
+' \nFocal point: ' + str( round(fp[0], 1)) + ', ' \
+ str( round(fp[1], 1)) + ', ' + str( round(fp[2], 1))
self.vtk_pip.text_actor.SetInput( text )
def updateVisualizationParameters(self):
# Compute visualization parameters
diff = self.max_value - self.min_value
self.op_max_bl = self.vtk_pip.op_max_bl = self.diag.op_max_bl = \
self.sl_pos_th_bl
self.op_max_rm = self.vtk_pip.op_max_rm = self.diag.op_max_rm = \
self.sl_pos_th_rm
self.th_bl = self.vtk_pip.th_bl = self.diag.th_bl = \
self.min_value + diff * self.sl_pos_th_bl
self.th_rm = self.vtk_pip.th_rm = self.diag.th_rm = \
self.min_value + diff * self.sl_pos_th_rm
self.ri_bl = self.vtk_pip.ri_bl = self.diag.ri_bl = \
diff * self.sl_pos_ri_bl
self.ri_rm = self.vtk_pip.ri_rm = self.diag.ri_rm = \
diff * self.sl_pos_ri_rm
self.vtk_pip.min_value = self.diag.min_value = self.min_value
self.vtk_pip.max_value = self.diag.max_value = self.max_value
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())