Source code for jaxtronomy.Util.image_util

__author__ = "sibirrer"

from functools import partial
from jax import jit, lax, numpy as jnp, scipy
import numpy as np


[docs] @partial(jit, static_argnums=4) def add_layer2image(grid2d, x_pos, y_pos, kernel, order=1): """Adds a kernel on the grid2d image at position x_pos, y_pos with an interpolated subgrid pixel shift of order=order. :param grid2d: 2d pixel grid (i.e. image) :param x_pos: x-position center (pixel coordinate) of the layer to be added :param y_pos: y-position center (pixel coordinate) of the layer to be added :param kernel: the layer to be added to the image :param order: interpolation order for sub-pixel shift of the kernel to be added :return: image with added layer, cut to original size """ if order > 1: raise ValueError(f"interpolation order > 1 is not supported in jaxtronomy") k_rows, k_cols = jnp.shape(kernel) if k_rows % 2 == 0 or k_cols % 2 == 0: raise ValueError("kernel dimensions must be odd") n_row, n_col = jnp.shape(grid2d) # Create a coordinate grid where the origin is placed at the point source # shifted left and up by the kernel radius xrange = jnp.arange(n_col) + k_cols // 2 - x_pos yrange = jnp.arange(n_row) + k_rows // 2 - y_pos x_grid, y_grid = jnp.meshgrid(xrange, yrange) # Maps kernel onto coordinate grid and add original image # Row indices are given by the y_grid and column indices are given by the x_grid return ( scipy.ndimage.map_coordinates(kernel, coordinates=[y_grid, x_grid], order=order) + grid2d )
[docs] @jit def add_layer2image_int(grid2d, x_pos, y_pos, kernel): """Adds a kernel on the grid2d image at position x_pos, y_pos at integer positions of pixel. :param grid2d: 2d pixel grid (i.e. image) :param x_pos: x-position center (pixel coordinate) of the layer to be added :param y_pos: y-position center (pixel coordinate) of the layer to be added :param kernel: the layer to be added to the image :return: image with added layer """ n_row, n_col = jnp.shape(grid2d) k_rows, k_cols = jnp.shape(kernel) if k_rows % 2 == 0 or k_cols % 2 == 0: raise ValueError("kernel dimensions must be odd") x_int = (jnp.round(x_pos)).astype(int) y_int = (jnp.round(y_pos)).astype(int) # Create a coordinate grid where the origin is placed at the point source # shifted left and up by the kernel radius xrange = jnp.arange(n_col) + k_cols // 2 - x_int yrange = jnp.arange(n_row) + k_rows // 2 - y_int x_grid, y_grid = jnp.meshgrid(xrange, yrange) # Maps kernel onto coordinate grid and add original image # Row indices are given by the y_grid and column indices are given by the x_grid return ( scipy.ndimage.map_coordinates(kernel, coordinates=[y_grid, x_grid], order=0) + grid2d )
[docs] @partial(jit, static_argnums=1) def re_size(image, factor=1): """Re-sizes image with nx x ny to nx/factor x ny/factor. :param image: 2d image with shape (nx,ny) :param factor: integer >=1 :return: """ if factor < 1: raise ValueError("scaling factor in re-sizing %s < 1" % factor) elif factor == 1: return image f = int(factor) nx, ny = np.shape(image) if int(nx / f) == nx / f and int(ny / f) == ny / f: small = image.reshape([int(nx / f), f, int(ny / f), f]).mean(3).mean(1) return small else: raise ValueError( "scaling with factor %s is not possible with grid size %s, %s" % (f, nx, ny) )