def resample_img(data, new_shape): """resamples d""" d1_g = OCLImage.from_array(data) d2_g = OCLImage.empty(new_shape,np.float32,num_channels = 2 if np.iscomplexobj(data) else 1) d2_g.copy_image_resampled(d1_g) return d2_g.get()
def resample_img(data, new_shape): """resamples d""" d1_g = OCLImage.from_array(data) d2_g = OCLImage.empty(new_shape, np.float32, num_channels=2 if np.iscomplexobj(data) else 1) d2_g.copy_image_resampled(d1_g) return d2_g.get()
def nlm3(data,sigma, size_filter = 2, size_search = 3): """for noise level of sigma_0, choose sigma = 1.5*sigma_0 """ prog = OCLProgram(abspath("kernels/nlm3.cl"), build_options="-D FS=%i -D BS=%i"%(size_filter,size_search)) data = data.astype(np.float32, copy = False) img = OCLImage.from_array(data) distImg = OCLImage.empty_like(data) distImg = OCLImage.empty_like(data) tmpImg = OCLImage.empty_like(data) tmpImg2 = OCLImage.empty_like(data) accBuf = OCLArray.zeros(data.shape,np.float32) weightBuf = OCLArray.zeros(data.shape,np.float32) for dx in range(size_search+1): for dy in range(-size_search,size_search+1): for dz in range(-size_search,size_search+1): prog.run_kernel("dist",img.shape,None, img,tmpImg,np.int32(dx),np.int32(dy),np.int32(dz)) prog.run_kernel("convolve",img.shape,None, tmpImg,tmpImg2,np.int32(1)) prog.run_kernel("convolve",img.shape,None, tmpImg2,tmpImg,np.int32(2)) prog.run_kernel("convolve",img.shape,None, tmpImg,distImg,np.int32(4)) prog.run_kernel("computePlus",img.shape,None, img,distImg,accBuf.data,weightBuf.data, np.int32(img.shape[0]), np.int32(img.shape[1]), np.int32(img.shape[2]), np.int32(dx),np.int32(dy),np.int32(dz), np.float32(sigma)) if any([dx,dy,dz]): prog.run_kernel("computeMinus",img.shape,None, img,distImg,accBuf.data,weightBuf.data, np.int32(img.shape[0]), np.int32(img.shape[1]), np.int32(img.shape[2]), np.int32(dx),np.int32(dy),np.int32(dz), np.float32(sigma)) acc = accBuf.get() weights = weightBuf.get() return acc/weights
def nlm3(data,sigma, size_filter = 2, size_search = 3): """for noise level of sigma_0, choose sigma = 1.5*sigma_0 """ prog = OCLProgram(abspath("kernels/nlm3.cl"), build_options="-D FS=%i -D BS=%i"%(size_filter,size_search)) img = OCLImage.from_array(data) distImg = OCLImage.empty_like(data) distImg = OCLImage.empty_like(data) tmpImg = OCLImage.empty_like(data) tmpImg2 = OCLImage.empty_like(data) accBuf = OCLArray.zeros(data.shape,np.float32) weightBuf = OCLArray.zeros(data.shape,np.float32) for dx in range(size_search+1): for dy in range(-size_search,size_search+1): for dz in range(-size_search,size_search+1): prog.run_kernel("dist",img.shape,None, img,tmpImg,np.int32(dx),np.int32(dy),np.int32(dz)) prog.run_kernel("convolve",img.shape,None, tmpImg,tmpImg2,np.int32(1)) prog.run_kernel("convolve",img.shape,None, tmpImg2,tmpImg,np.int32(2)) prog.run_kernel("convolve",img.shape,None, tmpImg,distImg,np.int32(4)) prog.run_kernel("computePlus",img.shape,None, img,distImg,accBuf.data,weightBuf.data, np.int32(img.shape[0]), np.int32(img.shape[1]), np.int32(img.shape[2]), np.int32(dx),np.int32(dy),np.int32(dz), np.float32(sigma)) if any([dx,dy,dz]): prog.run_kernel("computeMinus",img.shape,None, img,distImg,accBuf.data,weightBuf.data, np.int32(img.shape[0]), np.int32(img.shape[1]), np.int32(img.shape[2]), np.int32(dx),np.int32(dy),np.int32(dz), np.float32(sigma)) acc = accBuf.get() weights = weightBuf.get() return acc/weights
def transfer(data): """transfers data""" d1_g = OCLArray.from_array(data) d2_g = OCLArray.empty_like(data) if data.dtype.type == np.float32: im = OCLImage.empty(data.shape[::1],dtype = np.float32) elif data.dtype.type == np.complex64: im = OCLImage.empty(data.shape[::1],dtype = np.float32, num_channels=2) im.copy_buffer(d1_g) d2_g.copy_image(im) return d2_g.get()
def resample_buf(data, new_shape): """resamples d""" d1_g = OCLArray.from_array(data) d2_g = OCLArray.empty(new_shape, data.dtype) if data.dtype.type == np.float32: im = OCLImage.empty(data.shape[::1], dtype=np.float32) elif data.dtype.type == np.complex64: im = OCLImage.empty(data.shape[::1], dtype=np.float32, num_channels=2) im.copy_buffer(d1_g) d2_g.copy_image_resampled(im) return d2_g.get()
def transfer(data): """transfers data""" d1_g = OCLArray.from_array(data) d2_g = OCLArray.empty_like(data) if data.dtype.type == np.float32: im = OCLImage.empty(data.shape[::1], dtype=np.float32) elif data.dtype.type == np.complex64: im = OCLImage.empty(data.shape[::1], dtype=np.float32, num_channels=2) im.copy_buffer(d1_g) d2_g.copy_image(im) return d2_g.get()
def resample_buf(data, new_shape): """resamples d""" d1_g = OCLArray.from_array(data) d2_g = OCLArray.empty(new_shape,data.dtype) if data.dtype.type == np.float32: im = OCLImage.empty(data.shape[::1],dtype = np.float32) elif data.dtype.type == np.complex64: im = OCLImage.empty(data.shape[::1],dtype = np.float32, num_channels=2) im.copy_buffer(d1_g) d2_g.copy_image_resampled(im) return d2_g.get()
def scale(data, scale=(1., 1., 1.), interp="linear"): """returns a interpolated, scaled version of data scale = (scale_z,scale_y,scale_x) or scale = scale_all interp = "linear" | "nearest" """ bop = {"linear": "", "nearest": "-D USENEAREST"} if not interp in bop.keys(): raise KeyError("interp = '%s' not defined ,valid: %s" % (interp, bop.keys())) if not isinstance(scale, (tuple, list, np.ndarray)): scale = (scale, ) * 3 if len(scale) != 3: raise ValueError("scale = %s misformed" % scale) d_im = OCLImage.from_array(data) nshape = np.array(data.shape) * np.array(scale) nshape = tuple(nshape.astype(np.int)) res_g = OCLArray.empty(nshape, np.float32) prog = OCLProgram(abspath("kernels/scale.cl"), build_options=[bop[interp]]) prog.run_kernel("scale", res_g.shape[::-1], None, d_im, res_g.data) return res_g.get()
def bilateral3(data, size_filter, sigma_p, sigma_x=10.): """bilateral filter """ dtype = data.dtype.type dtypes_kernels = { np.float32: "bilat3_float", } if not dtype in dtypes_kernels: logger.info("data type %s not supported yet (%s), casting to float:" % (dtype, list(dtypes_kernels.keys()))) data = data.astype(np.float32) dtype = data.dtype.type img = OCLImage.from_array(data) res = OCLArray.empty_like(data) prog = OCLProgram(abspath("kernels/bilateral3.cl")) logger.debug("in bilateral3, image shape: {}".format(img.shape)) prog.run_kernel(dtypes_kernels[dtype], img.shape, None, img, res.data, np.int32(img.shape[0]), np.int32(img.shape[1]), np.int32(size_filter), np.float32(sigma_x), np.float32(sigma_p)) return res.get()
def _transfer_dn(self, dn): if self._is_subsampled: self._im_dn = OCLImage.from_array( self._copy_arr_with_correct_type(dn)) else: self._buf_dn = OCLArray.from_array( self._copy_arr_with_correct_type(dn))
def tv2(data, weight, Niter=50): """ chambolles tv regularized denoising weight should be around 2+1.5*noise_sigma """ prog = OCLProgram(abspath("kernels/tv2.cl")) data_im = OCLImage.from_array(data.astype(np, float32, copy=False)) pImgs = [ dev.createImage(data.shape[::-1], mem_flags=cl.mem_flags.READ_WRITE, dtype=np.float32, channel_order=cl.channel_order.RGBA) for i in range(2) ] outImg = dev.createImage(data.shape[::-1], dtype=np.float32, mem_flags=cl.mem_flags.READ_WRITE) dev.writeImage(inImg, data.astype(np.float32)) dev.writeImage(pImgs[0], np.zeros((4, ) + data.shape, dtype=np.float32)) dev.writeImage(pImgs[1], np.zeros((4, ) + data.shape, dtype=np.float32)) for i in range(Niter): proc.runKernel("div_step", inImg.shape, None, inImg, pImgs[i % 2], outImg) proc.runKernel("grad_step", inImg.shape, None, outImg, pImgs[i % 2], pImgs[1 - i % 2], np.float32(weight)) return dev.readImage(outImg, dtype=np.float32)
def tv2(data, weight, Niter=50): """ chambolles tv regularized denoising weight should be around 2+1.5*noise_sigma """ prog = OCLProgram(abspath("kernels/tv2.cl")) data_im = OCLImage.from_array(data.astype(np, float32, copy=False)) pImgs = [ dev.createImage( data.shape[::-1], mem_flags=cl.mem_flags.READ_WRITE, dtype=np.float32, channel_order=cl.channel_order.RGBA ) for i in range(2) ] outImg = dev.createImage(data.shape[::-1], dtype=np.float32, mem_flags=cl.mem_flags.READ_WRITE) dev.writeImage(inImg, data.astype(np.float32)) dev.writeImage(pImgs[0], np.zeros((4,) + data.shape, dtype=np.float32)) dev.writeImage(pImgs[1], np.zeros((4,) + data.shape, dtype=np.float32)) for i in range(Niter): proc.runKernel("div_step", inImg.shape, None, inImg, pImgs[i % 2], outImg) proc.runKernel("grad_step", inImg.shape, None, outImg, pImgs[i % 2], pImgs[1 - i % 2], np.float32(weight)) return dev.readImage(outImg, dtype=np.float32)
def bilateral3(data, size_filter, sigma_p, sigma_x = 10.): """bilateral filter """ dtype = data.dtype.type dtypes_kernels = {np.float32:"bilat3_float",} if not dtype in dtypes_kernels.keys(): logger.info("data type %s not supported yet (%s), casting to float:"%(dtype,dtypes_kernels.keys())) data = data.astype(np.float32) dtype = data.dtype.type img = OCLImage.from_array(data) res = OCLArray.empty_like(data) prog = OCLProgram(abspath("kernels/bilateral3.cl")) print img.shape prog.run_kernel(dtypes_kernels[dtype], img.shape,None, img,res.data, np.int32(img.shape[0]),np.int32(img.shape[1]), np.int32(size_filter),np.float32(sigma_x),np.float32(sigma_p)) return res.get()
def _setup_gpu(self): dev = get_device() self._queue = dev.queue self._ctx = dev.context prog = OCLProgram(absPath("kernels/bpm_3d_kernels.cl")) # the buffers/ images Nx, Ny = self.simul_xy Nx0, Ny0 = self.shape[:2] self._plan = fft_plan((Ny, Nx), **self.fftplan_kwargs) self._buf_plane = OCLArray.empty((Ny, Nx), np.complex64) self._buf_H = OCLArray.empty((Ny, Nx), np.complex64) self._img_xy = OCLImage.empty((Ny, Nx), dtype=np.float32, num_channels=2) # buffer for the weighted dn average self.intens_g = OCLArray.empty((1, Ny, Nx), dtype=Bpm3d._real_type) self.intens_dn_g = OCLArray.empty((1, Ny, Nx), dtype=Bpm3d._real_type) self.intens_sum_g = OCLArray.zeros((), dtype=Bpm3d._real_type) self.intens_dn_sum_g = OCLArray.zeros((), dtype=Bpm3d._real_type) # the kernels self._kernel_compute_propagator = prog.compute_propagator self._kernel_compute_propagator.set_scalar_arg_dtypes((None, ) + (np.float32, ) * 5) self._kernel_compute_propagator_buf = prog.compute_propagator_buf self._kernel_compute_propagator_buf.set_scalar_arg_dtypes( (None, ) + (np.float32, ) * 5 + (None, ) * 2) self._kernel_mult_complex = prog.mult self._kernel_im_to_buf_field = prog.img_to_buf_field self._kernel_im_to_buf_intensity = prog.img_to_buf_intensity self._kernel_im_to_im_intensity = prog.img_to_img_intensity self._kernel_buf_to_buf_field = prog.buf_to_buf_field self._kernel_buf_to_buf_intensity = prog.buf_to_buf_intensity self._kernel_mult_dn_img_float = prog.mult_dn_image self._kernel_mult_dn_buf_float = prog.mult_dn self._kernel_mult_dn_img_complex = prog.mult_dn_image_complex self._kernel_mult_dn_buf_complex = prog.mult_dn_complex self._kernel_mult_dn_img_float_local = prog.mult_dn_image_local self._kernel_mult_dn_buf_float_local = prog.mult_dn_local self._kernel_mult_dn_img_complex_local = prog.mult_dn_image_complex_local self._kernel_mult_dn_buf_complex_local = prog.mult_dn_complex_local self._kernel_reduction = OCLMultiReductionKernel( np.float32, neutral="0", reduce_expr="a+b", map_exprs=["a[i]", "b[i]"], arguments="__global float *a, __global float *b") self._fill_propagator(self.n0)
def _ocl_star_dist(a, n_rays=32): from gputools import OCLProgram, OCLArray, OCLImage (np.isscalar(n_rays) and 0 < int(n_rays)) or _raise(ValueError()) n_rays = int(n_rays) src = OCLImage.from_array(a.astype(np.uint16, copy=False)) dst = OCLArray.empty(a.shape + (n_rays, ), dtype=np.float32) program = OCLProgram(path_absolute("kernels/stardist2d.cl"), build_options=['-D', 'N_RAYS=%d' % n_rays]) program.run_kernel('star_dist', src.shape, None, dst.data, src) return dst.get()
def _fill_buf_plane(self, u0): """fills buf plane from the array u0 with the correct sizes...""" u0 = u0.astype(np.complex64, copy=False) if u0.shape == self._buf_plane.shape: self._buf_plane.write_array(u0) else: # interpolate self._buf_plane.copy_image_resampled(OCLImage.from_array(u0))
def _fill_buf_plane(self, u0): """fills buf plane from the array u0 with the correct sizes...""" u0 = u0.astype(np.complex64, copy=False) if u0.shape==self._buf_plane.shape: self._buf_plane.write_array(u0) else: # interpolate self._buf_plane.copy_image_resampled(OCLImage.from_array(u0))
def scale_bicubic(data, scale=(1., 1., 1.)): """ returns a interpolated, scaled version of data the output shape is scaled too. Parameters ---------- data: ndarray 3d input array scale: float, tuple scaling factor along each axis (x,y,z) interpolation: str either "nearest" or "linear" Returns ------- scaled output """ if not (isinstance(data, np.ndarray) and data.ndim == 3): raise ValueError("input data has to be a 3d array!") options_types = { np.uint8: ["-D", "TYPENAME=uchar", "-D", "READ_IMAGE=read_imageui"], np.uint16: ["-D", "TYPENAME=short", "-D", "READ_IMAGE=read_imageui"], np.float32: ["-D", "TYPENAME=float", "-D", "READ_IMAGE=read_imagef"], } dtype = data.dtype.type if not dtype in options_types: raise ValueError("type %s not supported! Available: %s" % (dtype, str(list(options_types.keys())))) if not isinstance(scale, (tuple, list, np.ndarray)): scale = (scale, ) * 3 if len(scale) != 3: raise ValueError("scale = %s misformed" % scale) d_im = OCLImage.from_array(data) nshape = _scale_shape(data.shape, scale) res_g = OCLArray.empty(nshape, dtype) prog = OCLProgram(abspath("kernels/scale.cl"), build_options=options_types[dtype]) prog.run_kernel("scale_bicubic", res_g.shape[::-1], None, d_im, res_g.data) return res_g.get()
def stardist_from_labels(a, n_rays=32): """ assumes a to be a label image with integer values that encode object ids. id 0 denotes background. """ out_shape = a.shape + (n_rays, ) src = OCLImage.from_array(a.astype(np.uint16, copy=False)) dst = OCLArray.empty(out_shape, dtype=np.float32) # program = OCLProgram("/home/uschmidt/research/dsb2018/notebooks/kernel.cl", build_options=["-D", "N_RAYS=%d" % n_rays]) # program = OCLProgram("kernel.cl", build_options=["-D", "N_RAYS=%d" % n_rays]) program = OCLProgram(src_str=kernel, build_options=["-D", "N_RAYS=%d" % n_rays]) program.run_kernel('star_dist', src.shape, None, dst.data, src) return dst.get()
def _setup_gpu(self): dev = get_device() self._queue = dev.queue self._ctx = dev.context prog = OCLProgram(absPath("kernels/bpm_3d_kernels.cl")) # the buffers/ images Nx, Ny = self.simul_xy Nx0, Ny0 = self.shape[:2] self._plan = fft_plan((Ny, Nx), **self.fftplan_kwargs) self._buf_plane = OCLArray.empty((Ny, Nx), np.complex64) self._buf_H = OCLArray.empty((Ny, Nx), np.complex64) self._img_xy = OCLImage.empty((Ny, Nx), dtype=np.float32, num_channels=2) # buffer for the weighted dn average self.intens_g = OCLArray.empty((1, Ny, Nx), dtype=Bpm3d._real_type) self.intens_dn_g = OCLArray.empty((1, Ny, Nx), dtype=Bpm3d._real_type) self.intens_sum_g = OCLArray.zeros((), dtype=Bpm3d._real_type) self.intens_dn_sum_g = OCLArray.zeros((), dtype=Bpm3d._real_type) # the kernels self._kernel_compute_propagator = prog.compute_propagator self._kernel_compute_propagator.set_scalar_arg_dtypes((None,)+(np.float32,)*5) self._kernel_compute_propagator_buf = prog.compute_propagator_buf self._kernel_compute_propagator_buf.set_scalar_arg_dtypes((None,)+(np.float32,)*5+(None,)*2) self._kernel_mult_complex = prog.mult self._kernel_im_to_buf_field = prog.img_to_buf_field self._kernel_im_to_buf_intensity = prog.img_to_buf_intensity self._kernel_im_to_im_intensity = prog.img_to_img_intensity self._kernel_buf_to_buf_field = prog.buf_to_buf_field self._kernel_buf_to_buf_intensity = prog.buf_to_buf_intensity self._kernel_mult_dn_img_float = prog.mult_dn_image self._kernel_mult_dn_buf_float = prog.mult_dn self._kernel_mult_dn_img_complex = prog.mult_dn_image_complex self._kernel_mult_dn_buf_complex = prog.mult_dn_complex self._kernel_mult_dn_img_float_local = prog.mult_dn_image_local self._kernel_mult_dn_buf_float_local = prog.mult_dn_local self._kernel_mult_dn_img_complex_local = prog.mult_dn_image_complex_local self._kernel_mult_dn_buf_complex_local = prog.mult_dn_complex_local self._kernel_reduction = OCLMultiReductionKernel(np.float32, neutral="0", reduce_expr="a+b", map_exprs=["a[i]", "b[i]"], arguments="__global float *a, __global float *b") self._fill_propagator(self.n0)
def _ocl_star_dist(lbl, n_rays=32, grid=(1, 1)): from gputools import OCLProgram, OCLArray, OCLImage (np.isscalar(n_rays) and 0 < int(n_rays)) or _raise(ValueError()) n_rays = int(n_rays) # slicing with grid is done with tuple(slice(0, None, g) for g in grid) res_shape = tuple((s - 1) // g + 1 for s, g in zip(lbl.shape, grid)) src = OCLImage.from_array(lbl.astype(np.uint16, copy=False)) dst = OCLArray.empty(res_shape + (n_rays, ), dtype=np.float32) program = OCLProgram(path_absolute("kernels/stardist2d.cl"), build_options=['-D', 'N_RAYS=%d' % n_rays]) program.run_kernel('star_dist', res_shape[::-1], None, dst.data, src, np.int32(grid[0]), np.int32(grid[1])) return dst.get()
def _ocl_star_dist3D(lbl, rays, grid=(1, 1, 1)): from gputools import OCLProgram, OCLArray, OCLImage grid = _normalize_grid(grid, 3) # if not all(g==1 for g in grid): # raise NotImplementedError("grid not yet implemented for OpenCL version of star_dist3D()...") res_shape = tuple(s // g for s, g in zip(lbl.shape, grid)) lbl_g = OCLImage.from_array(lbl.astype(np.uint16, copy=False)) dist_g = OCLArray.empty(res_shape + (len(rays), ), dtype=np.float32) rays_g = OCLArray.from_array(rays.vertices.astype(np.float32, copy=False)) program = OCLProgram(path_absolute("kernels/stardist3d.cl"), build_options=['-D', 'N_RAYS=%d' % len(rays)]) program.run_kernel('stardist3d', res_shape[::-1], None, lbl_g, rays_g.data, dist_g.data, np.int32(grid[0]), np.int32(grid[1]), np.int32(grid[2])) return dist_g.get()
def bilateral2(data, fSize, sigma_p, sigma_x=10.): """bilateral filter """ dtype = data.dtype.type dtypes_kernels = {np.float32: "bilat2_float", np.uint16: "bilat2_short"} if not dtype in dtypes_kernels.keys(): logger.info("data type %s not supported yet (%s), casting to float:" % (dtype, dtypes_kernels.keys())) data = data.astype(np.float32) dtype = data.dtype.type img = OCLImage.from_array(data) res = OCLArray.empty_like(data) prog = OCLProgram(abspath("kernels/bilateral2.cl")) prog.run_kernel(dtypes_kernels[dtype], img.shape, None, img, res.data, np.int32(img.shape[0]), np.int32(img.shape[1]), np.int32(fSize), np.float32(sigma_x), np.float32(sigma_p)) return res.get()
def affine(data, mat = np.identity(4), interp = "linear"): """affine transform data with matrix mat """ bop = {"linear":"","nearest":"-D USENEAREST"} if not interp in bop.keys(): raise KeyError("interp = '%s' not defined ,valid: %s"%(interp,bop.keys())) d_im = OCLImage.from_array(data) res_g = OCLArray.empty(data.shape,np.float32) mat_g = OCLArray.from_array(np.linalg.inv(mat).astype(np.float32,copy=False)) prog = OCLProgram(abspath("kernels/transformations.cl") , build_options=[bop[interp]]) prog.run_kernel("affine", data.shape[::-1],None, d_im,res_g.data,mat_g.data) return res_g.get()
def affine(data, mat = np.identity(4), mode ="linear"): """affine transform data with matrix mat """ bop = {"linear":"","nearest":"-D USENEAREST"} if not mode in bop.keys(): raise KeyError("mode = '%s' not defined ,valid: %s"%(mode, bop.keys())) d_im = OCLImage.from_array(data) res_g = OCLArray.empty(data.shape,np.float32) mat_g = OCLArray.from_array(np.linalg.inv(mat).astype(np.float32,copy=False)) prog = OCLProgram(abspath("kernels/transformations.cl") , build_options=[bop[mode]]) prog.run_kernel("affine", data.shape[::-1],None, d_im,res_g.data,mat_g.data) return res_g.get()
def _convolve3_old(data,h, dev = None): """convolves 3d data with kernel h on the GPU Device dev boundary conditions are clamping to edge. h is converted to float32 if dev == None the default one is used """ if dev is None: dev = get_device() if dev is None: raise ValueError("no OpenCLDevice found...") dtype = data.dtype.type dtypes_options = {np.float32:"", np.uint16:"-D SHORTTYPE"} if not dtype in dtypes_options.keys(): raise TypeError("data type %s not supported yet, please convert to:"%dtype,dtypes_options.keys()) prog = OCLProgram(abspath("kernels/convolve3.cl"), build_options = dtypes_options[dtype]) hbuf = OCLArray.from_array(h.astype(np.float32)) img = OCLImage.from_array(data) res = OCLArray.empty(data.shape,dtype=np.float32) Ns = [np.int32(n) for n in data.shape+h.shape] prog.run_kernel("convolve3d",img.shape,None, img,hbuf.data,res.data, *Ns) return res.get()
def scale(data, scale = (1.,1.,1.), interp = "linear"): """returns a interpolated, scaled version of data scale = (scale_z,scale_y,scale_x) or scale = scale_all interp = "linear" | "nearest" """ bop = {"linear":[],"nearest":["-D","USENEAREST"]} if not interp in bop.keys(): raise KeyError("interp = '%s' not defined ,valid: %s"%(interp,bop.keys())) if not isinstance(scale,(tuple, list, np.ndarray)): scale = (scale,)*3 if len(scale) != 3: raise ValueError("scale = %s misformed"%scale) d_im = OCLImage.from_array(data) nshape = np.array(data.shape)*np.array(scale) nshape = tuple(nshape.astype(np.int)) res_g = OCLArray.empty(nshape,np.float32) prog = OCLProgram(abspath("kernels/scale.cl"), build_options=bop[interp]) prog.run_kernel("scale", res_g.shape[::-1],None, d_im,res_g.data) return res_g.get()
def _transfer_dn(self, dn): if self._is_subsampled: self._im_dn = OCLImage.from_array(self._copy_arr_with_correct_type(dn)) else: self._buf_dn = OCLArray.from_array(self._copy_arr_with_correct_type(dn))
def image_from_array(data): im = OCLImage.from_array(data) assert np.allclose(data,im.get())
def convolve_spatial2(im, hs, mode="constant", plan=None, return_plan=False): """ spatial varying convolution of an 2d image with a 2d grid of psfs shape(im_ = (Ny,Nx) shape(hs) = (Gy,Gx, Hy,Hx) the input image im is subdivided into (Gy,Gz) blocks hs[j,i] is the psf at the center of each block (i,j) as of now each image dimension has to be divisble by the grid dim, i.e. Nx % Gx == 0 Ny % Gy == 0 mode can be: "constant" - assumed values to be zero "wrap" - periodic boundary condition """ if im.ndim != 2 or hs.ndim != 4: raise ValueError("wrong dimensions of input!") if not np.all([n % g == 0 for n, g in zip(im.shape, hs.shape[:2])]): raise NotImplementedError( "shape of image has to be divisible by Gx Gy = %s shape mismatch" % (str(hs.shape[:2]))) mode_str = {"constant": "CLK_ADDRESS_CLAMP", "wrap": "CLK_ADDRESS_REPEAT"} Ny, Nx = im.shape Gy, Gx = hs.shape[:2] # the size of each block within the grid Nblock_y, Nblock_x = Ny / Gy, Nx / Gx # the size of the overlapping patches with safety padding Npatch_x, Npatch_y = _next_power_of_2(3 * Nblock_x), _next_power_of_2( 3 * Nblock_y) #Npatch_x, Npatch_y = _next_power_of_2(2*Nblock_x), _next_power_of_2(2*Nblock_y) print(Nblock_x, Npatch_x) hs = np.fft.fftshift(pad_to_shape(hs, (Gy, Gx, Npatch_y, Npatch_x)), axes=(2, 3)) prog = OCLProgram(abspath("kernels/conv_spatial.cl"), build_options=["-D", "ADDRESSMODE=%s" % mode_str[mode]]) if plan is None: plan = fft_plan((Npatch_y, Npatch_x)) patches_g = OCLArray.empty((Gy, Gx, Npatch_y, Npatch_x), np.complex64) h_g = OCLArray.from_array(hs.astype(np.complex64)) im_g = OCLImage.from_array(im.astype(np.float32, copy=False)) x0s = Nblock_x * np.arange(Gx) y0s = Nblock_y * np.arange(Gy) print(x0s) for i, _x0 in enumerate(x0s): for j, _y0 in enumerate(y0s): prog.run_kernel( "fill_patch2", (Npatch_x, Npatch_y), None, im_g, np.int32(_x0 + Nblock_x / 2 - Npatch_x / 2), np.int32(_y0 + Nblock_y / 2 - Npatch_y / 2), patches_g.data, np.int32(i * Npatch_x * Npatch_y + j * Gx * Npatch_x * Npatch_y)) # convolution fft(patches_g, inplace=True, batch=Gx * Gy, plan=plan) fft(h_g, inplace=True, batch=Gx * Gy, plan=plan) prog.run_kernel("mult_inplace", (Npatch_x * Npatch_y * Gx * Gy, ), None, patches_g.data, h_g.data) fft(patches_g, inplace=True, inverse=True, batch=Gx * Gy, plan=plan) #return patches_g.get() #accumulate res_g = OCLArray.empty(im.shape, np.float32) for i in range(Gx + 1): for j in range(Gy + 1): prog.run_kernel("interpolate2", (Nblock_x, Nblock_y), None, patches_g.data, res_g.data, np.int32(i), np.int32(j), np.int32(Gx), np.int32(Gy), np.int32(Npatch_x), np.int32(Npatch_y)) res = res_g.get() if return_plan: return res, plan else: return res
def convolve_spatial3(im, hs, mode="constant", plan=None, return_plan=False, pad_factor=2): """ spatial varying convolution of an 3d image with a 3d grid of psfs shape(im_ = (Nz,Ny,Nx) shape(hs) = (Gz,Gy,Gx, Hz,Hy,Hx) the input image im is subdivided into (Gx,Gy,Gz) blocks hs[k,j,i] is the psf at the center of each block (i,j,k) as of now each image dimension has to be divisble by the grid dim, i.e. Nx % Gx == 0 Ny % Gy == 0 Nz % Gz == 0 mode can be: "constant" - assumed values to be zero "wrap" - periodic boundary condition """ if im.ndim != 3 or hs.ndim != 6: raise ValueError("wrong dimensions of input!") if not np.all([n % g == 0 for n, g in zip(im.shape, hs.shape[:3])]): raise NotImplementedError( "shape of image has to be divisible by Gx Gy = %s !" % (str(hs.shape[:3]))) mode_str = {"constant": "CLK_ADDRESS_CLAMP", "wrap": "CLK_ADDRESS_REPEAT"} Ns = tuple(im.shape) Gs = tuple(hs.shape[:3]) # the size of each block within the grid Nblocks = [n / g for n, g in zip(Ns, Gs)] # the size of the overlapping patches with safety padding Npatchs = tuple([_next_power_of_2(pad_factor * nb) for nb in Nblocks]) print(hs.shape) hs = np.fft.fftshift(pad_to_shape(hs, Gs + Npatchs), axes=(3, 4, 5)) prog = OCLProgram(abspath("kernels/conv_spatial.cl"), build_options=["-D", "ADDRESSMODE=%s" % mode_str[mode]]) if plan is None: plan = fft_plan(Npatchs) patches_g = OCLArray.empty(Gs + Npatchs, np.complex64) h_g = OCLArray.from_array(hs.astype(np.complex64)) im_g = OCLImage.from_array(im.astype(np.float32, copy=False)) Xs = [nb * np.arange(g) for nb, g in zip(Nblocks, Gs)] print(Nblocks) # this loops over all i,j,k for (k, _z0), (j, _y0), (i, _x0) in product(*[enumerate(X) for X in Xs]): prog.run_kernel( "fill_patch3", Npatchs[::-1], None, im_g, np.int32(_x0 + Nblocks[2] / 2 - Npatchs[2] / 2), np.int32(_y0 + Nblocks[1] / 2 - Npatchs[1] / 2), np.int32(_z0 + Nblocks[0] / 2 - Npatchs[0] / 2), patches_g.data, np.int32(i * np.prod(Npatchs) + j * Gs[2] * np.prod(Npatchs) + k * Gs[2] * Gs[1] * np.prod(Npatchs))) print(patches_g.shape, h_g.shape) # convolution fft(patches_g, inplace=True, batch=np.prod(Gs), plan=plan) fft(h_g, inplace=True, batch=np.prod(Gs), plan=plan) prog.run_kernel("mult_inplace", (np.prod(Npatchs) * np.prod(Gs), ), None, patches_g.data, h_g.data) fft(patches_g, inplace=True, inverse=True, batch=np.prod(Gs), plan=plan) #return patches_g.get() #accumulate res_g = OCLArray.zeros(im.shape, np.float32) for k, j, i in product(*[list(range(g + 1)) for g in Gs]): prog.run_kernel("interpolate3", Nblocks[::-1], None, patches_g.data, res_g.data, np.int32(i), np.int32(j), np.int32(k), np.int32(Gs[2]), np.int32(Gs[1]), np.int32(Gs[0]), np.int32(Npatchs[2]), np.int32(Npatchs[1]), np.int32(Npatchs[0])) res = res_g.get() if return_plan: return res, plan else: return res
def affine(data, mat=np.identity(4), mode="constant", interpolation="linear"): """ affine transform data with matrix mat, which is the inverse coordinate transform matrix (similar to ndimage.affine_transform) Parameters ---------- data, ndarray 3d array to be transformed mat, ndarray 3x3 or 4x4 inverse coordinate transform matrix mode: string boundary mode, one of the following: 'constant' pads with zeros 'edge' pads with edge values 'wrap' pads with the repeated version of the input interpolation, string interpolation mode, one of the following 'linear' 'nearest' Returns ------- res: ndarray transformed array (same shape as input) """ warnings.warn( "gputools.transform.affine: API change as of gputools>= 0.2.8: the inverse of the matrix is now used as in scipy.ndimage.affine_transform" ) if not (isinstance(data, np.ndarray) and data.ndim == 3): raise ValueError("input data has to be a 3d array!") interpolation_defines = { "linear": ["-D", "SAMPLER_FILTER=CLK_FILTER_LINEAR"], "nearest": ["-D", "SAMPLER_FILTER=CLK_FILTER_NEAREST"] } mode_defines = { "constant": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_CLAMP"], "wrap": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_REPEAT"], "edge": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_CLAMP_TO_EDGE"] } if not interpolation in interpolation_defines: raise KeyError("interpolation = '%s' not defined ,valid: %s" % (interpolation, list(interpolation_defines.keys()))) if not mode in mode_defines: raise KeyError("mode = '%s' not defined ,valid: %s" % (mode, list(mode_defines.keys()))) # reorder matrix, such that x,y,z -> z,y,x (as the kernel is assuming that) d_im = OCLImage.from_array(data.astype(np.float32, copy=False)) res_g = OCLArray.empty(data.shape, np.float32) mat_inv_g = OCLArray.from_array(mat.astype(np.float32, copy=False)) prog = OCLProgram(abspath("kernels/affine.cl"), build_options=interpolation_defines[interpolation] + mode_defines[mode]) prog.run_kernel("affine3", data.shape[::-1], None, d_im, res_g.data, mat_inv_g.data) return res_g.get()
def geometric_transform(data, mapping="c0,c1", output_shape=None, mode='constant', interpolation="linear"): """ Apply an arbitrary geometric transform. The given mapping function is used to find, for each point in the output, the corresponding coordinates in the input. The value of the input at those coordinates is determined by spline interpolation of the requested order. Parameters ---------- %(input)s mapping : {callable, scipy.LowLevelCallable} A callable object that accepts a tuple of length equal to the output array rank, and returns the corresponding input coordinates as a tuple of length equal to the input array rank. """ if not (isinstance(data, np.ndarray) and data.ndim in (2, 3)): raise ValueError("input data has to be a 2d or 3d array!") interpolation_defines = { "linear": ["-D", "SAMPLER_FILTER=CLK_FILTER_LINEAR"], "nearest": ["-D", "SAMPLER_FILTER=CLK_FILTER_NEAREST"] } mode_defines = { "constant": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_CLAMP"], "wrap": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_REPEAT"], "edge": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_CLAMP_TO_EDGE"] } if not interpolation in interpolation_defines: raise KeyError("interpolation = '%s' not defined ,valid: %s" % (interpolation, list(interpolation_defines.keys()))) if not mode in mode_defines: raise KeyError("mode = '%s' not defined ,valid: %s" % (mode, list(mode_defines.keys()))) if not data.dtype.type in cl_buffer_datatype_dict: raise KeyError( "dtype %s not supported yet (%s)" % (data.dtype.type, tuple(cl_buffer_datatype_dict.keys()))) dtype_defines = [ "-D", "DTYPE={type}".format(type=cl_buffer_datatype_dict[data.dtype.type]) ] image_functions = { np.float32: "read_imagef", np.uint8: "read_imageui", np.uint16: "read_imageui", np.int32: "read_imagei" } image_read_defines = [ "-D", "READ_IMAGE=%s" % image_functions[data.dtype.type] ] with open(abspath("kernels/geometric_transform.cl"), "r") as f: tpl = Template(f.read()) output_shape = tuple(output_shape) mappings = {"FUNC2": "c1,c0", "FUNC3": "c2,c1,c0"} mappings["FUNC%d" % data.ndim] = ",".join(reversed(mapping.split(","))) rendered = tpl.render(**mappings) d_im = OCLImage.from_array(data) res_g = OCLArray.empty(output_shape, data.dtype) prog = OCLProgram(src_str=rendered, build_options=interpolation_defines[interpolation] + mode_defines[mode] + dtype_defines + image_read_defines) kernel = "geometric_transform{ndim}".format(ndim=data.ndim) prog.run_kernel(kernel, output_shape[::-1], None, d_im, res_g.data) return res_g.get()
def _bpm_3d_image(size, units, lam = .5, u0 = None, dn = None, subsample = 1, n0 = 1., return_scattering = False, return_g = False, return_full_last = False, use_fresnel_approx = False, ): """ simulates the propagation of monochromativ wave of wavelength lam with initial conditions u0 along z in a media filled with dn size - the dimension of the image to be calulcated in pixels (Nx,Ny,Nz) units - the unit lengths of each dimensions in microns lam - the wavelength u0 - the initial field distribution, if u0 = None an incident plane wave is assumed dn - the refractive index of the medium (can be complex) """ clock = StopWatch() clock.tic("setup") Nx, Ny, Nz = size dx, dy, dz = units # subsampling Nx2, Ny2, Nz2 = (subsample*N for N in size) dx2, dy2, dz2 = (1.*d/subsample for d in units) #setting up the propagator k0 = 2.*np.pi/lam kxs = 2.*np.pi*np.fft.fftfreq(Nx2,dx2) kys = 2.*np.pi*np.fft.fftfreq(Ny2,dy2) KY, KX = np.meshgrid(kys,kxs, indexing= "ij") #H0 = np.sqrt(0.j+n0**2*k0**2-KX**2-KY**2) H0 = np.sqrt(n0**2*k0**2-KX**2-KY**2) if use_fresnel_approx: H0 = 0.j+n0**2*k0-.5*(KX**2+KY**2) outsideInds = np.isnan(H0) H = np.exp(-1.j*dz2*H0) H[outsideInds] = 0. H0[outsideInds] = 0. if u0 is None: u0 = np.ones((Ny2,Nx2),np.complex64) else: if subsample >1: u0 = zoom(np.real(u0),subsample) + 1.j*zoom(np.imag(u0),subsample) # setting up the gpu buffers and kernels program = OCLProgram(absPath("kernels/bpm_3d_kernels.cl")) plan = fft_plan((Ny2,Nx2)) plane_g = OCLArray.from_array(u0.astype(np.complex64)) h_g = OCLArray.from_array(H.astype(np.complex64)) if dn is not None: if isinstance(dn,OCLImage): dn_g = dn else: if dn.dtype.type in (np.complex64,np.complex128): dn_complex = np.zeros(dn.shape+(2,),np.float32) dn_complex[...,0] = np.real(dn) dn_complex[...,1] = np.imag(dn) dn_g = OCLImage.from_array(dn_complex) else: dn_g = OCLImage.from_array(dn.astype(np.float32)) isComplexDn = dn.dtype.type in (np.complex64,np.complex128) else: #dummy dn dn_g = OCLArray.empty((1,)*3,np.float16) if return_scattering: cos_theta = np.real(H0)/n0/k0 # = cos(theta) scatter_weights = cos_theta scatter_weights_g = OCLArray.from_array(scatter_weights.astype(np.float32)) # = cos(theta)^2 gfactor_weights = cos_theta**2 gfactor_weights_g = OCLArray.from_array(gfactor_weights.astype(np.float32)) #return None,None,scatter_weights, gfactor_weights scatter_cross_sec_g = OCLArray.zeros(Nz,"float32") gfactor_g = OCLArray.zeros(Nz,"float32") plain_wave_dct = Nx2*Ny2*np.exp(-1.j*k0*n0*np.arange(Nz)*dz).astype(np.complex64) reduce_kernel = OCLReductionKernel( np.float32, neutral="0", reduce_expr="a+b", map_expr="weights[i]*cfloat_abs(field[i]-(i==0)*plain)*cfloat_abs(field[i]-(i==0)*plain)", arguments="__global cfloat_t *field, __global float * weights,cfloat_t plain") # reduce_kernel = OCLReductionKernel( # np.float32, neutral="0", # reduce_expr="a+b", # map_expr = "weights[i]*(i!=0)*cfloat_abs(field[i])*cfloat_abs(field[i])", # arguments = "__global cfloat_t *field, __global float * weights,cfloat_t plain") u_g = OCLArray.empty((Nz,Ny,Nx),dtype=np.complex64) program.run_kernel("copy_subsampled_buffer",(Nx,Ny),None, u_g.data,plane_g.data, np.int32(subsample), np.int32(0)) clock.toc("setup") clock.tic("run") for i in range(Nz-1): for substep in range(subsample): fft(plane_g,inplace = True, plan = plan) program.run_kernel("mult",(Nx2*Ny2,),None, plane_g.data,h_g.data) if return_scattering and substep == (subsample-1): scatter_cross_sec_g[i+1] = reduce_kernel(plane_g, scatter_weights_g, plain_wave_dct[i+1]) gfactor_g[i+1] = reduce_kernel(plane_g, gfactor_weights_g, plain_wave_dct[i+1]) fft(plane_g,inplace = True, inverse = True, plan = plan) if dn is not None: if isComplexDn: program.run_kernel("mult_dn_complex_image",(Nx2,Ny2),None, plane_g.data,dn_g, np.float32(k0*dz2), np.float32(n0), np.int32(subsample*(i+1.)+substep), np.int32(subsample)) else: program.run_kernel("mult_dn_image",(Nx2,Ny2),None, plane_g.data,dn_g, np.float32(k0*dz2), np.float32(n0), np.int32(subsample*(i+1.)+substep), np.int32(subsample)) program.run_kernel("copy_subsampled_buffer",(Nx,Ny),None, u_g.data,plane_g.data, np.int32(subsample), np.int32((i+1)*Nx*Ny)) clock.toc("run") print clock result = (u_g.get(), dn_g.get(),) if return_scattering: # normalizing prefactor dkx = dx2/Nx2 # prefac = 1./Nx2/Ny2*dx2*dy2/4./np.pi/n0 prefac = 1./Nx2/Ny2*dx2*dy2 p = prefac*scatter_cross_sec_g.get() result += (p,) if return_g: prefac = 1./Nx2/Ny2*dx2*dy2 g = prefac*gfactor_g.get()/p result += (g,) if return_full_last: result += (plane_g.get(),) return result
def nlm3(data, sigma, size_filter=2, size_search=3): """ Fast version of Non local mean denoising of 3 dimensional data see [1]_ Parameters ---------- data: 3d ndarray the input volume sigma: float denoising strength size_filter: int the half size of the image patches (i.e. width is 2*size_filter+1 along every dimension) size_search: int the half size of the search window (i.e. width is 2*size_search+1 along every dimension) Returns ------- ndarray the denoised volume Examples -------- >>> d = np.random.uniform(0,1,(100,)*3) >>> d[40:60,40:60,40:60] += 5 >>> res = nlm3(d,1.,3,4) References ---------- .. [1] Buades, Antoni, Bartomeu Coll, and J-M. Morel. "A non-local algorithm for image denoising." CVPR 2005. """ prog = OCLProgram(abspath("kernels/nlm3.cl"), build_options="-D FS=%i -D BS=%i" % (size_filter, size_search)) data = data.astype(np.float32, copy=False) img = OCLImage.from_array(data) distImg = OCLImage.empty_like(data) distImg = OCLImage.empty_like(data) tmpImg = OCLImage.empty_like(data) tmpImg2 = OCLImage.empty_like(data) accBuf = OCLArray.zeros(data.shape, np.float32) weightBuf = OCLArray.zeros(data.shape, np.float32) for dx in range(size_search + 1): for dy in range(-size_search, size_search + 1): for dz in range(-size_search, size_search + 1): prog.run_kernel("dist", img.shape, None, img, tmpImg, np.int32(dx), np.int32(dy), np.int32(dz)) prog.run_kernel("convolve", img.shape, None, tmpImg, tmpImg2, np.int32(1)) prog.run_kernel("convolve", img.shape, None, tmpImg2, tmpImg, np.int32(2)) prog.run_kernel("convolve", img.shape, None, tmpImg, distImg, np.int32(4)) prog.run_kernel("computePlus", img.shape, None, img, distImg, accBuf.data, weightBuf.data, np.int32(img.shape[0]), np.int32(img.shape[1]), np.int32(img.shape[2]), np.int32(dx), np.int32(dy), np.int32(dz), np.float32(sigma)) if any([dx, dy, dz]): prog.run_kernel("computeMinus", img.shape, None, img, distImg, accBuf.data, weightBuf.data, np.int32(img.shape[0]), np.int32(img.shape[1]), np.int32(img.shape[2]), np.int32(dx), np.int32(dy), np.int32(dz), np.float32(sigma)) acc = accBuf.get() weights = weightBuf.get() return acc / weights
def convolve_spatial2(im, hs, mode = "constant", plan = None, return_plan = False): """ spatial varying convolution of an 2d image with a 2d grid of psfs shape(im_ = (Ny,Nx) shape(hs) = (Gy,Gx, Hy,Hx) the input image im is subdivided into (Gy,Gz) blocks hs[j,i] is the psf at the center of each block (i,j) as of now each image dimension has to be divisble by the grid dim, i.e. Nx % Gx == 0 Ny % Gy == 0 mode can be: "constant" - assumed values to be zero "wrap" - periodic boundary condition """ if im.ndim !=2 or hs.ndim !=4: raise ValueError("wrong dimensions of input!") if not np.all([n%g==0 for n,g in zip(im.shape,hs.shape[:2])]): raise NotImplementedError("shape of image has to be divisible by Gx Gy = %s shape mismatch"%(str(hs.shape[:2]))) mode_str = {"constant":"CLK_ADDRESS_CLAMP", "wrap":"CLK_ADDRESS_REPEAT"} Ny, Nx = im.shape Gy, Gx = hs.shape[:2] # the size of each block within the grid Nblock_y, Nblock_x = Ny/Gy, Nx/Gx # the size of the overlapping patches with safety padding Npatch_x, Npatch_y = _next_power_of_2(3*Nblock_x), _next_power_of_2(3*Nblock_y) #Npatch_x, Npatch_y = _next_power_of_2(2*Nblock_x), _next_power_of_2(2*Nblock_y) print Nblock_x, Npatch_x hs = np.fft.fftshift(pad_to_shape(hs,(Gy,Gx,Npatch_y,Npatch_x)),axes=(2,3)) prog = OCLProgram(abspath("kernels/conv_spatial.cl"), build_options=["-D","ADDRESSMODE=%s"%mode_str[mode]]) if plan is None: plan = fft_plan((Npatch_y,Npatch_x)) patches_g = OCLArray.empty((Gy,Gx,Npatch_y,Npatch_x),np.complex64) h_g = OCLArray.from_array(hs.astype(np.complex64)) im_g = OCLImage.from_array(im.astype(np.float32,copy=False)) x0s = Nblock_x*np.arange(Gx) y0s = Nblock_y*np.arange(Gy) print x0s for i,_x0 in enumerate(x0s): for j,_y0 in enumerate(y0s): prog.run_kernel("fill_patch2",(Npatch_x,Npatch_y),None, im_g, np.int32(_x0+Nblock_x/2-Npatch_x/2), np.int32(_y0+Nblock_y/2-Npatch_y/2), patches_g.data, np.int32(i*Npatch_x*Npatch_y+j*Gx*Npatch_x*Npatch_y)) # convolution fft(patches_g,inplace=True, batch = Gx*Gy, plan = plan) fft(h_g,inplace=True, batch = Gx*Gy, plan = plan) prog.run_kernel("mult_inplace",(Npatch_x*Npatch_y*Gx*Gy,),None, patches_g.data, h_g.data) fft(patches_g,inplace=True, inverse = True, batch = Gx*Gy, plan = plan) #return patches_g.get() #accumulate res_g = OCLArray.empty(im.shape,np.float32) for i in xrange(Gx+1): for j in xrange(Gy+1): prog.run_kernel("interpolate2",(Nblock_x,Nblock_y),None, patches_g.data,res_g.data, np.int32(i),np.int32(j), np.int32(Gx),np.int32(Gy), np.int32(Npatch_x),np.int32(Npatch_y)) res = res_g.get() if return_plan: return res, plan else: return res
def image_create_write(data): im = OCLImage.empty(data.shape,data.dtype) im.write_array(data) assert np.allclose(data,im.get())
def convolve_spatial3(im, hs, mode = "constant", plan = None, return_plan = False, pad_factor = 2): """ spatial varying convolution of an 3d image with a 3d grid of psfs shape(im_ = (Nz,Ny,Nx) shape(hs) = (Gz,Gy,Gx, Hz,Hy,Hx) the input image im is subdivided into (Gx,Gy,Gz) blocks hs[k,j,i] is the psf at the center of each block (i,j,k) as of now each image dimension has to be divisble by the grid dim, i.e. Nx % Gx == 0 Ny % Gy == 0 Nz % Gz == 0 mode can be: "constant" - assumed values to be zero "wrap" - periodic boundary condition """ if im.ndim !=3 or hs.ndim !=6: raise ValueError("wrong dimensions of input!") if not np.all([n%g==0 for n,g in zip(im.shape,hs.shape[:3])]): raise NotImplementedError("shape of image has to be divisible by Gx Gy = %s !"%(str(hs.shape[:3]))) mode_str = {"constant":"CLK_ADDRESS_CLAMP", "wrap":"CLK_ADDRESS_REPEAT"} Ns = tuple(im.shape) Gs = tuple(hs.shape[:3]) # the size of each block within the grid Nblocks = [n/g for n,g in zip(Ns,Gs)] # the size of the overlapping patches with safety padding Npatchs = tuple([_next_power_of_2(pad_factor*nb) for nb in Nblocks]) print hs.shape hs = np.fft.fftshift(pad_to_shape(hs,Gs+Npatchs),axes=(3,4,5)) prog = OCLProgram(abspath("kernels/conv_spatial.cl"), build_options=["-D","ADDRESSMODE=%s"%mode_str[mode]]) if plan is None: plan = fft_plan(Npatchs) patches_g = OCLArray.empty(Gs+Npatchs,np.complex64) h_g = OCLArray.from_array(hs.astype(np.complex64)) im_g = OCLImage.from_array(im.astype(np.float32,copy=False)) Xs = [nb*np.arange(g) for nb, g in zip(Nblocks,Gs)] print Nblocks # this loops over all i,j,k for (k,_z0), (j,_y0),(i,_x0) in product(*[enumerate(X) for X in Xs]): prog.run_kernel("fill_patch3",Npatchs[::-1],None, im_g, np.int32(_x0+Nblocks[2]/2-Npatchs[2]/2), np.int32(_y0+Nblocks[1]/2-Npatchs[1]/2), np.int32(_z0+Nblocks[0]/2-Npatchs[0]/2), patches_g.data, np.int32(i*np.prod(Npatchs)+ j*Gs[2]*np.prod(Npatchs)+ k*Gs[2]*Gs[1]*np.prod(Npatchs))) print patches_g.shape, h_g.shape # convolution fft(patches_g,inplace=True, batch = np.prod(Gs), plan = plan) fft(h_g,inplace=True, batch = np.prod(Gs), plan = plan) prog.run_kernel("mult_inplace",(np.prod(Npatchs)*np.prod(Gs),),None, patches_g.data, h_g.data) fft(patches_g, inplace=True, inverse = True, batch = np.prod(Gs), plan = plan) #return patches_g.get() #accumulate res_g = OCLArray.zeros(im.shape,np.float32) for k, j, i in product(*[range(g+1) for g in Gs]): prog.run_kernel("interpolate3",Nblocks[::-1],None, patches_g.data, res_g.data, np.int32(i),np.int32(j),np.int32(k), np.int32(Gs[2]),np.int32(Gs[1]),np.int32(Gs[0]), np.int32(Npatchs[2]),np.int32(Npatchs[1]),np.int32(Npatchs[0])) res = res_g.get() if return_plan: return res, plan else: return res
def _convolve_spatial3(im, hs, mode="constant", grid_dim=None, plan=None, return_plan=False, pad_factor=2): if im.ndim != 3: raise ValueError("wrong dimensions of input!") if not (hs.ndim == 6 or (hs.ndim == 3 and grid_dim)): raise ValueError("wrong dimensions of psf grid!") if grid_dim: if hs.shape != im.shape: raise ValueError("if grid_dim is set, then im.shape = hs.shape !") Gs = tuple(grid_dim) else: if not hs.ndim == 6: raise ValueError("wrong dimensions of psf grid! (Gy,Gx,Ny,Nx)") Gs = hs.shape[:3] if not np.all([n % g == 0 for n, g in zip(im.shape, Gs)]): raise NotImplementedError( "shape of image has to be divisible by Gx Gy = %s shape mismatch" % (str(hs.shape[:2]))) mode_str = { "constant": "CLK_ADDRESS_CLAMP", "wrap": "CLK_ADDRESS_REPEAT", "edge": "CLK_ADDRESS_CLAMP_TO_EDGE", "reflect": "CLK_ADDRESS_MIRRORED_REPEAT" } Ns = im.shape # the size of each block within the grid Nblocks = [n // g for n, g in zip(Ns, Gs)] # the size of the overlapping patches with safety padding Npatchs = tuple([next_power_of_2(pad_factor * nb) for nb in Nblocks]) prog = OCLProgram(abspath("kernels/conv_spatial3.cl"), build_options=["-D", "ADDRESSMODE=%s" % mode_str[mode]]) if plan is None: plan = fft_plan(Gs + Npatchs, axes=(-3, -2, -1)) Xs = [nb * np.arange(g) for nb, g in zip(Nblocks, Gs)] patches_g = OCLArray.empty(Gs + Npatchs, np.complex64) # prepare psfs if grid_dim: h_g = OCLArray.zeros(Gs + Npatchs, np.complex64) tmp_g = OCLArray.from_array(hs.astype(np.float32, copy=False)) for (k, _z0), (j, _y0), (i, _x0) in product(*[enumerate(X) for X in Xs]): prog.run_kernel( "fill_psf_grid3", Nblocks[::-1], None, tmp_g.data, np.int32(im.shape[2]), np.int32(im.shape[1]), np.int32(i * Nblocks[2]), np.int32(j * Nblocks[1]), np.int32(k * Nblocks[0]), h_g.data, np.int32(Npatchs[2]), np.int32(Npatchs[1]), np.int32(Npatchs[0]), np.int32(-Nblocks[2] // 2 + Npatchs[2] // 2), np.int32(-Nblocks[1] // 2 + Npatchs[1] // 2), np.int32(-Nblocks[0] // 2 + Npatchs[0] // 2), np.int32(i * np.prod(Npatchs) + j * Gs[2] * np.prod(Npatchs) + k * Gs[2] * Gs[1] * np.prod(Npatchs))) else: hs = np.fft.fftshift(pad_to_shape(hs, Gs + Npatchs), axes=(3, 4, 5)) h_g = OCLArray.from_array(hs.astype(np.complex64)) im_g = OCLImage.from_array(im.astype(np.float32, copy=False)) # this loops over all i,j,k for (k, _z0), (j, _y0), (i, _x0) in product(*[enumerate(X) for X in Xs]): prog.run_kernel( "fill_patch3", Npatchs[::-1], None, im_g, np.int32(_x0 + Nblocks[2] // 2 - Npatchs[2] // 2), np.int32(_y0 + Nblocks[1] // 2 - Npatchs[1] // 2), np.int32(_z0 + Nblocks[0] // 2 - Npatchs[0] // 2), patches_g.data, np.int32(i * np.prod(Npatchs) + j * Gs[2] * np.prod(Npatchs) + k * Gs[2] * Gs[1] * np.prod(Npatchs))) # convolution fft(patches_g, inplace=True, plan=plan) fft(h_g, inplace=True, plan=plan) prog.run_kernel("mult_inplace", (np.prod(Npatchs) * np.prod(Gs), ), None, patches_g.data, h_g.data) fft(patches_g, inplace=True, inverse=True, plan=plan) # return patches_g.get() # accumulate res_g = OCLArray.zeros(im.shape, np.float32) for k, j, i in product(*[list(range(g + 1)) for g in Gs]): prog.run_kernel("interpolate3", Nblocks[::-1], None, patches_g.data, res_g.data, np.int32(i), np.int32(j), np.int32(k), np.int32(Gs[2]), np.int32(Gs[1]), np.int32(Gs[0]), np.int32(Npatchs[2]), np.int32(Npatchs[1]), np.int32(Npatchs[0])) res = res_g.get() if return_plan: return res, plan else: return res
def _convolve_spatial3(im, hs, mode = "constant", grid_dim = None, plan = None, return_plan = False, pad_factor = 2): if im.ndim !=3: raise ValueError("wrong dimensions of input!") if not (hs.ndim==6 or (hs.ndim==3 and grid_dim)): raise ValueError("wrong dimensions of psf grid!") if grid_dim: if hs.shape != im.shape: raise ValueError("if grid_dim is set, then im.shape = hs.shape !") Gs = tuple(grid_dim) else: if not hs.ndim==6: raise ValueError("wrong dimensions of psf grid! (Gy,Gx,Ny,Nx)") Gs = hs.shape[:3] if not np.all([n%g==0 for n,g in zip(im.shape,Gs)]): raise NotImplementedError("shape of image has to be divisible by Gx Gy = %s shape mismatch"%(str(hs.shape[:2]))) mode_str = {"constant":"CLK_ADDRESS_CLAMP", "wrap":"CLK_ADDRESS_REPEAT"} Ns = im.shape # the size of each block within the grid Nblocks = [n/g for n,g in zip(Ns,Gs)] # the size of the overlapping patches with safety padding Npatchs = tuple([_next_power_of_2(pad_factor*nb) for nb in Nblocks]) prog = OCLProgram(abspath("kernels/conv_spatial3.cl"), build_options=["-D","ADDRESSMODE=%s"%mode_str[mode]]) if plan is None: plan = fft_plan(Npatchs) Xs = [nb*np.arange(g) for nb, g in zip(Nblocks,Gs)] patches_g = OCLArray.empty(Gs+Npatchs,np.complex64) #prepare psfs if grid_dim: h_g = OCLArray.zeros(Gs+Npatchs,np.complex64) tmp_g = OCLArray.from_array(hs.astype(np.float32, copy = False)) for (k,_z0), (j,_y0),(i,_x0) in product(*[enumerate(X) for X in Xs]): prog.run_kernel("fill_psf_grid3", Nblocks[::-1],None, tmp_g.data, np.int32(im.shape[2]), np.int32(im.shape[1]), np.int32(i*Nblocks[2]), np.int32(j*Nblocks[1]), np.int32(k*Nblocks[0]), h_g.data, np.int32(Npatchs[2]), np.int32(Npatchs[1]), np.int32(Npatchs[0]), np.int32(-Nblocks[2]/2+Npatchs[2]/2), np.int32(-Nblocks[1]/2+Npatchs[1]/2), np.int32(-Nblocks[0]/2+Npatchs[0]/2), np.int32(i*np.prod(Npatchs)+ j*Gs[2]*np.prod(Npatchs)+ k*Gs[2]*Gs[1]*np.prod(Npatchs))) else: hs = np.fft.fftshift(pad_to_shape(hs,Gs+Npatchs),axes=(3,4,5)) h_g = OCLArray.from_array(hs.astype(np.complex64)) im_g = OCLImage.from_array(im.astype(np.float32,copy=False)) # this loops over all i,j,k for (k,_z0), (j,_y0),(i,_x0) in product(*[enumerate(X) for X in Xs]): prog.run_kernel("fill_patch3",Npatchs[::-1],None, im_g, np.int32(_x0+Nblocks[2]/2-Npatchs[2]/2), np.int32(_y0+Nblocks[1]/2-Npatchs[1]/2), np.int32(_z0+Nblocks[0]/2-Npatchs[0]/2), patches_g.data, np.int32(i*np.prod(Npatchs)+ j*Gs[2]*np.prod(Npatchs)+ k*Gs[2]*Gs[1]*np.prod(Npatchs))) # convolution fft(patches_g,inplace=True, batch = np.prod(Gs), plan = plan) fft(h_g,inplace=True, batch = np.prod(Gs), plan = plan) prog.run_kernel("mult_inplace",(np.prod(Npatchs)*np.prod(Gs),),None, patches_g.data, h_g.data) fft(patches_g, inplace=True, inverse = True, batch = np.prod(Gs), plan = plan) #return patches_g.get() #accumulate res_g = OCLArray.zeros(im.shape,np.float32) for k, j, i in product(*[range(g+1) for g in Gs]): prog.run_kernel("interpolate3",Nblocks[::-1],None, patches_g.data, res_g.data, np.int32(i),np.int32(j),np.int32(k), np.int32(Gs[2]),np.int32(Gs[1]),np.int32(Gs[0]), np.int32(Npatchs[2]),np.int32(Npatchs[1]),np.int32(Npatchs[0])) res = res_g.get() if return_plan: return res, plan else: return res
def __init__(self, *args, **kwargs): kwargs["enforce_subsampled"] = True super(Bpm3d_img, self).__init__(*args, **kwargs) self._is_subsampled = True self.result_im = OCLImage.empty(self.shape[::-1], dtype=np.float32)
def set_shape(self, dataShape): if self.isGPU: self.dataImg = OCLImage.empty(dataShape[::-1], dtype=self.dtype) else: raise NotImplementedError("TODO")
def _convolve_spatial2(im, hs, mode = "constant", grid_dim = None, pad_factor = 2, plan = None, return_plan = False): """ spatial varying convolution of an 2d image with a 2d grid of psfs shape(im_ = (Ny,Nx) shape(hs) = (Gy,Gx, Hy,Hx) the input image im is subdivided into (Gy,Gx) blocks hs[j,i] is the psf at the center of each block (i,j) as of now each image dimension has to be divisible by the grid dim, i.e. Nx % Gx == 0 Ny % Gy == 0 mode can be: "constant" - assumed values to be zero "wrap" - periodic boundary condition """ if grid_dim: Gs = tuple(grid_dim) else: Gs = hs.shape[:2] mode_str = {"constant":"CLK_ADDRESS_CLAMP", "wrap":"CLK_ADDRESS_REPEAT"} Ny, Nx = im.shape Gy, Gx = Gs # the size of each block within the grid Nblock_y, Nblock_x = Ny/Gy, Nx/Gx # the size of the overlapping patches with safety padding Npatch_x, Npatch_y = _next_power_of_2(pad_factor*Nblock_x), _next_power_of_2(pad_factor*Nblock_y) prog = OCLProgram(abspath("kernels/conv_spatial2.cl"), build_options=["-D","ADDRESSMODE=%s"%mode_str[mode]]) if plan is None: plan = fft_plan((Npatch_y,Npatch_x)) x0s = Nblock_x*np.arange(Gx) y0s = Nblock_y*np.arange(Gy) patches_g = OCLArray.empty((Gy,Gx,Npatch_y,Npatch_x),np.complex64) #prepare psfs if grid_dim: h_g = OCLArray.zeros((Gy,Gx,Npatch_y,Npatch_x),np.complex64) tmp_g = OCLArray.from_array(hs.astype(np.float32, copy = False)) for i,_x0 in enumerate(x0s): for j,_y0 in enumerate(y0s): prog.run_kernel("fill_psf_grid2", (Nblock_x,Nblock_y),None, tmp_g.data, np.int32(Nx), np.int32(i*Nblock_x), np.int32(j*Nblock_y), h_g.data, np.int32(Npatch_x), np.int32(Npatch_y), np.int32(-Nblock_x/2+Npatch_x/2), np.int32(-Nblock_y/2+Npatch_y/2), np.int32(i*Npatch_x*Npatch_y+j*Gx*Npatch_x*Npatch_y) ) else: hs = np.fft.fftshift(pad_to_shape(hs,(Gy,Gx,Npatch_y,Npatch_x)),axes=(2,3)) h_g = OCLArray.from_array(hs.astype(np.complex64)) #prepare image im_g = OCLImage.from_array(im.astype(np.float32,copy=False)) for i,_x0 in enumerate(x0s): for j,_y0 in enumerate(y0s): prog.run_kernel("fill_patch2",(Npatch_x,Npatch_y),None, im_g, np.int32(_x0+Nblock_x/2-Npatch_x/2), np.int32(_y0+Nblock_y/2-Npatch_y/2), patches_g.data, np.int32(i*Npatch_x*Npatch_y+j*Gx*Npatch_x*Npatch_y)) #return np.abs(patches_g.get()) # convolution fft(patches_g,inplace=True, batch = Gx*Gy, plan = plan) fft(h_g,inplace=True, batch = Gx*Gy, plan = plan) prog.run_kernel("mult_inplace",(Npatch_x*Npatch_y*Gx*Gy,),None, patches_g.data, h_g.data) fft(patches_g,inplace=True, inverse = True, batch = Gx*Gy, plan = plan) print Nblock_x, Npatch_x #return np.abs(patches_g.get()) #accumulate res_g = OCLArray.empty(im.shape,np.float32) for j in xrange(Gy+1): for i in xrange(Gx+1): prog.run_kernel("interpolate2",(Nblock_x,Nblock_y),None, patches_g.data,res_g.data, np.int32(i),np.int32(j), np.int32(Gx),np.int32(Gy), np.int32(Npatch_x),np.int32(Npatch_y)) res = res_g.get() if return_plan: return res, plan else: return res
def affine(data, mat=np.identity(4), mode="constant", interpolation="linear"): """ affine transform data with matrix mat Parameters ---------- data, ndarray 3d array to be transformed mat, ndarray 4x4 affine matrix mode: string boundary mode, one of the following: 'constant' pads with zeros 'edge' pads with edge values 'wrap' pads with the repeated version of the input interpolation, string interpolation mode, one of the following 'linear' 'nearest' Returns ------- res: ndarray transformed array (same shape as input) """ if not (isinstance(data, np.ndarray) and data.ndim == 3): raise ValueError("input data has to be a 3d array!") interpolation_defines = { "linear": ["-D", "SAMPLER_FILTER=CLK_FILTER_LINEAR"], "nearest": ["-D", "SAMPLER_FILTER=CLK_FILTER_NEAREST"] } mode_defines = { "constant": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_CLAMP"], "wrap": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_REPEAT"], "edge": ["-D", "SAMPLER_ADDRESS=CLK_ADDRESS_CLAMP_TO_EDGE"] } if not interpolation in interpolation_defines: raise KeyError("interpolation = '%s' not defined ,valid: %s" % (interpolation, list(interpolation_defines.keys()))) if not mode in mode_defines: raise KeyError("mode = '%s' not defined ,valid: %s" % (mode, list(mode_defines.keys()))) d_im = OCLImage.from_array(data.astype(np.float32, copy=False)) res_g = OCLArray.empty(data.shape, np.float32) mat_g = OCLArray.from_array( np.linalg.inv(mat).astype(np.float32, copy=False)) prog = OCLProgram(abspath("kernels/transformations.cl"), build_options=interpolation_defines[interpolation] + mode_defines[mode]) prog.run_kernel("affine", data.shape[::-1], None, d_im, res_g.data, mat_g.data) return res_g.get()
def image_from_array(data): im = OCLImage.from_array(data) assert np.allclose(data, im.get())
def _convolve_spatial2(im, hs, mode="constant", grid_dim=None, pad_factor=2, plan=None, return_plan=False): """ spatial varying convolution of an 2d image with a 2d grid of psfs shape(im_ = (Ny,Nx) shape(hs) = (Gy,Gx, Hy,Hx) the input image im is subdivided into (Gy,Gx) blocks hs[j,i] is the psf at the center of each block (i,j) as of now each image dimension has to be divisible by the grid dim, i.e. Nx % Gx == 0 Ny % Gy == 0 mode can be: "constant" - assumed values to be zero "wrap" - periodic boundary condition """ if grid_dim: Gs = tuple(grid_dim) else: Gs = hs.shape[:2] mode_str = {"constant": "CLK_ADDRESS_CLAMP", "wrap": "CLK_ADDRESS_REPEAT"} Ny, Nx = im.shape Gy, Gx = Gs # the size of each block within the grid Nblock_y, Nblock_x = Ny // Gy, Nx // Gx # the size of the overlapping patches with safety padding Npatch_x, Npatch_y = _next_power_of_2( pad_factor * Nblock_x), _next_power_of_2(pad_factor * Nblock_y) prog = OCLProgram(abspath("kernels/conv_spatial2.cl"), build_options=["-D", "ADDRESSMODE=%s" % mode_str[mode]]) if plan is None: plan = fft_plan((Gy, Gx, Npatch_y, Npatch_x), axes=(-2, -1)) x0s = Nblock_x * np.arange(Gx) y0s = Nblock_y * np.arange(Gy) patches_g = OCLArray.empty((Gy, Gx, Npatch_y, Npatch_x), np.complex64) #prepare psfs if grid_dim: h_g = OCLArray.zeros((Gy, Gx, Npatch_y, Npatch_x), np.complex64) tmp_g = OCLArray.from_array(hs.astype(np.float32, copy=False)) for i, _x0 in enumerate(x0s): for j, _y0 in enumerate(y0s): prog.run_kernel( "fill_psf_grid2", (Nblock_x, Nblock_y), None, tmp_g.data, np.int32(Nx), np.int32(i * Nblock_x), np.int32(j * Nblock_y), h_g.data, np.int32(Npatch_x), np.int32(Npatch_y), np.int32(-Nblock_x // 2 + Npatch_x // 2), np.int32(-Nblock_y // 2 + Npatch_y // 2), np.int32(i * Npatch_x * Npatch_y + j * Gx * Npatch_x * Npatch_y)) else: hs = np.fft.fftshift(pad_to_shape(hs, (Gy, Gx, Npatch_y, Npatch_x)), axes=(2, 3)) h_g = OCLArray.from_array(hs.astype(np.complex64)) #prepare image im_g = OCLImage.from_array(im.astype(np.float32, copy=False)) for i, _x0 in enumerate(x0s): for j, _y0 in enumerate(y0s): prog.run_kernel( "fill_patch2", (Npatch_x, Npatch_y), None, im_g, np.int32(_x0 + Nblock_x // 2 - Npatch_x // 2), np.int32(_y0 + Nblock_y // 2 - Npatch_y // 2), patches_g.data, np.int32(i * Npatch_x * Npatch_y + j * Gx * Npatch_x * Npatch_y)) #return np.abs(patches_g.get()) # convolution fft(patches_g, inplace=True, plan=plan) fft(h_g, inplace=True, plan=plan) prog.run_kernel("mult_inplace", (Npatch_x * Npatch_y * Gx * Gy, ), None, patches_g.data, h_g.data) fft(patches_g, inplace=True, inverse=True, plan=plan) logger.debug("Nblock_x: {}, Npatch_x: {}".format(Nblock_x, Npatch_x)) #return np.abs(patches_g.get()) #accumulate res_g = OCLArray.empty(im.shape, np.float32) for j in range(Gy + 1): for i in range(Gx + 1): prog.run_kernel("interpolate2", (Nblock_x, Nblock_y), None, patches_g.data, res_g.data, np.int32(i), np.int32(j), np.int32(Gx), np.int32(Gy), np.int32(Npatch_x), np.int32(Npatch_y)) res = res_g.get() if return_plan: return res, plan else: return res
def image_create_write(data): im = OCLImage.empty(data.shape, data.dtype) im.write_array(data) assert np.allclose(data, im.get())