Commit d498a62eda097803ac743abd7fe5cb6042cfad8f
1 parent
10ed1e32
Exists in
master
Added option to apply ww&wl
Showing
2 changed files
with
32 additions
and
2 deletions
Show diff stats
invesalius/gui/brain_seg_dialog.py
@@ -81,6 +81,8 @@ class BrainSegmenterDialog(wx.Dialog): | @@ -81,6 +81,8 @@ class BrainSegmenterDialog(wx.Dialog): | ||
81 | self.txt_threshold.SetMinClientSize((w, -1)) | 81 | self.txt_threshold.SetMinClientSize((w, -1)) |
82 | self.chk_new_mask = wx.CheckBox(self, wx.ID_ANY, _("Create new mask")) | 82 | self.chk_new_mask = wx.CheckBox(self, wx.ID_ANY, _("Create new mask")) |
83 | self.chk_new_mask.SetValue(True) | 83 | self.chk_new_mask.SetValue(True) |
84 | + self.chk_apply_wwwl = wx.CheckBox(self, wx.ID_ANY, _("Apply WW&WL")) | ||
85 | + self.chk_apply_wwwl.SetValue(False) | ||
84 | self.progress = wx.Gauge(self, -1) | 86 | self.progress = wx.Gauge(self, -1) |
85 | self.lbl_progress_caption = wx.StaticText(self, -1, _("Elapsed time:")) | 87 | self.lbl_progress_caption = wx.StaticText(self, -1, _("Elapsed time:")) |
86 | self.lbl_time = wx.StaticText(self, -1, _("00:00:00")) | 88 | self.lbl_time = wx.StaticText(self, -1, _("00:00:00")) |
@@ -120,6 +122,7 @@ class BrainSegmenterDialog(wx.Dialog): | @@ -120,6 +122,7 @@ class BrainSegmenterDialog(wx.Dialog): | ||
120 | ) | 122 | ) |
121 | sizer_3.Add(self.txt_threshold, 0, wx.ALL, 5) | 123 | sizer_3.Add(self.txt_threshold, 0, wx.ALL, 5) |
122 | main_sizer.Add(sizer_3, 0, wx.EXPAND, 0) | 124 | main_sizer.Add(sizer_3, 0, wx.EXPAND, 0) |
125 | + main_sizer.Add(self.chk_apply_wwwl, 0, wx.EXPAND | wx.ALL, 5) | ||
123 | main_sizer.Add(self.chk_new_mask, 0, wx.EXPAND | wx.ALL, 5) | 126 | main_sizer.Add(self.chk_new_mask, 0, wx.EXPAND | wx.ALL, 5) |
124 | main_sizer.Add(self.progress, 0, wx.EXPAND | wx.ALL, 5) | 127 | main_sizer.Add(self.progress, 0, wx.EXPAND | wx.ALL, 5) |
125 | time_sizer = wx.BoxSizer(wx.HORIZONTAL) | 128 | time_sizer = wx.BoxSizer(wx.HORIZONTAL) |
@@ -216,6 +219,7 @@ class BrainSegmenterDialog(wx.Dialog): | @@ -216,6 +219,7 @@ class BrainSegmenterDialog(wx.Dialog): | ||
216 | device_id = self.plaidml_devices[self.cb_devices.GetValue()] | 219 | device_id = self.plaidml_devices[self.cb_devices.GetValue()] |
217 | except (KeyError, AttributeError): | 220 | except (KeyError, AttributeError): |
218 | device_id = "llvm_cpu.0" | 221 | device_id = "llvm_cpu.0" |
222 | + apply_wwwl = self.chk_apply_wwwl.GetValue() | ||
219 | create_new_mask = self.chk_new_mask.GetValue() | 223 | create_new_mask = self.chk_new_mask.GetValue() |
220 | use_gpu = self.chk_use_gpu.GetValue() | 224 | use_gpu = self.chk_use_gpu.GetValue() |
221 | prob_threshold = self.sld_threshold.GetValue() / 100.0 | 225 | prob_threshold = self.sld_threshold.GetValue() / 100.0 |
@@ -224,8 +228,11 @@ class BrainSegmenterDialog(wx.Dialog): | @@ -224,8 +228,11 @@ class BrainSegmenterDialog(wx.Dialog): | ||
224 | self.btn_segment.Disable() | 228 | self.btn_segment.Disable() |
225 | self.chk_new_mask.Disable() | 229 | self.chk_new_mask.Disable() |
226 | 230 | ||
231 | + window_width = slc.Slice().window_width | ||
232 | + window_level = slc.Slice().window_level | ||
233 | + | ||
227 | try: | 234 | try: |
228 | - self.ps = segment.SegmentProcess(image, create_new_mask, backend, device_id, use_gpu) | 235 | + self.ps = segment.SegmentProcess(image, create_new_mask, backend, device_id, use_gpu, apply_wwwl, window_width, window_level) |
229 | self.ps.start() | 236 | self.ps.start() |
230 | except (multiprocessing.ProcessError, OSError, ValueError) as err: | 237 | except (multiprocessing.ProcessError, OSError, ValueError) as err: |
231 | self.OnStop(None) | 238 | self.OnStop(None) |
invesalius/segmentation/brain/segment.py
@@ -20,6 +20,17 @@ SIZE = 48 | @@ -20,6 +20,17 @@ SIZE = 48 | ||
20 | OVERLAP = SIZE // 2 + 1 | 20 | OVERLAP = SIZE // 2 + 1 |
21 | 21 | ||
22 | 22 | ||
23 | +def get_LUT_value(data, window, level): | ||
24 | + shape = data.shape | ||
25 | + data_ = data.ravel() | ||
26 | + data = np.piecewise(data_, | ||
27 | + [data_ <= (level - 0.5 - (window-1)/2), | ||
28 | + data_ > (level - 0.5 + (window-1)/2)], | ||
29 | + [0, window, lambda data_: ((data_ - (level - 0.5))/(window-1) + 0.5)*(window)]) | ||
30 | + data.shape = shape | ||
31 | + return data | ||
32 | + | ||
33 | + | ||
23 | def gen_patches(image, patch_size, overlap): | 34 | def gen_patches(image, patch_size, overlap): |
24 | sz, sy, sx = image.shape | 35 | sz, sy, sx = image.shape |
25 | i_cuts = list( | 36 | i_cuts = list( |
@@ -63,6 +74,8 @@ def brain_segment(image, probability_array, comm_array): | @@ -63,6 +74,8 @@ def brain_segment(image, probability_array, comm_array): | ||
63 | model = keras.models.model_from_json(json_file.read()) | 74 | model = keras.models.model_from_json(json_file.read()) |
64 | model.load_weights(str(folder.joinpath("model.h5"))) | 75 | model.load_weights(str(folder.joinpath("model.h5"))) |
65 | model.compile("Adam", "binary_crossentropy") | 76 | model.compile("Adam", "binary_crossentropy") |
77 | + | ||
78 | + keras.utils.plot_model(model, "model.png", show_shapes=True, show_layer_names=True) | ||
66 | 79 | ||
67 | image = imagedata_utils.image_normalize(image, 0.0, 1.0, output_dtype=np.float32) | 80 | image = imagedata_utils.image_normalize(image, 0.0, 1.0, output_dtype=np.float32) |
68 | sums = np.zeros_like(image) | 81 | sums = np.zeros_like(image) |
@@ -80,7 +93,7 @@ def brain_segment(image, probability_array, comm_array): | @@ -80,7 +93,7 @@ def brain_segment(image, probability_array, comm_array): | ||
80 | 93 | ||
81 | ctx = multiprocessing.get_context('spawn') | 94 | ctx = multiprocessing.get_context('spawn') |
82 | class SegmentProcess(ctx.Process): | 95 | class SegmentProcess(ctx.Process): |
83 | - def __init__(self, image, create_new_mask, backend, device_id, use_gpu): | 96 | + def __init__(self, image, create_new_mask, backend, device_id, use_gpu, apply_wwwl=False, window_width=255, window_level=127): |
84 | multiprocessing.Process.__init__(self) | 97 | multiprocessing.Process.__init__(self) |
85 | 98 | ||
86 | self._image_filename = image.filename | 99 | self._image_filename = image.filename |
@@ -102,6 +115,10 @@ class SegmentProcess(ctx.Process): | @@ -102,6 +115,10 @@ class SegmentProcess(ctx.Process): | ||
102 | self.device_id = device_id | 115 | self.device_id = device_id |
103 | self.use_gpu = use_gpu | 116 | self.use_gpu = use_gpu |
104 | 117 | ||
118 | + self.apply_wwwl = apply_wwwl | ||
119 | + self.window_width = window_width | ||
120 | + self.window_level = window_level | ||
121 | + | ||
105 | self._pconn, self._cconn = multiprocessing.Pipe() | 122 | self._pconn, self._cconn = multiprocessing.Pipe() |
106 | self._exception = None | 123 | self._exception = None |
107 | 124 | ||
@@ -122,6 +139,12 @@ class SegmentProcess(ctx.Process): | @@ -122,6 +139,12 @@ class SegmentProcess(ctx.Process): | ||
122 | shape=self._image_shape, | 139 | shape=self._image_shape, |
123 | mode="r", | 140 | mode="r", |
124 | ) | 141 | ) |
142 | + | ||
143 | + print(image.min(), image.max()) | ||
144 | + if self.apply_segment_threshold: | ||
145 | + print("Applying window level") | ||
146 | + image = get_LUT_value(image, self.window_width, self.window_level) | ||
147 | + | ||
125 | probability_array = np.memmap( | 148 | probability_array = np.memmap( |
126 | self._prob_array_filename, | 149 | self._prob_array_filename, |
127 | dtype=np.float32, | 150 | dtype=np.float32, |