Spaces:
Runtime error
Runtime error
| import cv2 | |
| from scipy.ndimage import zoom as scizoom | |
| from numba import njit, prange | |
| import numpy as np | |
| import math | |
| def gen_lensmask(h, w, gamma): | |
| """ | |
| Generate lens mask with shape (h, w). | |
| For point (i, j), | |
| distance = [(i - h // 2)^2 + (j - w // 2)^2] ^ (1/2) / [h // 2)^2 + (w // 2)^2] ^ (1/2) | |
| mask = scale * (1 - distance) ^ gamma | |
| @param h: height | |
| @param w: width | |
| @param gamma: exponential factor | |
| @return: Mask, H x W | |
| """ | |
| dist1 = np.array([list(range(w))] * h) - w // 2 | |
| dist2 = np.array([list(range(h))] * w) - h // 2 | |
| dist2 = np.transpose(dist2, (1, 0)) | |
| dist = np.sqrt((dist1 ** 2 + dist2 ** 2)) / np.sqrt((w ** 2 + h ** 2) / 4) | |
| mask = (1 - dist) ** gamma | |
| return mask | |
| def gen_disk(radius, dtype=np.float32): | |
| if radius <= 8: | |
| L = np.arange(-8, 8 + 1) | |
| else: | |
| L = np.arange(-radius, radius + 1) | |
| X, Y = np.meshgrid(L, L) | |
| disk = np.array((X ** 2 + Y ** 2) <= radius ** 2, dtype=dtype) | |
| disk /= np.sum(disk) | |
| return disk | |
| # modification of https://github.com/FLHerne/mapgen/blob/master/diamondsquare.py | |
| def plasma_fractal(mapsize=256, wibbledecay=3): | |
| """ | |
| Generate a heightmap using diamond-square algorithm. | |
| Return square 2d array, side length 'mapsize', of floats in range 0-255. | |
| 'mapsize' must be a power of two. | |
| """ | |
| assert (mapsize & (mapsize - 1) == 0) | |
| maparray = np.empty((mapsize, mapsize), dtype=np.float_) | |
| maparray[0, 0] = 0 | |
| stepsize = mapsize | |
| wibble = 100 | |
| def wibbledmean(array): | |
| return array / 4 + wibble * np.random.uniform(-wibble, wibble, | |
| array.shape) | |
| def fillsquares(): | |
| """For each square of points stepsize apart, | |
| calculate middle value as mean of points + wibble""" | |
| cornerref = maparray[0:mapsize:stepsize, 0:mapsize:stepsize] | |
| squareaccum = cornerref + np.roll(cornerref, shift=-1, axis=0) | |
| squareaccum += np.roll(squareaccum, shift=-1, axis=1) | |
| maparray[stepsize // 2:mapsize:stepsize, | |
| stepsize // 2:mapsize:stepsize] = wibbledmean(squareaccum) | |
| def filldiamonds(): | |
| """For each diamond of points stepsize apart, | |
| calculate middle value as mean of points + wibble""" | |
| mapsize = maparray.shape[0] | |
| drgrid = maparray[stepsize // 2:mapsize:stepsize, | |
| stepsize // 2:mapsize:stepsize] | |
| ulgrid = maparray[0:mapsize:stepsize, 0:mapsize:stepsize] | |
| ldrsum = drgrid + np.roll(drgrid, 1, axis=0) | |
| lulsum = ulgrid + np.roll(ulgrid, -1, axis=1) | |
| ltsum = ldrsum + lulsum | |
| maparray[0:mapsize:stepsize, | |
| stepsize // 2:mapsize:stepsize] = wibbledmean(ltsum) | |
| tdrsum = drgrid + np.roll(drgrid, 1, axis=1) | |
| tulsum = ulgrid + np.roll(ulgrid, -1, axis=0) | |
| ttsum = tdrsum + tulsum | |
| maparray[stepsize // 2:mapsize:stepsize, | |
| 0:mapsize:stepsize] = wibbledmean(ttsum) | |
| while stepsize >= 2: | |
| fillsquares() | |
| filldiamonds() | |
| stepsize //= 2 | |
| wibble /= wibbledecay | |
| maparray -= maparray.min() | |
| return maparray / maparray.max() | |
| def clipped_zoom(img, zoom_factor): | |
| # clipping along the width dimension: | |
| ch0 = int(np.ceil(img.shape[0] / float(zoom_factor))) | |
| top0 = (img.shape[0] - ch0) // 2 | |
| # clipping along the height dimension: | |
| ch1 = int(np.ceil(img.shape[1] / float(zoom_factor))) | |
| top1 = (img.shape[1] - ch1) // 2 | |
| img = scizoom(img[top0:top0 + ch0, top1:top1 + ch1], | |
| (zoom_factor, zoom_factor, 1), order=1) | |
| return img | |
| def getOptimalKernelWidth1D(radius, sigma): | |
| return radius * 2 + 1 | |
| def gauss_function(x, mean, sigma): | |
| return (np.exp(- (x - mean)**2 / (2 * (sigma**2)))) / (np.sqrt(2 * np.pi) * sigma) | |
| def getMotionBlurKernel(width, sigma): | |
| k = gauss_function(np.arange(width), 0, sigma) | |
| Z = np.sum(k) | |
| return k/Z | |
| def shift(image, dx, dy): | |
| if(dx < 0): | |
| shifted = np.roll(image, shift=image.shape[1]+dx, axis=1) | |
| shifted[:,dx:] = shifted[:,dx-1:dx] | |
| elif(dx > 0): | |
| shifted = np.roll(image, shift=dx, axis=1) | |
| shifted[:,:dx] = shifted[:,dx:dx+1] | |
| else: | |
| shifted = image | |
| if(dy < 0): | |
| shifted = np.roll(shifted, shift=image.shape[0]+dy, axis=0) | |
| shifted[dy:,:] = shifted[dy-1:dy,:] | |
| elif(dy > 0): | |
| shifted = np.roll(shifted, shift=dy, axis=0) | |
| shifted[:dy,:] = shifted[dy:dy+1,:] | |
| return shifted | |
| def _motion_blur(x, radius, sigma, angle): | |
| width = getOptimalKernelWidth1D(radius, sigma) | |
| kernel = getMotionBlurKernel(width, sigma) | |
| point = (width * np.sin(np.deg2rad(angle)), width * np.cos(np.deg2rad(angle))) | |
| hypot = math.hypot(point[0], point[1]) | |
| blurred = np.zeros_like(x, dtype=np.float32) | |
| for i in range(width): | |
| dy = -math.ceil(((i*point[0]) / hypot) - 0.5) | |
| dx = -math.ceil(((i*point[1]) / hypot) - 0.5) | |
| if (np.abs(dy) >= x.shape[0] or np.abs(dx) >= x.shape[1]): | |
| # simulated motion exceeded image borders | |
| break | |
| shifted = shift(x, dx, dy) | |
| blurred = blurred + kernel[i] * shifted | |
| return blurred | |
| # Numba nopython compilation to shuffle_pixles | |
| def shuffle_pixels_njit(img, shift, iteration): | |
| height, width = img.shape[:2] | |
| # locally shuffle pixels | |
| for _ in range(iteration): | |
| for h in range(height - shift, shift, -1): | |
| for w in range(width - shift, shift, -1): | |
| dx, dy = np.random.randint(-shift, shift, size=(2,)) | |
| h_prime, w_prime = h + dy, w + dx | |
| # swap | |
| img[h, w], img[h_prime, w_prime] = img[h_prime, w_prime], img[h, w] | |
| return img | |