diff --git a/simulatedmicroscopy/image.py b/simulatedmicroscopy/image.py index 609c0e4..4eb82a7 100644 --- a/simulatedmicroscopy/image.py +++ b/simulatedmicroscopy/image.py @@ -256,6 +256,7 @@ def create_particle_image( cls, coordinates: type[Coordinates], particle: type[BaseParticle], + edge_pixel_margin: int = 0, *args, **kwargs, ) -> type[Image]: @@ -267,6 +268,8 @@ def create_particle_image( Set of coordinates particle : list[BaseParticle] Particle to use for image, will also use its pixel size for the final image + edge_pixel_margin : int + Number of extra empty pixels to apply as a margin around the edges of the image Returns ------- @@ -275,6 +278,7 @@ def create_particle_image( """ # convert pixel sizes to micrometers for calculatation pixel_sizes_um = np.array(particle.pixel_sizes) * 1e6 + edge_pixel_margin = int(edge_pixel_margin) # scale coordinates with pixel size, order of coords is xyz, while pixel size order is zyx scaled_coords = ( @@ -286,13 +290,21 @@ def create_particle_image( ) # offset coordinates by half the size of the box, such that the coordinate points to the middle of the particle # round to integer to create point at certain pixel - xs, ys, zs = np.round(scaled_coords).astype(int) + xs, ys, zs = np.round(scaled_coords).astype(int) + edge_pixel_margin image = np.zeros(shape=[1 for _ in particle.shape]) particle_response = particle.response().copy() for x, y, z in zip(xs, ys, zs): image = overlap_arrays(image, particle_response, offset=(z, y, x)) + if edge_pixel_margin != 0: + # add extra pixels at right edges if an edge pixel_margin is given + image = overlap_arrays( + image, + np.zeros(shape=[1 for _ in particle.shape]), + offset=np.array(image.shape) + edge_pixel_margin - 1, + ) + im = cls(image=image, pixel_sizes=particle.pixel_sizes, *args, **kwargs) im.pixel_coordinates = np.transpose([zs, ys, xs]) + particle_offset.T return im diff --git a/tests/test_particle.py b/tests/test_particle.py index d4dacf3..69693bd 100644 --- a/tests/test_particle.py +++ b/tests/test_particle.py @@ -86,6 +86,20 @@ def test_particle_image_size(): assert np.prod(im.image.shape) == 2.0 * np.prod(particle.shape) +def test_particle_image_edge_pixel_margin(): + diameter_um = 2.0 + edge_pixel_margin = 10 + particle = Sphere([1e-6, 1e-6, 1e-6], 1e-6 * diameter_um / 2.0) + coords = Coordinates([[0.0, 0.0, 0.0], [0.0, diameter_um, 0.0]]) + im = Image.create_particle_image(coords, particle) + im2 = Image.create_particle_image(coords, particle, edge_pixel_margin) + + # image shape should be padded on all sides by edge_pixel_margin + assert np.all( + np.array(im2.image.shape) == 2 * edge_pixel_margin + np.array(im.image.shape) + ) + + @pytest.mark.parametrize( "dtype", [