Commit 516b0f05ceca0b92fd94ea19091e5fc719d753ff

Authored by Thiago Franco de Moraes
1 parent f17e9109

Tool to keep the greatest component from the mask

invesalius/data/slice_.py
... ... @@ -16,10 +16,13 @@
16 16 # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais
17 17 # detalhes.
18 18 #--------------------------------------------------------------------------
  19 +import heapq
19 20 import os
20 21 import tempfile
21 22  
22 23 import numpy
  24 +from scipy import ndimage
  25 +from scipy.ndimage.measurements import label
23 26 import vtk
24 27 from wx.lib.pubsub import pub as Publisher
25 28  
... ... @@ -162,6 +165,8 @@ class Slice(object):
162 165  
163 166 Publisher.subscribe(self._do_boolean_op, 'Do boolean operation')
164 167  
  168 + Publisher.subscribe(self._keep_greatest_region, 'Keep greatest component')
  169 +
165 170 Publisher.subscribe(self.OnExportMask,'Export mask to file')
166 171  
167 172 Publisher.subscribe(self.OnCloseProject, 'Close project data')
... ... @@ -1114,6 +1119,7 @@ class Slice(object):
1114 1119 if mask.matrix[n, 0, 0] == 0:
1115 1120 m = mask.matrix[n, 1:, 1:]
1116 1121 mask.matrix[n, 1:, 1:] = self.do_threshold_to_a_slice(self.matrix[n-1], m, mask.threshold_range)
  1122 + mask.matrix[n, 0, 0] = 1
1117 1123  
1118 1124 mask.matrix.flush()
1119 1125  
... ... @@ -1261,6 +1267,28 @@ class Slice(object):
1261 1267 future_mask.was_edited = True
1262 1268 self._add_mask_into_proj(future_mask)
1263 1269  
  1270 + def _keep_greatest_region(self, pubsub_evt):
  1271 + self.keep_greatest_region(self.current_mask)
  1272 +
  1273 + def keep_greatest_region(self, mask):
  1274 + self.do_threshold_to_all_slices(mask)
  1275 + mask.matrix[0, :, :] = 1
  1276 + mask.matrix[:, 0, :] = 1
  1277 + mask.matrix[:, :, 0] = 1
  1278 +
  1279 + m= mask.matrix[1:, 1:, 1:]
  1280 + m[:] = (m > 128) * 255
  1281 +
  1282 + labeled_array, num_features = label(m)
  1283 + sizes = ndimage.sum(m,labeled_array,range(1,num_features+1))
  1284 + sl = zip(range(1, num_features + 1), sizes)
  1285 + sl.sort(key=lambda x: x[1])
  1286 + tag = sl[-1][0]
  1287 + m[labeled_array!=tag]=0
  1288 +
  1289 + mask.was_edited = True
  1290 + self.discard_all_buffers()
  1291 +
1264 1292 def apply_slice_buffer_to_mask(self, orientation):
1265 1293 """
1266 1294 Apply the modifications (edition) in mask buffer to mask.
... ...
invesalius/gui/widgets/slice_menu.py
... ... @@ -164,6 +164,11 @@ class SliceMenu(wx.Menu):
164 164 self.AppendMenu(-1, _("Projection type"), submenu_projection)
165 165 ###self.AppendMenu(-1, _("Image Tiling"), submenu_image_tiling)
166 166  
  167 + self.kgc_id = new_id = wx.NewId()
  168 + item = wx.MenuItem(self, new_id, u"Keep greatest component")
  169 + self.AppendItem(item)
  170 +
  171 +
167 172 # It doesn't work in Linux
168 173 self.Bind(wx.EVT_MENU, self.OnPopup)
169 174 # In Linux the bind must be putted in the submenu
... ... @@ -207,86 +212,90 @@ class SliceMenu(wx.Menu):
207 212  
208 213 def OnPopup(self, evt):
209 214 id = evt.GetId()
210   - item = self.ID_TO_TOOL_ITEM[evt.GetId()]
211   - key = item.GetLabel()
212   - if(key in const.WINDOW_LEVEL.keys()):
213   - window, level = const.WINDOW_LEVEL[key]
214   - Publisher.sendMessage('Bright and contrast adjustment image',
215   - (window, level))
216   - Publisher.sendMessage('Update window level value',\
217   - (window, level))
218   - Publisher.sendMessage('Update window and level text',\
219   - "WL: %d WW: %d"%(level, window))
220   - Publisher.sendMessage('Update slice viewer')
221   -
222   - #Necessary update the slice plane in the volume case exists
223   - Publisher.sendMessage('Render volume viewer')
224   -
225   - elif(key in const.SLICE_COLOR_TABLE.keys()):
226   - values = const.SLICE_COLOR_TABLE[key]
227   - Publisher.sendMessage('Change colour table from background image', values)
228   - Publisher.sendMessage('Update slice viewer')
229   -
230   - if sys.platform == 'linux2':
231   - for i in self.pseudo_color_items:
232   - it = self.pseudo_color_items[i]
233   - if it.IsChecked():
234   - it.Toggle()
235   -
236   - item.Toggle()
237   - self.HideClutDialog()
238   - self._gen_event = True
239   -
240   - elif key in self.plist_presets:
241   - values = presets.get_wwwl_preset_colours(self.plist_presets[key])
242   - Publisher.sendMessage('Change colour table from background image from plist', values)
243   - Publisher.sendMessage('Update slice viewer')
244   -
245   - if sys.platform == 'linux2':
246   - for i in self.pseudo_color_items:
247   - it = self.pseudo_color_items[i]
248   - if it.IsChecked():
249   - it.Toggle()
250   -
251   - item.Toggle()
252   - self.HideClutDialog()
253   - self._gen_event = True
254   -
255   - elif(key in const.IMAGE_TILING.keys()):
256   - values = const.IMAGE_TILING[key]
257   - Publisher.sendMessage('Set slice viewer layout', values)
258   - Publisher.sendMessage('Update slice viewer')
259   -
260   - elif key in PROJECTIONS_ID:
261   - print 'Key', key
262   - pid = PROJECTIONS_ID[key]
263   - Publisher.sendMessage('Set projection type', pid)
264   - Publisher.sendMessage('Reload actual slice')
265 215  
266   - elif key == _('Custom'):
267   - if self.cdialog is None:
268   - slc = sl.Slice()
269   - histogram = slc.histogram
270   - init = slc.matrix.min()
271   - end = slc.matrix.max()
272   - nodes = slc.nodes
273   - self.cdialog = ClutImagedataDialog(histogram, init, end, nodes)
274   - self.cdialog.Show()
275   - else:
276   - self.cdialog.Show(self._gen_event)
277   -
278   - if sys.platform == 'linux2':
279   - for i in self.pseudo_color_items:
280   - it = self.pseudo_color_items[i]
281   - if it.IsChecked():
282   - it.Toggle()
283   -
284   - item.Toggle()
  216 + if id == self.kgc_id:
  217 + Publisher.sendMessage('Keep greatest component')
  218 + Publisher.sendMessage('Reload actual slice')
  219 + else:
285 220 item = self.ID_TO_TOOL_ITEM[evt.GetId()]
286   - item.Check(True)
287   - self._gen_event = False
288   -
289   - evt.Skip()
  221 + key = item.GetLabel()
  222 + if(key in const.WINDOW_LEVEL.keys()):
  223 + window, level = const.WINDOW_LEVEL[key]
  224 + Publisher.sendMessage('Bright and contrast adjustment image',
  225 + (window, level))
  226 + Publisher.sendMessage('Update window level value',\
  227 + (window, level))
  228 + Publisher.sendMessage('Update window and level text',\
  229 + "WL: %d WW: %d"%(level, window))
  230 + Publisher.sendMessage('Update slice viewer')
  231 +
  232 + #Necessary update the slice plane in the volume case exists
  233 + Publisher.sendMessage('Render volume viewer')
  234 +
  235 + elif(key in const.SLICE_COLOR_TABLE.keys()):
  236 + values = const.SLICE_COLOR_TABLE[key]
  237 + Publisher.sendMessage('Change colour table from background image', values)
  238 + Publisher.sendMessage('Update slice viewer')
  239 +
  240 + if sys.platform == 'linux2':
  241 + for i in self.pseudo_color_items:
  242 + it = self.pseudo_color_items[i]
  243 + if it.IsChecked():
  244 + it.Toggle()
  245 +
  246 + item.Toggle()
  247 + self.HideClutDialog()
  248 + self._gen_event = True
  249 +
  250 + elif key in self.plist_presets:
  251 + values = presets.get_wwwl_preset_colours(self.plist_presets[key])
  252 + Publisher.sendMessage('Change colour table from background image from plist', values)
  253 + Publisher.sendMessage('Update slice viewer')
  254 +
  255 + if sys.platform == 'linux2':
  256 + for i in self.pseudo_color_items:
  257 + it = self.pseudo_color_items[i]
  258 + if it.IsChecked():
  259 + it.Toggle()
  260 +
  261 + item.Toggle()
  262 + self.HideClutDialog()
  263 + self._gen_event = True
  264 +
  265 + elif(key in const.IMAGE_TILING.keys()):
  266 + values = const.IMAGE_TILING[key]
  267 + Publisher.sendMessage('Set slice viewer layout', values)
  268 + Publisher.sendMessage('Update slice viewer')
  269 +
  270 + elif key in PROJECTIONS_ID:
  271 + print 'Key', key
  272 + pid = PROJECTIONS_ID[key]
  273 + Publisher.sendMessage('Set projection type', pid)
  274 + Publisher.sendMessage('Reload actual slice')
  275 +
  276 + elif key == _('Custom'):
  277 + if self.cdialog is None:
  278 + slc = sl.Slice()
  279 + histogram = slc.histogram
  280 + init = slc.matrix.min()
  281 + end = slc.matrix.max()
  282 + nodes = slc.nodes
  283 + self.cdialog = ClutImagedataDialog(histogram, init, end, nodes)
  284 + self.cdialog.Show()
  285 + else:
  286 + self.cdialog.Show(self._gen_event)
  287 +
  288 + if sys.platform == 'linux2':
  289 + for i in self.pseudo_color_items:
  290 + it = self.pseudo_color_items[i]
  291 + if it.IsChecked():
  292 + it.Toggle()
  293 +
  294 + item.Toggle()
  295 + item = self.ID_TO_TOOL_ITEM[evt.GetId()]
  296 + item.Check(True)
  297 + self._gen_event = False
  298 + evt.Skip()
290 299  
291 300 def HideClutDialog(self):
292 301 if self.cdialog:
... ...