def __init__(self, image=None, mayavi_viewer=True, fliplr=False, parent=None): super(OrthoViewer, self).__init__(parent=parent, designer_layout=ui_layout_class()) # if ANALYZE Images are known to be presented in right-handed # orientation, then you can forcibly ignore the sign of # R[0,0], in the index to world transform self._fliplr = fliplr # kick in the manual connections etc written below self.extra_setup_ui() self._image_loaded = False self._overlay_active = False # only enforce vtk_order if necessary for Mayavi self.blender = BlendedImages(vtk_order=mayavi_viewer) if mayavi_viewer: # Creates Mayavi 3D view self.create_mayavi_window() self.mayavi_widget.mr_vis.blender = self.blender try: self.update_image(image) except RuntimeError: print 'no image to load in __init__()'
class BlendedOrtho(QtGui.QMainWindow): def __init__(self, img1, img2, **bimage_kws): QtGui.QMainWindow.__init__(self) self.ortho_figs_widget = MplQT4OrthoSlicesWidget(parent=self) self.setCentralWidget(self.ortho_figs_widget) self.image = BlendedImages(main=img1, over=img2, over_alpha = 0.5, **bimage_kws) self.initialize_plots() # connect variants of position states QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL("xyz_state(int,int,int)"), self.xyz_position_watcher) QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL("xyz_state(int,int)"), self.xyz_position_watcher) QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL("xyz_state(int)"), self.xyz_position_watcher) def initialize_plots(self): planes = self.image.cut_image((0,0,0)) lims = self.image.bbox self.ortho_figs_widget.initialize_plots( planes, (0,0,0), lims, interpolation='nearest' ) def xyz_position_watcher(self, *args): axes = args xyz_loc = self.ortho_figs_widget.active_voxel # just simply replot for now self.update_fig_data(xyz_loc, axes=axes) def update_fig_data(self, xyz_loc, axes=(SAG, COR, AXI)): planes = self.image.cut_image(xyz_loc, axes=axes) self.ortho_figs_widget.update_plot_data( planes, fig_labels=axes )
def __init__(self, img1, img2, **bimage_kws): QtGui.QMainWindow.__init__(self) self.ortho_figs_widget = MplQT4OrthoSlicesWidget(parent=self) self.setCentralWidget(self.ortho_figs_widget) self.image = BlendedImages(main=img1, over=img2, over_alpha = 0.5, **bimage_kws) self.initialize_plots() # connect variants of position states QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL("xyz_state(int,int,int)"), self.xyz_position_watcher) QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL("xyz_state(int,int)"), self.xyz_position_watcher) QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL("xyz_state(int)"), self.xyz_position_watcher)
class OrthoViewer(XIPYWindowApp): def __init__(self, image=None, mayavi_viewer=True, fliplr=False, parent=None): super(OrthoViewer, self).__init__(parent=parent, designer_layout=ui_layout_class()) # if ANALYZE Images are known to be presented in right-handed # orientation, then you can forcibly ignore the sign of # R[0,0], in the index to world transform self._fliplr = fliplr # kick in the manual connections etc written below self.extra_setup_ui() self._image_loaded = False self._overlay_active = False # only enforce vtk_order if necessary for Mayavi self.blender = BlendedImages(vtk_order=mayavi_viewer) if mayavi_viewer: # Creates Mayavi 3D view self.create_mayavi_window() self.mayavi_widget.mr_vis.blender = self.blender try: self.update_image(image) except RuntimeError: print 'no image to load in __init__()' def extra_setup_ui(self): # set up cmap options self.cmap_box.insertItems(0, cmaps) self.cmap_box.setCurrentIndex(cmaps.index('gray')) # connect cmap box QtCore.QObject.connect(self.cmap_box, QtCore.SIGNAL('currentIndexChanged(QString)'), self.set_main_cmap) # set up interp options self.interp_box.insertItems(0, interpolations) self.interp_box.setCurrentIndex(interpolations.index('nearest')) self.ortho_figs_widget.set_interp('nearest') # connect menu items self.actionLoad_MR_File.triggered.connect(self.on_load_mr) self.actionUnload_Overlay.triggered.connect(self.remove_overlay) # connect image space buttons self.worldspace_button.toggled.connect(self.change_to_world) self.voxspace_button.toggled.connect(self.change_to_vox) # connect variants of position states QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL('xyz_state(int,int,int)'), self.xyz_position_watcher) QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL('xyz_state(int,int)'), self.xyz_position_watcher) QtCore.QObject.connect(self.ortho_figs_widget, QtCore.SIGNAL('xyz_state(int)'), self.xyz_position_watcher) # connect the plugin launching event to notify the mayavi widget ## # why not this way?? because of the object type?? ## QtCore.QObject.connect(self, ## QtCore.SIGNAL('plugin_launched(object)'), ## self._update_mayavi_viewer_panel) self.plugin_launched.connect(self._update_mayavi_viewer_panel) def create_mayavi_window(self): mayavi_widget = mayavi_widgets.MayaviWidget( main_ref=self, manage_overlay=False ) mayavi_widget.show() mayavi_widget.activateWindow() self.mwidget_toggle = mayavi_widget.toggle_view_action() self.menuView.addAction(self.mwidget_toggle) r = mayavi_widget.geometry() mayavi_widget.setGeometry(900,100,r.width(),r.height()) self.mwidget_toggle.setChecked(False) self.mayavi_widget = mayavi_widget def _update_mayavi_viewer_panel(self, plugin): if hasattr(self, 'mayavi_widget') and self.mayavi_widget is not None: self.mayavi_widget.add_toolbar(plugin.func_man) @with_attribute('_image_loaded') def _update_plugin_params(self): # these are the in-place arguments for any plugin loc_methods = (self.ortho_figs_widget.update_location, ) image_methods = (self.triggered_overlay_update, ) im_props_methods = (self.change_overlay_props, ) bbox = self.image.bbox self._plugin_args = (loc_methods, image_methods, im_props_methods, bbox) # here are some keyword arguments self._plugin_kwargs['external_loc'] = self.ortho_figs_widget.xyz_state[float,float,float] self._plugin_kwargs['main_ref'] = self ########## ACTION/MENU HANDLERS ########## def on_load_mr(self, bool): fname = browse_files(self, dialog='Select Image File', wildcard='Images (*.nii *.nii.gz *.hdr *.img)') if fname: self.update_image(fname) ########## IMAGE DATA UPDATES ########## def update_image(self, image, mode='world'): if type(image) != ni_api.Image: try: image = load_spatial_image(image) except RuntimeError: self.image = None self._image_loaded = False raise self.blender.main = image # this reference may no longer be necessary self.image = self.blender.main self._image_loaded = True # need to update: # slider ranges # plugin params limits = self.blender.bbox print 'new limits:', limits self.update_ranges(limits) self._update_plugin_params() planes = self.blender.cut_image((0,0,0)) self.ortho_figs_widget.initialize_plots(planes, (0,0,0), limits) if hasattr(self, 'mayavi_widget') and self.mayavi_widget is not None: self.mayavi_widget.mr_vis.blender = self.blender def triggered_overlay_update(self, func_man): print 'heard overlay upate signal' self.blender.over = func_man.overlay self.update_fig_data() def change_overlay_props(self, func_man): pdict = make_mpl_image_properties(func_man) print 'heard props change' if 'norm' in pdict: n = pdict['norm'] pdict['norm'] = (n.vmin, n.vmax) self.blender.update_over_props(**pdict) self.update_fig_data() @QtCore.pyqtSlot(str) def set_main_cmap(self, cmap): cmap = cm.cmap_d[str(cmap)] print 'heard cmap change', cmap self.blender.main_cmap = cmap self.update_fig_data() @with_attribute('_overlay_active') def remove_overlay(self, bool): print 'unloading MR overlays' self.blender.over = None del self.over_img self._overlay_active = False self.update_fig_data() for tool in self._active_tools: tool.deactivate(strip_overlay=True) def change_to_world(self, active): if active: self.change_image_space('world') def change_to_vox(self, active): if active: self.change_image_space('voxel') @with_attribute('_image_loaded') def change_image_space(self, mode): ## self.image.switch_mode(mode) print 'this is broken' return self.update_image(self.image) if self._overlay_active: self.over_img.update_target_space(self.image) self.update_overlay_slices(self.over_img) # NEED TO TEST THIS #self.check_max_extents() limits = self.image.bbox self.update_ranges(limits) ########## FIGURE/PLOTTING UPDATES ########## @with_attribute('_image_loaded') def check_max_extents(self): limits = self.blender.bbox self.update_ranges(limits) return limits def cut_to_location(self, loc): pass @QtCore.pyqtSlot(int, int, int) @QtCore.pyqtSlot(int, int) @QtCore.pyqtSlot(int) def xyz_position_watcher(self, *args): axes = args xyz_loc = self.ortho_figs_widget.active_voxel self.update_fig_data(xyz_loc=xyz_loc, axes=axes) @with_attribute('_image_loaded') def update_fig_data(self, xyz_loc=None, axes=(SAG, COR, AXI)): if xyz_loc is None: xyz_loc = self.ortho_figs_widget.active_voxel planes = self.blender.cut_image(xyz_loc, axes=axes) self.ortho_figs_widget.update_main_plot_data( planes, fig_labels=axes ) @with_attribute('_image_loaded') def update_ranges(self, limits): sliders = [self.sag_slider, self.cor_slider, self.axi_slider] spinners = [self.sag_spinner, self.cor_spinner, self.axi_spinner] for slider, spinner, lim in zip(sliders, spinners, limits): slider.setMinimum(lim[0]); slider.setMaximum(lim[1]) slider.setSliderPosition(0) spinner.setRange(lim[0], lim[1]) spinner.setSingleStep(1) def _do_rand_data(self): rand_data = [np.random.randn(10,10) for x in [0,1,2]] interp = str(self.interp_box.currentText()) cmap = cm.cmap_d[str(self.cmap_box.currentText())] plot_limits = [(-50,50)]*3 self.ortho_figs_widget.initialize_plots(rand_data, (0,0,0), plot_limits, interpolation=interp, cmap=cmap) self.update_ranges(plot_limits)
activation = -np.sqrt(anat) anat *= np.sin(4*x)*np.sin(4*y)*np.sin(4*z) activation[activation < -.5] = -.6 activation -= activation.min() main_img = ni_api.Image( anat, ni_api.AffineTransform.from_start_step('ijk', xipy_ras, [0,0,0], [1,1,1]) ) over_img = ni_api.Image( activation, ni_api.AffineTransform.from_start_step('ijk', xipy_ras, [0,0,0], [1,1,1]) ) bi = BlendedImages(vtk_order=True) bi.main = main_img bi.over = over_img pd = tvtk.PointData() class PDataDB(object): def __init__(self, pd): self.pd = pd self.db = dict() def add_to_pdata(self, array, name): if len(array.shape) > 3: vtk_order = quick_convert_rgba_to_vtk(array) flat_shape = (np.prod(vtk_order.shape[:3]), vtk_order.shape[3])