def find_min_seam_debug(grid1, grid2): w, h = grid1.dims acc_energy = Grid2D((w, h)) energy = Grid2D((w, h)) seam = [] # Calcaulte accumulative energy # First row # First cell acc_energy[0, 0] = ENERGY_MAX energy[0, 0] = ENERGY_MAX for i in range(1, w): acc_energy[i, 0] = energy2(grid1[i - 1, 0], grid2[i, 0]) energy[i, 0] = energy2(grid1[i - 1, 0], grid2[i, 0]) # Other rows for j in range(1, h): acc_energy[0, j] = ENERGY_MAX energy[0, j] = ENERGY_MAX for i in range(1, w - 1): if acc_energy[i + 1, j - 1] < acc_energy[i, j - 1] and acc_energy[ i + 1, j - 1] < acc_energy[i - 1, j - 1]: e = energy3(grid2[i, j], grid1[i - 1, j], grid1[i, j - 1]) else: e = energy3(grid2[i, j], grid1[i - 1, j], grid2[i, j - 1]) acc_energy[i, j] = min(acc_energy[i - 1:i + 2, j - 1]) + e energy[i, j] = e #Last cell e = energy3(grid2[i, j], grid1[i - 1, j], grid2[i, j - 1]) acc_energy[-1, j] = min(acc_energy[-2:, j - 1]) + e energy[-1, j] = e last_seam = argmin(acc_energy[:, -1]) seam.append(last_seam) for j in range(h - 2, -1, -1): if last_seam == 1: last_seam + argmin(acc_energy[last_seam:last_seam + 2, j]) elif last_seam == w - 2: last_seam = last_seam - 1 + argmin( acc_energy[last_seam - 1:last_seam + 1, j]) else: last_seam = last_seam - 1 + argmin( acc_energy[last_seam - 1:last_seam + 2, j]) seam.append(last_seam) seam.reverse() return seam, energy
def distribution_from_grid(grid, x_cells, y_cells): distribution = Grid2D((x_cells, y_cells), 0) grid_w, grid_h = grid.dims w = grid_w // x_cells h = grid_h // y_cells for index in grid.index_iter(): i, j = index distribution[i // w, j // h] += grid[index] distribution2 = Grid2D((x_cells + 1, y_cells + 1), 0) distribution2[1:, 1:] = distribution return distribution2
def demo_distribution_2d(): # grid = Grid2D((100, 100), 0) # for index in grid.index_iter(): # x, y = index # grid[index] = (x + 1)*(y + 1) grid = Grid2D((4, 4)) grid[..., ...] = [[1, 2, 4, 8], [2, 3, 5, 11], [4, 5, 7, 11], [8, 11, 11, 11]] print grid probs = distribution_from_grid(grid, 4, 4) print probs d = Distribution2D(probs, (0, 0), (500, 500)) samples = [] for k in range(10000): samples.append(d(random(), random())) samples_to_image(samples, (200, 200), 'rand_dist.png')
def perlin_noise_from_smoothnoise(width, height, layers, falloff, noise, normalize=True): perlin_noise = Grid2D((width, height), 0) r = 1 for k in range(layers): r *= falloff s_noise = noise.generate(layers - k - 1) for p in perlin_noise.index_iter(): perlin_noise[p] += s_noise[p] * r #Normalise if normalize: r = 1 w = 0 for k in range(layers): r *= falloff w += r for p in perlin_noise.index_iter(): perlin_noise[p] /= w return perlin_noise
def map_gradient(gradient, grid): color_grid = Grid2D(grid.dims) for index in grid.index_iter(): color_grid[index] = gradient.get_color(grid[index]) return color_grid
def make_uniform_noise(width, height): noise = Grid2D((width, height), 0) for p in noise.index_iter(): noise[p] = random() #randint(0, 1) #random() return noise
def calc_acc_energy2(grid1, grid2): w, h = grid1.dims acc_energy = Grid2D((w, h)) # First row # First cell acc_energy[0, 0] = ENERGY_MAX for i in range(1, w): acc_energy[i, 0] = energy2(grid1[i, 0], grid2[i, 0]) # Other rows for j in range(1, h): acc_energy[0, j] = ENERGY_MAX for i in range(1, w - 1): e = energy2(grid1[i, j], grid2[i, j]) acc_energy[i, j] = min(acc_energy[i - 1:i + 2, j - 1]) + e #Last cell e = energy2(grid1[i, j], grid2[i, j]) acc_energy[-1, j] = min(acc_energy[-2:, j - 1]) + e return acc_energy
def cubic_interpolation(self, k): t = 2**k noise = self.uniform_noise smooth_noise = Grid2D((self.width, self.height), 0) for i in range(self.width): x0, x1, x2, x3, x_alpha, x_alpha_2, x_alpha_3, x_alpha_i, x_alpha_i2, x_alpha_i3 = sample_points_cubic( i, t, self.width) for j in range(self.height): y0, y1, y2, y3, y_alpha, y_alpha_2, y_alpha_3, y_alpha_i, y_alpha_i2, y_alpha_i3 = sample_points_cubic( j, t, self.height) a0 = x_alpha_i3*noise[x0, y0] + x_alpha_i2*x_alpha*noise[x1, y0] + \ x_alpha_i*x_alpha_2*noise[x2, y0] + x_alpha_3*noise[x3, y0] a1 = x_alpha_i3*noise[x0, y1] + x_alpha_i2*x_alpha*noise[x1, y1] + \ x_alpha_i*x_alpha_2*noise[x2, y1] + x_alpha_3*noise[x3, y1] a2 = x_alpha_i3*noise[x0, y2] + x_alpha_i2*x_alpha*noise[x1, y2] + \ x_alpha_i*x_alpha_2*noise[x2, y2] + x_alpha_3*noise[x3, y2] a3 = x_alpha_i3*noise[x0, y3] + x_alpha_i2*x_alpha*noise[x1, y3] + \ x_alpha_i*x_alpha_2*noise[x2, y3] + x_alpha_3*noise[x3, y3] smooth_noise[i, j] = y_alpha_i3*a0 + y_alpha_i2*y_alpha*a1 + \ y_alpha_i*y_alpha_2*a2 + y_alpha_3*a3 return smooth_noise
def make_half_checker_grids(col_obj): checker_grid1 = Grid2D((50, 30), col_obj.white) checker_grid2 = Grid2D((50, 30), col_obj.white) for index in checker_grid1.index_iter(): x, y = index checker_grid = checker_grid1 if x < 25: checker_grid = checker_grid2 if x != 25: if (x + y) % 2 == 0: checker_grid[index] = col_obj.black else: checker_grid[index] = col_obj.grey return checker_grid1, checker_grid2
def make_checker_grid(col_obj): checker_grid = Grid2D((50, 30), col_obj.white) for index in checker_grid.index_iter(): x, y = index if (x + y) % 2 == 0: checker_grid[index] = col_obj.black return checker_grid
def make_checker_board_noise(width, height, period=1): noise = Grid2D((width, height), 0) for p in noise.index_iter(): i, j = p noise[p] = (i // period % 2 + j // period % 2) % 2 return noise
def demo_draw(): grid = Grid2D((600, 600), 0) draw_perlin_ellipse_tree(grid, (300, 300), 100, 70, pi / 4, 70, 3, 4, 0.8) grid = greyscale_grid_to_rgb_grid(grid, [1, 1, 1, 1]) grid_to_rgb_image(grid, 'draw/perlin_ellipse_tree.png')
def testZero(self): washblue_grid = Grid2D((50, 30), self.washblue) acc_energy = calc_acc_energy(washblue_grid, washblue_grid) for index in acc_energy.index_iter(): x, y = index if (x > 0): self.assertAlmostEqual(acc_energy[index], 0) else: self.assertAlmostEqual(acc_energy[index], ENERGY_MAX)
def int_perlin_noise(width, height, layers, n, tiles=1): noise_list = perlin_noise(width, height, layers) int_noise_list = [] for noise in noise_list: int_noise = Grid2D((width, height)) for p in noise.index_iter(): int_noise[p] = int(floor(noise[p] / (1 / n))) int_noise_list.append(int_noise) return int_noise_list
def quilt_debug(grid1, grid2, w): seam, energy = find_min_seam_debug(grid1[-w:, :], grid2[:w, :]) res = Grid2D((grid1.width + grid2.width - w, grid1.height)) for i in range(res.width): for j in range(res.height): if i < grid1.width - w + seam[j]: res[i, j] = grid1[i, j] elif i == grid1.width - w + seam[j]: res[i, j] = (1, 0, 0, 1) else: res[i, j] = grid2[i - grid1.width + w, j] return res, energy
def linear_interpolation(self, k): t = 2**k noise = self.uniform_noise smooth_noise = Grid2D((self.width, self.height), 0) for i in range(self.width): x0, x1, x_alpha = sample_points(i, t, self.width) for j in range(self.height): y0, y1, y_alpha = sample_points(j, t, self.height) a0 = (1 - x_alpha) * noise[x0, y0] + (x_alpha) * noise[x1, y0] a1 = (1 - x_alpha) * noise[x0, y1] + (x_alpha) * noise[x1, y1] smooth_noise[i, j] = (1 - y_alpha) * a0 + (y_alpha) * a1 return smooth_noise
def quilt(grid1, grid2, w): seam = find_min_seam(grid1[grid1.width - w:, :], grid2[:w, :]) assert is_non_negative(seam) res = Grid2D((grid1.width + grid2.width - w, grid1.height)) for i in range(res.width): for j in range(res.height): if i < grid1.width - w + seam[j]: res[i, j] = grid1[i, j] else: res[i, j] = grid2[i - grid1.width + w, j] # if i == grid1.width - w + seam[j]: # r, g, b, a = res[i, j] # res[i, j] = (r, g, b, 0.5) return res
def in_neighbourhood(p): gp = gx, gy = grid_coordinates(p) if grid[gp]: return True for cell in grid.square_iter(gp, 2): if cell and sqr_dist(cell, p) <= r_sqr: return True return False #Create the grid cell_size = r / sqrt(2) inv_cell_size = 1 / cell_size r_sqr = r * r grid = Grid2D( (int(ceil(width / cell_size)), int(ceil(height / cell_size)))) process_list = RandomQueue() sample_points = [] #generate the first point put_point((rand(width), rand(height))) #generate other points from points in queue. while not process_list.empty(): p = process_list.pop() for i in xrange(k): q = generate_random_around(p, r) if in_rectangle(q) and not in_neighbourhood(q): put_point(q)
def sample_poisson_uniform(width, height, r, k): #Convert rectangle (the one to be sampled) coordinates to # coordinates in the grid. def grid_coordinates(p): x, y = p return (int(x*inv_cell_size), int(y*inv_cell_size)) # Puts a sample point in all the algorithm's relevant containers. def put_point(p): process_list.push(p) sample_points.append(p) grid[grid_coordinates(p)] = p # Generates a point randomly selected around # the given point, between r and 2*r units away. def generate_random_around(p, r): x, y = p rr = uniform(r, 2*r) rt = uniform(0, 2*pi) return rr*sin(rt) + x, rr*cos(rt) + y # Is the given point in the rectangle to be sampled? def in_rectangle(p): x, y = p return 0 <= x < width and 0 <= y < height def in_neighbourhood(p): gp = gx, gy = grid_coordinates(p) if grid[gp]: return True for cell in grid.square_iter(gp, 2): if cell and sqr_dist(cell, p) <= r_sqr: return True return False #Create the grid cell_size = r/sqrt(2) inv_cell_size = 1 / cell_size r_sqr = r*r grid = Grid2D((int(ceil(width/cell_size)), int(ceil(height/cell_size)))) process_list = RandomQueue() sample_points = [] #generate the first point put_point((rand(width), rand(height))) #generate other points from points in queue. while not process_list.empty(): p = process_list.pop() for i in range(k): q = generate_random_around(p, r) if in_rectangle(q) and not in_neighbourhood(q): put_point(q) return sample_points