def test_screenshot(qtbot): "Test taking a screenshot" viewer = Viewer() view = viewer.window.qt_viewer qtbot.addWidget(view) np.random.seed(0) # Add image data = np.random.random((10, 15)) viewer.add_image(data) # Add labels data = np.random.randint(20, size=(10, 15)) viewer.add_labels(data) # Add points data = 20 * np.random.random((10, 2)) viewer.add_points(data) # Add vectors data = 20 * np.random.random((10, 2, 2)) viewer.add_vectors(data) # Add shapes data = 20 * np.random.random((10, 4, 2)) viewer.add_shapes(data) # Take screenshot screenshot = viewer.screenshot() assert screenshot.ndim == 3 # Close the viewer viewer.window.close()
def test_nD_shapes(qtbot): """Test adding vectors.""" viewer = Viewer() view = viewer.window.qt_viewer qtbot.addWidget(view) np.random.seed(0) # create one random rectangle per "plane" planes = np.tile(np.arange(10).reshape((10, 1, 1)), (1, 4, 1)) corners = np.random.uniform(0, 10, size=(10, 4, 2)) data = np.concatenate((planes, corners), axis=2) viewer.add_shapes(data) assert np.all( [np.all(ld == d) for ld, d in zip(viewer.layers[0].data, data)] ) assert len(viewer.layers) == 1 assert view.layers.vbox_layout.count() == 2 * len(viewer.layers) + 2 assert viewer.dims.ndim == 3 assert view.dims.nsliders == viewer.dims.ndim assert np.sum(view.dims._displayed_sliders) == 1 # Flip dims order displayed viewer.dims.order = [0, 2, 1] assert viewer.dims.order == [0, 2, 1] # Flip dims order including non-displayed viewer.dims.order = [1, 0, 2] assert viewer.dims.order == [1, 0, 2] # Close the viewer viewer.window.close()
def test_add_shapes(qtbot): """Test adding shapes.""" viewer = Viewer() view = viewer.window.qt_viewer qtbot.addWidget(view) np.random.seed(0) data = 20 * np.random.random((10, 4, 2)) viewer.add_shapes(data) assert np.all(viewer.layers[0].data == data) assert len(viewer.layers) == 1 assert view.layers.vbox_layout.count() == 2 * len(viewer.layers) + 2 assert viewer.dims.ndim == 2 assert view.dims.nsliders == viewer.dims.ndim assert np.sum(view.dims._displayed_sliders) == 0 # Switch to 3D rendering mode and back to 2D rendering mode viewer.dims.ndisplay = 3 assert viewer.dims.ndisplay == 3 viewer.dims.ndisplay = 2 assert viewer.dims.ndisplay == 2 # Close the viewer viewer.window.close()
def __init__( self, viewer: Viewer, im_shape: tuple, cell_masks: list = [], initial_state: Union[str, np.ndarray] = "good", selection_layer_name: str = 'selected_cell', accepted_layer_name: str = 'accepted_mask', rejected_layer_name: str = 'rejected_mask', mode: str = 'all', ): self.selected_shapes = viewer.add_shapes(name=selection_layer_name) self.initialize_masks( viewer=viewer, im_shape=im_shape, cell_masks=cell_masks, initial_state=initial_state, accepted_layer_name=accepted_layer_name, rejected_layer_name=rejected_layer_name, ) viewer.bind_key("t", self.toggle_selected_mask) self._mode = mode
def test_add_shapes(qtbot): """Test adding vectors.""" viewer = Viewer() view = viewer.window.qt_viewer qtbot.addWidget(view) np.random.seed(0) data = 20 * np.random.random((10, 4, 2)) viewer.add_shapes(data) assert np.all(viewer.layers[0].data == data) assert len(viewer.layers) == 1 assert view.layers.vbox_layout.count() == 2 * len(viewer.layers) + 2 assert viewer.dims.ndim == 2 assert view.dims.nsliders == 0 assert np.sum(view.dims._displayed) == 0 # Close the viewer viewer.window.close()
def test_data_change_ndisplay_shapes(qtbot): """Test change data calls for shapes layer with ndisplay change.""" viewer = Viewer() view = viewer.window.qt_viewer qtbot.addWidget(view) np.random.seed(0) data = 20 * np.random.random((10, 4, 3)) layer = viewer.add_shapes(data) visual = view.layer_to_visual[layer] @patch.object(visual, '_on_data_change', wraps=visual._on_data_change) def test_ndisplay_change(mocked_method, ndisplay=3): viewer.dims.ndisplay = ndisplay mocked_method.assert_called_once() # Switch to 3D rendering mode and back to 2D rendering mode test_ndisplay_change(ndisplay=3) test_ndisplay_change(ndisplay=2) # Close the viewer viewer.window.close()
# add the timeseries movie_layer = viewer.add_image(movie, name='timeseries', contrast_limits=(0.0, 600.0), colormap='gray') mean_layer = viewer.add_image(mean, name='mean', contrast_limits=(0.0, 600.0), colormap='gray', visible=False) # # lc_layer = viewer.add_image(localcorr, name='localcorr', contrast_limits=(0.35, 1.0), colormap='gray', visible=False) # # centers_layer = viewer.add_points(centers, name='centers', edge_width=0, face_color='green', visible=False, opacity=0.5) # shapes_layer = viewer.add_shapes(polygons, shape_type='polygon', edge_width=0, face_color='green', opacity=0.5, name='neurons', visible=False) # labels = label(mask) labels_layer = viewer.add_labels(labels, name='rois') # polygons_edit = shapes_layer.data # np.save('data/neurofinder/polygons_edit.npy', polygons_edit)
base_cols = ['red', 'green', 'blue', 'white'] colors = [base_cols[i] for i in id] with gui_qt(): # create an empty viewer viewer = Viewer() # add the images layer = viewer.add_image(tiles, name=slide_name, clim_range=[0, 255]) # add borders viewer.add_shapes(np.array(shapes), shape_type='rectangle', face_color=[0, 0, 0, 0], edge_color=colors, edge_width=border * 2, opacity=0.75, name='annotation') viewer.layers.unselect_all() @viewer.bind_key('c') def cored(viewer): """Set the current annotation to cored """ msg = 'cored' shapes = viewer.layers['annotation'] shapes._data_view.update_edge_color(0, base_cols[annot_types.index(msg)]) shapes.refresh()
shape_1 = np.array([[float(c.attrib['X']), float(c.attrib['Y'])] for c in root[0][0][0]]) shape_2 = np.array([[float(c.attrib['X']), float(c.attrib['Y'])] for c in root[0][1][0]]) tumors = [shape_1, shape_2] #print([p.shape[:2] for p in pyramid]) with gui_qt(): # create an empty viewer viewer = Viewer() # add the pyramid #viewer.open(file_name, layer_type='image', name='slide', multiscale=True, scale=[10, 10], translate=[1000, 100]) #viewer.open(file_name, layer_type='image', name='slide', multiscale=True, scale=[10, 10]) viewer.open(file_name, layer_type='image', name='H&E stained lymph node', multiscale=True) layer = viewer.layers[0] tumor_layer = viewer.add_shapes(tumors, shape_type='polygon', edge_width=50, edge_color='blue', face_color=[0, 0, 1, 0.5], opacity=0.5, name='Tumors')
def build_plugin_(viewer: Viewer) -> None: """ This part of the code sort of ended up as the controller for the plugin. """ # validate state image_layers = [l for l in viewer.layers if isinstance(l, Image)] if len(image_layers) < 1: return layer: Image = image_layers[0] # the image to visualize is the first image: np.ndarray = layer.data if image.ndim != 3: return if image.shape[2] <= 1: return n_channels = image.shape[2] # set up dock widgets topograph_pixels = _TopographPixels(n_channels) topograph_cells = TopographCells() viewer.window.add_dock_widget( topograph_pixels.view, name="TopographPixels", area="right" ) # viewer.window.add_dock_widget(topograph_cells, name='TopographCells', area='right') init_rect = np.asarray([[0, 0], [0, 500], [500, 500], [500, 0]]) shapes_layer: Shapes = viewer.add_shapes( [init_rect], shape_type="rectangle", name="Annotations", ndim=2, edge_color=[(1, 1, 1, 1)], # black face_color=[(0, 0, 0, 0)], # clear ) _shape: Optional[np.ndarray] = None def update_plots(): # at least one rectangle shapes: List[np.ndarray] = shapes_layer.data shapes: List[np.ndarray] = [s for s in shapes if is_rectangle(s)] if len(shapes) == 0: return # check if it's changed at all shape: np.ndarray = shapes[0] nonlocal _shape if (shape == _shape).all(): return _shape = np.copy(shape) # get shape extents ymin, ymax = shape[:, 0].min(), shape[:, 0].max() ymin, ymax = int(round(ymin)), int(round(ymax)) # ymin, ymax = int(round(ymin)), int(round(ymax)) + 1 xmin, xmax = shape[:, 1].min(), shape[:, 1].max() xmin, xmax = int(round(xmin)), int(round(xmax)) # xmin, xmax = int(round(xmin)), int(round(xmax)) + 1 # clip extents ymin = min(max(ymin, 0), image.shape[0]) ymax = max(min(ymax, image.shape[0]), 0) xmin = min(max(xmin, 0), image.shape[1]) xmax = max(min(xmax, image.shape[1]), 0) # get desired region of image region = image[ymin:ymax, xmin:xmax, :] topograph_pixels.plotLayout.updatePlots(region) def on_change(event: Event) -> None: event_type = getattr(event, "type", None) if event_type != "set_data": return update_plots() shapes_layer.events.connect(on_change) update_plots()
def build_plugin(viewer: Viewer) -> None: # prepare viewer window viewer.window.qt_viewer.layerButtons.deleteButton.setDisabled(True) # add annotation layer with a single window init_rect = np.asarray([[0, 0], [500, 0], [500, 500], [0, 500]]) annotation_layer: Shapes = viewer.add_shapes( [init_rect], shape_type="rectangle", name="Annotations", ndim=2, edge_color=[(1, 1, 1, 1)], face_color=[(0, 0, 0, 0)], ) topograph_pixels = TopographPixels(viewer.layers) dock_widget: QtViewerDockWidget = viewer.window.add_dock_widget( topograph_pixels.view, name="TopographPixels", area="right" ) viewer.window._qt_window.resizeDocks([dock_widget], [300], Qt.Horizontal) # update annotation rectangle _rect: Optional[np.ndarray] = None def update_plots() -> None: """ Note that all coordinate values are in world coordinates; they correspond to *microns*. It is the responsibility of whoever is interacting with the image to convert these values from microns to pixels. """ # at least one rectangle shapes: List[np.ndarray] = annotation_layer.data rects: List[np.ndarray] = [s for s in shapes if is_rectangle(s)] if len(rects) == 0: return # did rect change? rect = rects[0] nonlocal _rect if (_rect == rect).all(): return _rect = np.copy(rect) # polygon to rectangle ymin, ymax = rect[:, 0].min(), rect[:, 0].max() ymin, ymax = int(round(ymin)), int(round(ymax)) + 1 xmin, xmax = rect[:, 1].min(), rect[:, 1].max() xmin, xmax = int(round(xmin)), int(round(xmax)) + 1 topograph_pixels.update_plots(xmin, xmax, ymin, ymax) @thread_worker def run_update(): topograph_pixels.runButton.setDisabled(True) topograph_pixels.runButton.setText("Running...") update_plots() topograph_pixels.runButton.setEnabled(True) topograph_pixels.runButton.setText("Update") def run(): worker = run_update() worker.start() topograph_pixels.runButton.clicked.connect(run) # viewer.layers.events.moved.connect(update_plots) # # def on_change(event: Event) -> None: # event_type = getattr(event, "type", None) # if event_type != "set_data": # return # # update_plots() # # annotation_layer.events.connect(on_change) # updating edge width _edge_width: Optional[float] = None def update_edge_width() -> None: edge_width = min(5 / viewer.camera.zoom, 200) nonlocal _edge_width if _edge_width == edge_width: return _edge_width = edge_width # current_edge_width.setter from `shapes.py` annotation_layer._current_edge_width = edge_width for i in range(len(annotation_layer._data_view.shapes)): annotation_layer._data_view.update_edge_width(i, edge_width) annotation_layer.status = format_float(annotation_layer.current_edge_width) annotation_layer.events.edge_width() def on_camera_event(event: Event): if event.type != "zoom": return update_edge_width() viewer.camera.events.connect(on_camera_event) update_edge_width()