def decimate(image, shape, sigma=None, average=False, queue=None, block=False): """Decimate *image* so that its dimensions match the final *shape*, which has to be a divisor of the original shape. Remove low frequencies by a Gaussian filter with *sigma* pixels. If *sigma* is None, use the FWHM of one low resolution pixel. Use command *queue*, if *block* is True, wait for the copy to finish. """ if queue is None: queue = cfg.OPENCL.queue image = g_util.get_array(image, queue=queue) shape = make_tuple(shape) pow_shape = tuple([next_power_of_two(n) for n in image.shape]) orig_shape = image.shape if image.shape != pow_shape: image = pad(image, region=(0, 0) + pow_shape, queue=queue) if sigma is None: sigma = tuple([fwnm_to_sigma(float(image.shape[i]) / shape[i], n=2) for i in range(2)]) LOG.debug( "decimate, shape: %s, final_shape: %s, sigma: %s, average: %s", image.shape, shape, sigma, average, ) fltr = get_gauss_2d(image.shape, sigma, fourier=True, queue=queue, block=block) image = image.astype(cfg.PRECISION.np_cplx) fft_2(image, queue=queue, block=block) image *= fltr ifft_2(image, queue=queue, block=block) image = crop(image.real, (0, 0) + orig_shape, queue=queue, block=block) return bin_image(image, shape, average=average, queue=queue, block=block)
def pad(image, region=None, out=None, value=0, queue=None, block=False): """Pad a 2D *image*. *region* is the region to pad as (y_0, x_0, height, width). If not specified, the next power of two dimensions are used and the image is centered in the padded one. The final image dimensions are height x width and the filling starts at (y_0, x_0), *out* is the pyopencl Array instance, if not specified it will be created. *out* is also returned. *value* is the padded value. If *block* is True, wait for the copy to finish. """ if region is None: shape = tuple([next_power_of_two(n) for n in image.shape]) y_0 = (shape[0] - image.shape[0]) / 2 x_0 = (shape[1] - image.shape[1]) / 2 region = (y_0, x_0) + shape if queue is None: queue = cfg.OPENCL.queue if out is None: out = cl_array.zeros(queue, (region[2], region[3]), dtype=image.dtype) + value image = g_util.get_array(image, queue=queue) n_bytes = image.dtype.itemsize y_0, x_0, height, width = region src_origin = (0, 0, 0) dst_origin = (n_bytes * x_0, y_0, 0) region = (n_bytes * image.shape[1], image.shape[0], 1) LOG.debug('pad, shape: %s, src_origin: %s, dst_origin: %s, region: %s', image.shape, src_origin, dst_origin, region) _copy_rect(image, out, src_origin, dst_origin, region, queue, block=block) return out
def pad(image, region=None, out=None, value=0, queue=None, block=False): """Pad a 2D *image*. *region* is the region to pad as (y_0, x_0, height, width). If not specified, the next power of two dimensions are used and the image is centered in the padded one. The final image dimensions are height x width and the filling starts at (y_0, x_0), *out* is the pyopencl Array instance, if not specified it will be created. *out* is also returned. *value* is the padded value. If *block* is True, wait for the copy to finish. """ if region is None: shape = tuple([next_power_of_two(n) for n in image.shape]) y_0 = (shape[0] - image.shape[0]) // 2 x_0 = (shape[1] - image.shape[1]) // 2 region = (y_0, x_0) + shape if queue is None: queue = cfg.OPENCL.queue if out is None: out = cl_array.zeros(queue, (region[2], region[3]), dtype=image.dtype) + value image = g_util.get_array(image, queue=queue) n_bytes = image.dtype.itemsize y_0, x_0, height, width = region src_origin = (0, 0, 0) dst_origin = (n_bytes * x_0, y_0, 0) region = (n_bytes * image.shape[1], image.shape[0], 1) LOG.debug( "pad, shape: %s, src_origin: %s, dst_origin: %s, region: %s", image.shape, src_origin, dst_origin, region, ) _copy_rect(image, out, src_origin, dst_origin, region, queue, block=block) return out
def decimate(image, shape, sigma=None, average=False, queue=None, block=False): """Decimate *image* so that its dimensions match the final *shape*, which has to be a divisor of the original shape. Remove low frequencies by a Gaussian filter with *sigma* pixels. If *sigma* is None, use the FWHM of one low resolution pixel. Use command *queue*, if *block* is True, wait for the copy to finish. """ if queue is None: queue = cfg.OPENCL.queue image = g_util.get_array(image, queue=queue) shape = make_tuple(shape) pow_shape = tuple([next_power_of_two(n) for n in image.shape]) orig_shape = image.shape if image.shape != pow_shape: image = pad(image, region=(0, 0) + pow_shape, queue=queue) if sigma is None: sigma = tuple([fwnm_to_sigma(float(image.shape[i]) / shape[i], n=2) for i in range(2)]) LOG.debug('decimate, shape: %s, final_shape: %s, sigma: %s, average: %s', image.shape, shape, sigma, average) fltr = get_gauss_2d(image.shape, sigma, fourier=True, queue=queue, block=block) image = image.astype(cfg.PRECISION.np_cplx) fft_2(image, queue=queue, block=block) image *= fltr ifft_2(image, queue=queue, block=block) image = crop(image.real, (0, 0) + orig_shape, queue=queue, block=block) return bin_image(image, shape, average=average, queue=queue, block=block)