-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplot_nifti.py
More file actions
159 lines (121 loc) · 5.41 KB
/
plot_nifti.py
File metadata and controls
159 lines (121 loc) · 5.41 KB
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
#!/usr/bin/env python3
# This code takes a nifti file as input and generates a 3D model as output
import SimpleITK as sitk
import vtk
from lookuptable import get_lut_1, get_lut_2, get_lut_3
# Get vtk-file from nifti-image/numpy array
def get_vtk(data, voxelsize):
data = data.astype('uint8')
bytes_data = data.tobytes()
imageimport = vtk.vtkImageImport()
imageimport.CopyImportVoidPointer(bytes_data, len(bytes_data))
imageimport.SetDataSpacing(voxelsize[0],voxelsize[1],voxelsize[2])
imageimport.SetDataOrigin(0,0,0)
imageimport.SetDataScalarType(3) #='VTK_UNSIGNED_CHAR'
imageimport.SetNumberOfScalarComponents(1)
data_shape = data.shape
imageimport.SetWholeExtent(0, data_shape[2] - 1, 0, data_shape[1] - 1, 0, data_shape[0]-1)
imageimport.SetDataExtentToWholeExtent()
return imageimport
# Plot the brain
def map_brain_surface(data, intensity, voxelsize, min_val, max_val, colors):
global count
print(count)
count += 1
imageimport = get_vtk(data, voxelsize)
# Lookuptable for colors
if colors=='redyellowwhitegreenblue':
colortransfer, lut = get_lut_1(min_val, max_val)
elif colors=='redwhiteblue':
colortransfer, lut = get_lut_2(min_val, max_val)
elif colors=='redwhite':
colortransfer, lut = get_lut_3(min_val, max_val)
contourFilter = vtk.vtkContourFilter()
contourFilter.SetInputConnection(imageimport.GetOutputPort())
contourFilter.SetValue(0, intensity)
mapper = vtk.vtkPolyDataMapper()
mapper.SetLookupTable(colortransfer)
mapper.SetInputConnection(contourFilter.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
return actor, lut
def render_brain(actor, lut, scalarBar, png_name):
renderer = vtk.vtkRenderer()
for a in actor:
renderer.AddActor(a)
if scalarbar:
scalarBar = vtk.vtkScalarBarActor()
scalarBar.SetLookupTable(lut)
scalarBar.SetTitle("score")
scalarBar.SetNumberOfLabels(5)
scalarBar.SetMaximumNumberOfColors(200)
renderer.AddActor2D(scalarBar)
renderer.SetBackground(0,0,0) #black #(1,1,1)=white
## Define the camera position
# renderer.camera = vtk.vtkCamera()
# renderer.ResetCamera()
# camera = renderer.GetActiveCamera()
# camera.SetThickness(600)
# camera.SetPosition(150, 450, 250)
# camera.SetRoll(90)
# RenderWindow
renderwindow = vtk.vtkRenderWindow()
renderwindow.AddRenderer(renderer)
renderwindow.SetAlphaBitPlanes(1) # for transparent background in the screenshots
# Create the RendererWindowInteractor and show the vtk_file
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(renderwindow)
renderwindow.SetSize(1000,600)
renderwindow.Render()
# Get a screenshot with transparent background
windowtoifilter = vtk.vtkWindowToImageFilter()
windowtoifilter.SetInput(renderwindow)
windowtoifilter.SetInputBufferTypeToRGBA()
windowtoifilter.Update()
writer = vtk.vtkPNGWriter()
png_name = './plots/'+png_name
writer.SetFileName(png_name)
writer.SetInputData(windowtoifilter.GetOutput())
if save_mode:
writer.Write()
else:
interactor.Start()
def main(filename, min_val, max_val, scalarbar, colors, png_name='Brainplot_1.png'):
img = sitk.ReadImage(filename) # SimpleITK object
data = sitk.GetArrayFromImage(img).astype('float32') # array
actor_list = []
count_intensity = 0
for intensity in range(min_val,max_val,1):
if intensity in data:
data_ = (data == intensity).astype(int)
data_ = data_*intensity
data_ = data_[::-1] #mirror
actor, lut = map_brain_surface(data=data_, intensity=intensity, voxelsize=img.GetSpacing(), min_val=min_val, max_val=max_val, colors=colors)
actor_list.append(actor)
else:
count_intensity += 1
print('Count of intensities not found in the file: ', count_intensity)
render_brain(actor_list, lut, scalarBar=scalarbar, png_name=png_name)
#############################
count = 0
############################# Variables #############################
## Define the filename of the input file you want to plot
filename = './masks/claustrum_example.nii.gz'
## Set scalarbar (colorbar) to True or False depending if you want to see a scalarbar in your plot or not.
scalarbar = True
#scalarbar = False
## Define the scalar range in your file. As a limitation, the code works best with a minimal value of zero. Both numbers should be integers.
### Hint: negative scores or floats can be encoded in positive integers, e.g. by (value*100)+100 (or +101) for scores between -1 and 1.
### Thereby, min_val=((-1)*100)+100=0 and max_val=((1)*100)+100=200. The scalarbar has to be adjusted in a post-processing step.
min_val = 0
max_val = 40
## Choose the colors you want to use for your plot. There are two colorscales available. Feel free to adjust them for your own colorsystem.
colors='redyellowwhitegreenblue'
#colors='redwhiteblue'
#colors='redwhite'
## Set save_mode to True if you want to save an automatic screenshot of the plot. Set it to False if you want to see the plot in the 3D interactor window without saving.
#save_mode = True
save_mode = False
#############################
if __name__ == "__main__":
main(filename=filename, min_val=min_val, max_val=max_val, scalarbar=scalarbar, colors=colors, png_name='Brainplot_nifti.png')