forked from SimpleITK/TUTORIAL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
registration_gui.py
141 lines (120 loc) · 4.73 KB
/
registration_gui.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
import SimpleITK as sitk
import matplotlib.pyplot as plt
import numpy as np
#
# Set of methods used for displaying the registration metric during the optimization.
#
# Callback invoked when the StartEvent happens, sets up our new data.
def start_plot():
global metric_values, multires_iterations, ax, fig
fig, ax = plt.subplots(1, 1, figsize=(8, 4))
metric_values = []
multires_iterations = []
plt.show()
# Callback invoked when the EndEvent happens, do cleanup of data and figure.
def end_plot():
global metric_values, multires_iterations, ax, fig
del metric_values
del multires_iterations
del ax
del fig
# Callback invoked when the IterationEvent happens, update our data and display new figure.
def plot_values(registration_method):
global metric_values, multires_iterations, ax, fig
metric_values.append(registration_method.GetMetricValue())
# Plot the similarity metric values
ax.plot(metric_values, "r")
ax.plot(
multires_iterations,
[metric_values[index] for index in multires_iterations],
"b*",
)
ax.set_xlabel("Iteration Number", fontsize=12)
ax.set_ylabel("Metric Value", fontsize=12)
fig.canvas.draw()
# Callback invoked when the sitkMultiResolutionIterationEvent happens, update the index into the
# metric_values list.
def update_multires_iterations():
global metric_values, multires_iterations
multires_iterations.append(len(metric_values))
def overlay_binary_segmentation_contours(image, mask, window_min, window_max):
"""
Given a 2D image and mask:
a. resample the image and mask into isotropic grid (required for display).
b. rescale the image intensities using the given window information.
c. overlay the contours computed from the mask onto the image.
"""
# Resample the image (linear interpolation) and mask (nearest neighbor interpolation) into an isotropic grid,
# required for display.
original_spacing = image.GetSpacing()
original_size = image.GetSize()
min_spacing = min(original_spacing)
new_spacing = [min_spacing, min_spacing]
new_size = [
int(round(original_size[0] * (original_spacing[0] / min_spacing))),
int(round(original_size[1] * (original_spacing[1] / min_spacing))),
]
resampled_img = sitk.Resample(
image,
new_size,
sitk.Transform(),
sitk.sitkLinear,
image.GetOrigin(),
new_spacing,
image.GetDirection(),
0.0,
image.GetPixelID(),
)
resampled_msk = sitk.Resample(
mask,
new_size,
sitk.Transform(),
sitk.sitkNearestNeighbor,
mask.GetOrigin(),
new_spacing,
mask.GetDirection(),
0.0,
mask.GetPixelID(),
)
# Create the overlay: cast the mask to expected label pixel type, and do the same for the image after
# window-level, accounting for the high dynamic range of the CT.
return sitk.LabelMapContourOverlay(
sitk.Cast(resampled_msk, sitk.sitkLabelUInt8),
sitk.Cast(
sitk.IntensityWindowing(
resampled_img, windowMinimum=window_min, windowMaximum=window_max
),
sitk.sitkUInt8,
),
opacity=1,
contourThickness=[2, 2],
)
def display_coronal_with_overlay(
temporal_slice, coronal_slice, images, masks, label, window_min, window_max
):
"""
Display a coronal slice from the 4D (3D+time) CT with a contour overlaid onto it. The contour is the edge of
the specific label.
"""
img = images[temporal_slice][:, coronal_slice, :]
msk = masks[temporal_slice][:, coronal_slice, :] == label
overlay_img = overlay_binary_segmentation_contours(img, msk, window_min, window_max)
# Flip the image so that corresponds to correct radiological view.
plt.imshow(np.flipud(sitk.GetArrayFromImage(overlay_img)))
plt.axis("off")
plt.show()
def display_coronal_with_label_maps_overlay(
coronal_slice, mask_index, image, masks, label, window_min, window_max
):
"""
Display a coronal slice from a 3D CT with a contour overlaid onto it. The contour is the edge of
the specific label from the specific mask. Function is used to display results of transforming a segmentation
using registration.
"""
img = image[:, coronal_slice, :]
msk = masks[mask_index][:, coronal_slice, :] == label
overlay_img = overlay_binary_segmentation_contours(img, msk, window_min, window_max)
# Flip the image so that corresponds to correct radiological view.
plt.imshow(np.flipud(sitk.GetArrayFromImage(overlay_img)))
plt.axis("off")
plt.show()