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 | 18 | #-------------------------------------------------------------------------- |
19 | 19 | |
20 | 20 | import os |
21 | +import multiprocessing | |
21 | 22 | import tempfile |
23 | +import time | |
22 | 24 | |
23 | 25 | import vtk |
24 | 26 | import wx |
... | ... | @@ -738,6 +740,43 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
738 | 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 | 780 | class WatershedConfig(object): |
742 | 781 | __metaclass__= utils.Singleton |
743 | 782 | def __init__(self): |
... | ... | @@ -1201,28 +1240,57 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
1201 | 1240 | if BRUSH_BACKGROUND in markers and BRUSH_FOREGROUND in markers: |
1202 | 1241 | #w_algorithm = WALGORITHM[self.config.algorithm] |
1203 | 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 | 1274 | #tmp_image = ndimage.morphological_gradient( |
1214 | 1275 | #get_LUT_value(image, ww, wl).astype('uint16'), |
1215 | 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 | 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 | 1295 | if self.viewer.overwrite_mask: |
1228 | 1296 | mask[:] = 0 |
... | ... | @@ -1241,6 +1309,34 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
1241 | 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 | 1340 | def get_style(style): |
1245 | 1341 | STYLES = { |
1246 | 1342 | const.STATE_DEFAULT: DefaultInteractorStyle, | ... | ... |