Commit ec28565e626970c6b63950d27106acbf71c69a44
1 parent
07491a64
Exists in
watershed_improvements_bkp
runing 3d watershed using multiprocessing
Showing
1 changed file
with
114 additions
and
18 deletions
Show diff stats
invesalius/data/styles.py
@@ -18,7 +18,9 @@ | @@ -18,7 +18,9 @@ | ||
18 | #-------------------------------------------------------------------------- | 18 | #-------------------------------------------------------------------------- |
19 | 19 | ||
20 | import os | 20 | import os |
21 | +import multiprocessing | ||
21 | import tempfile | 22 | import tempfile |
23 | +import time | ||
22 | 24 | ||
23 | import vtk | 25 | import vtk |
24 | import wx | 26 | import wx |
@@ -738,6 +740,43 @@ class EditorInteractorStyle(DefaultInteractorStyle): | @@ -738,6 +740,43 @@ class EditorInteractorStyle(DefaultInteractorStyle): | ||
738 | return x, y, z | 740 | return x, y, z |
739 | 741 | ||
740 | 742 | ||
743 | +class WatershedProgressWindow(wx.Frame): | ||
744 | + def __init__(self, process, parent=None): | ||
745 | + wx.Frame.__init__(self, parent, -1) | ||
746 | + self.process = process | ||
747 | + self._build_gui() | ||
748 | + self._bind_wx_events() | ||
749 | + self.timer = wx.Timer(self) | ||
750 | + self.timer.Start(1000) | ||
751 | + | ||
752 | + def _build_gui(self): | ||
753 | + self.gauge = wx.Gauge(self, -1, 100) | ||
754 | + self.btn_cancel = wx.Button(self, -1, _("&Cancel")) | ||
755 | + | ||
756 | + sizer = wx.BoxSizer(wx.VERTICAL) | ||
757 | + sizer.Add(wx.StaticText(self, -1, _("Applying watershed"))) | ||
758 | + sizer.Add(self.gauge, 0, wx.EXPAND) | ||
759 | + sizer.Add(self.btn_cancel, 0, wx.ALIGN_LEFT) | ||
760 | + | ||
761 | + self.SetSizer(sizer) | ||
762 | + sizer.Fit(self) | ||
763 | + self.Layout() | ||
764 | + | ||
765 | + def __del__(self): | ||
766 | + self.timer.Stop() | ||
767 | + | ||
768 | + def _bind_wx_events(self): | ||
769 | + self.Bind(wx.EVT_TIMER, self.TimeHandler) | ||
770 | + self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_cancel) | ||
771 | + | ||
772 | + def on_cancel(self, evt): | ||
773 | + self.timer.Stop() | ||
774 | + self.process.terminate() | ||
775 | + | ||
776 | + def TimeHandler(self, evt): | ||
777 | + self.gauge.Pulse() | ||
778 | + | ||
779 | + | ||
741 | class WatershedConfig(object): | 780 | class WatershedConfig(object): |
742 | __metaclass__= utils.Singleton | 781 | __metaclass__= utils.Singleton |
743 | def __init__(self): | 782 | def __init__(self): |
@@ -1201,28 +1240,57 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): | @@ -1201,28 +1240,57 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): | ||
1201 | if BRUSH_BACKGROUND in markers and BRUSH_FOREGROUND in markers: | 1240 | if BRUSH_BACKGROUND in markers and BRUSH_FOREGROUND in markers: |
1202 | #w_algorithm = WALGORITHM[self.config.algorithm] | 1241 | #w_algorithm = WALGORITHM[self.config.algorithm] |
1203 | bstruct = generate_binary_structure(3, CON3D[self.config.con_3d]) | 1242 | bstruct = generate_binary_structure(3, CON3D[self.config.con_3d]) |
1204 | - if self.config.use_ww_wl: | ||
1205 | - if self.config.algorithm == 'Watershed': | ||
1206 | - tmp_image = ndimage.morphological_gradient( | ||
1207 | - get_LUT_value(image, ww, wl).astype('uint16'), | ||
1208 | - self.config.mg_size) | ||
1209 | - tmp_mask = watershed(tmp_image, markers.astype('int16'), bstruct) | ||
1210 | - else: | ||
1211 | - tmp_image = get_LUT_value(image, ww, wl).astype('uint16') | ||
1212 | - #tmp_image = ndimage.gaussian_filter(tmp_image, self.config.mg_size) | 1243 | + tfile = tempfile.mktemp() |
1244 | + tmp_mask = np.memmap(tfile, shape=mask.shape, dtype=mask.dtype, | ||
1245 | + mode='w+') | ||
1246 | + q = multiprocessing.Queue() | ||
1247 | + p = multiprocessing.Process(target=do_watershed, args=(image, | ||
1248 | + markers, tmp_mask, bstruct, | ||
1249 | + self.config.algorithm, | ||
1250 | + self.config.mg_size, | ||
1251 | + self.config.use_ww_wl, wl, ww, q)) | ||
1252 | + | ||
1253 | + wp = WatershedProgressWindow(p) | ||
1254 | + wp.Center(wx.BOTH) | ||
1255 | + wp.Show() | ||
1256 | + wp.MakeModal() | ||
1257 | + | ||
1258 | + p.start() | ||
1259 | + | ||
1260 | + while q.empty() and p.is_alive(): | ||
1261 | + time.sleep(0.5) | ||
1262 | + wx.Yield() | ||
1263 | + | ||
1264 | + wp.MakeModal(False) | ||
1265 | + wp.Destroy() | ||
1266 | + del wp | ||
1267 | + | ||
1268 | + if q.empty(): | ||
1269 | + return | ||
1270 | + #do_watershed(image, markers, tmp_mask, bstruct, self.config.algorithm, | ||
1271 | + #self.config.mg_size, self.config.use_ww_wl, wl, ww) | ||
1272 | + #if self.config.use_ww_wl: | ||
1273 | + #if self.config.algorithm == 'Watershed': | ||
1213 | #tmp_image = ndimage.morphological_gradient( | 1274 | #tmp_image = ndimage.morphological_gradient( |
1214 | #get_LUT_value(image, ww, wl).astype('uint16'), | 1275 | #get_LUT_value(image, ww, wl).astype('uint16'), |
1215 | #self.config.mg_size) | 1276 | #self.config.mg_size) |
1216 | - tmp_mask = watershed_ift(tmp_image, markers.astype('int16'), bstruct) | ||
1217 | - else: | ||
1218 | - if self.config.algorithm == 'Watershed': | ||
1219 | - tmp_image = ndimage.morphological_gradient((image - image.min()).astype('uint16'), self.config.mg_size) | ||
1220 | - tmp_mask = watershed(tmp_image, markers.astype('int16'), bstruct) | ||
1221 | - else: | ||
1222 | - tmp_image = (image - image.min()).astype('uint16') | ||
1223 | - #tmp_image = ndimage.gaussian_filter(tmp_image, self.config.mg_size) | 1277 | + #tmp_mask = watershed(tmp_image, markers.astype('int16'), bstruct) |
1278 | + #else: | ||
1279 | + #tmp_image = get_LUT_value(image, ww, wl).astype('uint16') | ||
1280 | + ##tmp_image = ndimage.gaussian_filter(tmp_image, self.config.mg_size) | ||
1281 | + ##tmp_image = ndimage.morphological_gradient( | ||
1282 | + ##get_LUT_value(image, ww, wl).astype('uint16'), | ||
1283 | + ##self.config.mg_size) | ||
1284 | + #tmp_mask = watershed_ift(tmp_image, markers.astype('int16'), bstruct) | ||
1285 | + #else: | ||
1286 | + #if self.config.algorithm == 'Watershed': | ||
1224 | #tmp_image = ndimage.morphological_gradient((image - image.min()).astype('uint16'), self.config.mg_size) | 1287 | #tmp_image = ndimage.morphological_gradient((image - image.min()).astype('uint16'), self.config.mg_size) |
1225 | - tmp_mask = watershed_ift(tmp_image, markers.astype('int8'), bstruct) | 1288 | + #tmp_mask = watershed(tmp_image, markers.astype('int16'), bstruct) |
1289 | + #else: | ||
1290 | + #tmp_image = (image - image.min()).astype('uint16') | ||
1291 | + ##tmp_image = ndimage.gaussian_filter(tmp_image, self.config.mg_size) | ||
1292 | + ##tmp_image = ndimage.morphological_gradient((image - image.min()).astype('uint16'), self.config.mg_size) | ||
1293 | + #tmp_mask = watershed_ift(tmp_image, markers.astype('int8'), bstruct) | ||
1226 | 1294 | ||
1227 | if self.viewer.overwrite_mask: | 1295 | if self.viewer.overwrite_mask: |
1228 | mask[:] = 0 | 1296 | mask[:] = 0 |
@@ -1241,6 +1309,34 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): | @@ -1241,6 +1309,34 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): | ||
1241 | Publisher.sendMessage('Reload actual slice') | 1309 | Publisher.sendMessage('Reload actual slice') |
1242 | 1310 | ||
1243 | 1311 | ||
1312 | +def do_watershed(image, markers, mask, bstruct, algorithm, mg_size, use_ww_wl, wl, ww, q): | ||
1313 | + if use_ww_wl: | ||
1314 | + if algorithm == 'Watershed': | ||
1315 | + tmp_image = ndimage.morphological_gradient( | ||
1316 | + get_LUT_value(image, ww, wl).astype('uint16'), | ||
1317 | + mg_size) | ||
1318 | + tmp_mask = watershed(tmp_image, markers.astype('int16'), bstruct) | ||
1319 | + else: | ||
1320 | + tmp_image = get_LUT_value(image, ww, wl).astype('uint16') | ||
1321 | + #tmp_image = ndimage.gaussian_filter(tmp_image, self.config.mg_size) | ||
1322 | + #tmp_image = ndimage.morphological_gradient( | ||
1323 | + #get_LUT_value(image, ww, wl).astype('uint16'), | ||
1324 | + #self.config.mg_size) | ||
1325 | + tmp_mask = watershed_ift(tmp_image, markers.astype('int16'), bstruct) | ||
1326 | + else: | ||
1327 | + if algorithm == 'Watershed': | ||
1328 | + tmp_image = ndimage.morphological_gradient((image - image.min()).astype('uint16'), mg_size) | ||
1329 | + tmp_mask = watershed(tmp_image, markers.astype('int16'), bstruct) | ||
1330 | + else: | ||
1331 | + tmp_image = (image - image.min()).astype('uint16') | ||
1332 | + #tmp_image = ndimage.gaussian_filter(tmp_image, self.config.mg_size) | ||
1333 | + #tmp_image = ndimage.morphological_gradient((image - image.min()).astype('uint16'), self.config.mg_size) | ||
1334 | + tmp_mask = watershed_ift(tmp_image, markers.astype('int8'), bstruct) | ||
1335 | + mask[:] = tmp_mask | ||
1336 | + q.put(1) | ||
1337 | + | ||
1338 | + | ||
1339 | + | ||
1244 | def get_style(style): | 1340 | def get_style(style): |
1245 | STYLES = { | 1341 | STYLES = { |
1246 | const.STATE_DEFAULT: DefaultInteractorStyle, | 1342 | const.STATE_DEFAULT: DefaultInteractorStyle, |