def test_fill(Event): """Test filling label.""" data = np.ones((20, 20)) data[:5, :5] = 2 data[-5:, -5:] = 3 layer = Labels(data) assert np.unique(layer.data[:5, :5]) == 2 assert np.unique(layer.data[-5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 layer.mode = 'fill' layer.position = (0, 0) layer.selected_label = 4 # Simulate click event = ReadOnlyWrapper(Event(type='mouse_press', is_dragging=False)) mouse_press_callbacks(layer, event) assert np.unique(layer.data[:5, :5]) == 4 assert np.unique(layer.data[-5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 layer.position = (19, 19) layer.selected_label = 5 # Simulate click event = ReadOnlyWrapper(Event(type='mouse_press', is_dragging=False)) mouse_press_callbacks(layer, event) assert np.unique(layer.data[:5, :5]) == 4 assert np.unique(layer.data[-5:, -5:]) == 5 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1
def test_fill_nD_plane(MouseEvent): """Test filling label nD plane.""" data = np.ones((20, 20, 20), dtype=np.int32) data[:5, :5, :5] = 2 data[0, 8:10, 8:10] = 2 data[-5:, -5:, -5:] = 3 layer = Labels(data) assert np.unique(layer.data[:5, :5, :5]) == 2 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:, -5:]) == 1 assert np.unique(layer.data[-5:, :5, -5:]) == 1 assert np.unique(layer.data[0, 8:10, 8:10]) == 2 layer.mode = 'fill' layer.selected_label = 4 # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(0, 0, 0), view_direction=(1, 0, 0), dims_displayed=(0, 1), dims_point=(0, 0), ) ) mouse_press_callbacks(layer, event) assert np.unique(layer.data[0, :5, :5]) == 4 assert np.unique(layer.data[1:5, :5, :5]) == 2 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:, -5:]) == 1 assert np.unique(layer.data[-5:, :5, -5:]) == 1 assert np.unique(layer.data[0, 8:10, 8:10]) == 2 layer.selected_label = 5 # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(0, 19, 19), view_direction=(1, 0, 0), dims_displayed=(0, 1), dims_point=(0, 0, 0), ) ) mouse_press_callbacks(layer, event) assert np.unique(layer.data[0, :5, :5]) == 4 assert np.unique(layer.data[1:5, :5, :5]) == 2 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[1:5, -5:, -5:]) == 1 assert np.unique(layer.data[-5:, :5, -5:]) == 1 assert np.unique(layer.data[0, -5:, -5:]) == 5 assert np.unique(layer.data[0, :5, -5:]) == 5 assert np.unique(layer.data[0, 8:10, 8:10]) == 2
def test_add_colors(): """Test adding new colors""" data = np.random.randint(20, size=(40, 40)) layer = Labels(data) assert len(layer._all_vals) == layer.num_colors layer.selected_label = 51 assert len(layer._all_vals) == 52 layer.show_selected_label = True layer.selected_label = 53 assert len(layer._all_vals) == 54
def test_erase(Event, brush_shape, expected_sum): """Test erasing labels with different brush shapes.""" data = np.ones((20, 20)) layer = Labels(data) layer.brush_size = 10 layer.mode = 'erase' layer.brush_shape = brush_shape layer.selected_label = 3 layer.position = (0, 0) # Simulate click event = ReadOnlyWrapper(Event(type='mouse_press', is_dragging=False)) mouse_press_callbacks(layer, event) layer.position = (19, 19) # Simulate drag event = ReadOnlyWrapper(Event(type='mouse_move', is_dragging=True)) mouse_move_callbacks(layer, event) # Simulate release event = ReadOnlyWrapper(Event(type='mouse_release', is_dragging=False)) mouse_release_callbacks(layer, event) # Painting goes from (0, 0) to (19, 19) with a brush size of 10, changing # all pixels along that path, but non outside it. assert np.unique(layer.data[:8, :8]) == 0 assert np.unique(layer.data[-8:, -8:]) == 0 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 assert np.sum(layer.data == 1) == expected_sum
def test_undo_redo( brush_shape, brush_size, mode, selected_label, preserve_labels, n_dimensional, ): blobs = data.binary_blobs(length=64, volume_fraction=0.3, n_dim=3) layer = Labels(blobs) data_history = [blobs.copy()] with pytest.warns(FutureWarning): layer.brush_shape = brush_shape layer.brush_size = brush_size layer.mode = mode layer.selected_label = selected_label layer.preserve_labels = preserve_labels layer.n_edit_dimensions = 3 if n_dimensional else 2 coord = np.random.random((3, )) * (np.array(blobs.shape) - 1) while layer.data[tuple(coord.astype(int))] == 0 and np.any(layer.data): coord = np.random.random((3, )) * (np.array(blobs.shape) - 1) if layer.mode == 'fill': layer.fill(coord, layer.selected_label) if layer.mode == 'erase': layer.paint(coord, 0) if layer.mode == 'paint': layer.paint(coord, layer.selected_label) data_history.append(np.copy(layer.data)) layer.undo() np.testing.assert_array_equal(layer.data, data_history[0]) layer.redo() np.testing.assert_array_equal(layer.data, data_history[1])
def test_changing_colormap_updates_colorbox(qtbot): """Test that changing the colormap on a layer will update color swatch in the combo box""" layer = Labels(_LABELS, color=_COLOR) qtctrl = QtLabelsControls(layer) qtbot.addWidget(qtctrl) color_box = qtctrl.colorBox layer.selected_label = 1 # For a paint event, which does not occur in a headless qtbot color_box.paintEvent(None) np.testing.assert_equal( color_box.color, np.round(np.asarray(layer._selected_color) * 255 * layer.opacity), ) layer.colormap = colormap_utils.label_colormap(num_colors=5) # For a paint event, which does not occur in a headless qtbot color_box.paintEvent(None) np.testing.assert_equal( color_box.color, np.round(np.asarray(layer._selected_color) * 255 * layer.opacity), )
def test_paint_scale(Event, brush_shape, expected_sum): """Test painting labels with circle/square brush when scaled.""" data = np.ones((20, 20)) layer = Labels(data, scale=(2, 2)) layer.brush_size = 20 layer.brush_shape = brush_shape layer.mode = 'paint' layer.selected_label = 3 layer.position = (0, 0) # Simulate click event = ReadOnlyWrapper(Event(type='mouse_press', is_dragging=False)) mouse_press_callbacks(layer, event) layer.position = (39, 39) # Simulate drag event = ReadOnlyWrapper(Event(type='mouse_move', is_dragging=True)) mouse_move_callbacks(layer, event) # Simulate release event = ReadOnlyWrapper(Event(type='mouse_release', is_dragging=False)) mouse_release_callbacks(layer, event) # Painting goes from (0, 0) to (19, 19) with a brush size of 10, changing # all pixels along that path, but none outside it. assert np.unique(layer.data[:8, :8]) == 3 assert np.unique(layer.data[-8:, -8:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 assert np.sum(layer.data == 3) == expected_sum
def test_show_selected_label(): """Test color of labels when filtering to selected labels""" np.random.seed(0) data = np.random.randint(20, size=(10, 15)) layer = Labels(data) original_color = layer.get_color(1) layer.show_selected_label = True original_background_color = layer.get_color(layer._background_label) none_color = layer.get_color(None) layer.selected_label = 1 # color of selected label has not changed assert np.allclose(layer.get_color(layer.selected_label), original_color) current_background_color = layer.get_color(layer._background_label) # color of background is background color assert current_background_color == original_background_color # color of all others is none color other_labels = np.unique(layer.data)[2:] other_colors = np.array( list(map(lambda x: layer.get_color(x), other_labels)) ) assert np.allclose(other_colors, none_color)
def test_paint(Event, brush_shape, expected_sum): """Test painting labels with circle/square brush.""" data = np.ones((20, 20), dtype=np.int32) layer = Labels(data) layer.brush_size = 10 assert layer.cursor_size == 10 with pytest.warns(FutureWarning): layer.brush_shape = brush_shape layer.mode = 'paint' layer.selected_label = 3 # Simulate click event = ReadOnlyWrapper( Event(type='mouse_press', is_dragging=False, position=(0, 0))) mouse_press_callbacks(layer, event) # Simulate drag event = ReadOnlyWrapper( Event(type='mouse_move', is_dragging=True, position=(19, 19))) mouse_move_callbacks(layer, event) # Simulate release event = ReadOnlyWrapper( Event(type='mouse_release', is_dragging=False, position=(19, 19))) mouse_release_callbacks(layer, event) # Painting goes from (0, 0) to (19, 19) with a brush size of 10, changing # all pixels along that path, but none outside it. assert np.unique(layer.data[:8, :8]) == 3 assert np.unique(layer.data[-8:, -8:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 assert np.sum(layer.data == 3) == expected_sum
def test_add_large_colors(): label_array = (5e6 * np.ones((2, 2, 2))).astype(np.uint64) label_array[0, :, :] = [[0, 1], [2, 3]] layer = Labels(label_array) assert len(layer._all_vals) == layer.num_colors layer.show_selected_label = True layer.selected_label = int(5e6) assert layer._all_vals.size < 1026
def test_paint(MouseEvent): """Test painting labels with circle brush.""" data = np.ones((20, 20), dtype=np.int32) layer = Labels(data) layer.brush_size = 10 assert layer.cursor_size == 10 layer.mode = 'paint' layer.selected_label = 3 # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(0, 0), view_direction=None, dims_displayed=(0, 1), dims_point=(0, 0), ) ) mouse_press_callbacks(layer, event) # Simulate drag event = ReadOnlyWrapper( MouseEvent( type='mouse_move', is_dragging=True, position=(19, 19), view_direction=None, dims_displayed=(0, 1), dims_point=(0, 0), ) ) mouse_move_callbacks(layer, event) # Simulate release event = ReadOnlyWrapper( MouseEvent( type='mouse_release', is_dragging=False, position=(19, 19), view_direction=None, dims_displayed=(0, 1), dims_point=(0, 0), ) ) mouse_release_callbacks(layer, event) # Painting goes from (0, 0) to (19, 19) with a brush size of 10, changing # all pixels along that path, but none outside it. assert np.unique(layer.data[:8, :8]) == 3 assert np.unique(layer.data[-8:, -8:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 assert np.sum(layer.data == 3) == 244
def test_negative_label(): """Test negative label values are supported.""" data = np.random.randint(low=-1, high=20, size=(10, 10)) original_data = np.copy(data) layer = Labels(data) layer.selected_label = -1 layer.brush_size = 3 layer.paint((5, 5), -1) assert np.count_nonzero(layer.data == -1) > np.count_nonzero( original_data == -1)
def test_selecting_label(): """Test selecting label.""" np.random.seed(0) data = np.random.randint(20, size=(10, 15)) layer = Labels(data) assert layer.selected_label == 0 assert layer._selected_color is None layer.selected_label = 1 assert layer.selected_label == 1 assert len(layer._selected_color) == 4
def test_selecting_label(): """Test changing n_dimensional.""" np.random.seed(0) data = np.random.randint(20, size=(10, 15)) layer = Labels(data) assert layer.selected_label == 0 assert layer._selected_color == None layer.selected_label = 1 assert layer.selected_label == 1 assert len(layer._selected_color) == 4
def test_fill_nD_all(Event): """Test filling label nD.""" data = np.ones((20, 20, 20), dtype=np.int32) data[:5, :5, :5] = 2 data[0, 8:10, 8:10] = 2 data[-5:, -5:, -5:] = 3 layer = Labels(data) assert np.unique(layer.data[:5, :5, :5]) == 2 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:, -5:]) == 1 assert np.unique(layer.data[-5:, :5, -5:]) == 1 assert np.unique(layer.data[0, 8:10, 8:10]) == 2 layer.n_dimensional = True layer.mode = 'fill' layer.selected_label = 4 # Simulate click event = ReadOnlyWrapper( Event(type='mouse_press', is_dragging=False, position=(0, 0, 0))) mouse_press_callbacks(layer, event) assert np.unique(layer.data[:5, :5, :5]) == 4 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:, -5:]) == 1 assert np.unique(layer.data[-5:, :5, -5:]) == 1 assert np.unique(layer.data[0, 8:10, 8:10]) == 2 layer.selected_label = 5 # Simulate click event = ReadOnlyWrapper( Event(type='mouse_press', is_dragging=False, position=(0, 19, 19))) mouse_press_callbacks(layer, event) assert np.unique(layer.data[:5, :5, :5]) == 4 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:, -5:]) == 5 assert np.unique(layer.data[-5:, :5, -5:]) == 5 assert np.unique(layer.data[0, 8:10, 8:10]) == 2
def test_mouse_move(): """Test painting labels with different brush sizes.""" np.random.seed(0) data = np.random.randint(20, size=(20, 20)) layer = Labels(data) layer.brush_size = 10 layer.mode = 'paint' layer.selected_label = 3 layer._last_cursor_coord = (0, 0) layer.coordinates = (19, 19) Event = collections.namedtuple('Event', 'is_dragging') event = Event(is_dragging=True) layer.on_mouse_move(event) assert np.unique(layer.data[:5, :5]) == 3 assert np.unique(layer.data[-5:, -5:]) == 3
def test_paint_3d(MouseEvent): """Test filling label nD.""" data = np.zeros((21, 21, 21), dtype=np.int32) data[10, 10, 10] = 1 layer = Labels(data) layer._slice_dims(point=(0, 0, 0), ndisplay=3) layer.n_edit_dimensions = 3 layer.mode = 'paint' layer.selected_label = 4 layer.brush_size = 3 # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(0.1, 0, 0), view_direction=np.full(3, np.sqrt(3)), dims_displayed=(0, 1, 2), dims_point=(0, 0, 0), ) ) mouse_press_callbacks(layer, event) np.testing.assert_array_equal(np.unique(layer.data), [0, 4]) num_filled = np.bincount(layer.data.ravel())[4] assert num_filled > 1 layer.mode = 'erase' # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(0, 10, 10), view_direction=(1, 0, 0), dims_displayed=(0, 1, 2), dims_point=(0, 0, 0), ) ) mouse_press_callbacks(layer, event) new_num_filled = np.bincount(layer.data.ravel())[4] assert new_num_filled < num_filled