Commit 516b0f05ceca0b92fd94ea19091e5fc719d753ff
1 parent
f17e9109
Exists in
mask_greatest_component
Tool to keep the greatest component from the mask
Showing
2 changed files
with
115 additions
and
78 deletions
Show diff stats
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: | ... | ... |