heatmap.py
3.2 kB · python · 106 lines
1import os2import sys34# MRLYPROD56HERE = os.path.dirname(os.path.abspath(__file__))7MRLYPROD = os.path.normpath(os.path.join(HERE, ".."))89if not os.path.isdir(os.path.join(MRLYPROD, "mrlypy", "six")):10 sys.exit(f"missing mrlypy: expected it at {MRLYPROD}")1112sys.path.insert(0, MRLYPROD)1314import mrlypy.two as m215import numpy as np16from config import DATA_DIR, IMAGE_SIZE17from helpers import hex_key18from PIL import Image19from typing import Iterable2021INVERT = False22LEVEL = 123LIMIT = 5024MODE = "FIT"25PAINT = "GRAYSCALE"26ODDS = [i for i in range(1, LIMIT, 2)]27NUMBERS = ODDS28FUNCS = [29 m2.carpet_2d,30 m2.net_2d,31 m2.tree_2d,32 m2.void_2d,33]3435def pad_grid(grid: np.ndarray, max_height: int, max_width: int) -> np.ndarray:36 pad_height = max_height - grid.shape[0]37 pad_width = max_width - grid.shape[1]38 pad_top = pad_height // 239 pad_bottom = pad_height - pad_top40 pad_left = pad_width // 241 pad_right = pad_width - pad_left42 return np.pad(grid, ((pad_top, pad_bottom), (pad_left, pad_right)), 'constant')4344def resize_grid(grid: np.ndarray) -> np.ndarray:45 if grid.shape == IMAGE_SIZE:46 return grid47 old_height, old_width = grid.shape48 new_y, new_x = np.indices(IMAGE_SIZE)49 old_x = (new_x * old_width / IMAGE_SIZE[1]).astype(int)50 old_y = (new_y * old_height / IMAGE_SIZE[0]).astype(int)51 return grid[old_y, old_x]5253def create_color_map(max_value: int) -> np.ndarray:54 if max_value == 0:55 return np.array([[0, 0, 0]], dtype=np.uint8)56 grayscale_map = np.linspace(0, 255, max_value + 1, dtype=np.uint8)57 color_maps = {58 "GRAYSCALE": np.stack([grayscale_map] * 3, axis=1),59 "RANDOM": np.random.randint(0, 256, size=(max_value + 1, 3), dtype=np.uint8),60 }61 color_map = color_maps[PAINT]62 color_map[0] = [0, 0, 0]63 return color_map6465def draw_step(grid: np.ndarray, name: str):66 fp = f"{DATA_DIR}/{name}.png"67 max_val = np.max(grid)68 color_map = create_color_map(max_val)69 image_array = color_map[grid]70 image = Image.fromarray(image_array, 'RGB')71 image = image.resize(IMAGE_SIZE, Image.Resampling.NEAREST)72 image.save(fp, "PNG")73 print(f"Saved: {fp}")7475def generate_steps(title: str, grids: Iterable[np.ndarray], mode: str):76 heatmap = None77 if mode == "FIT":78 heatmap = np.zeros(IMAGE_SIZE, dtype=np.int16)79 for grid in grids:80 heatmap += resize_grid(grid)81 elif mode == "GROW":82 for grid in grids:83 if heatmap is None:84 heatmap = grid.astype(np.int16)85 else:86 h_h, h_w = heatmap.shape87 g_h, g_w = grid.shape88 new_h = max(h_h, g_h)89 new_w = max(h_w, g_w)90 if new_h > h_h or new_w > h_w:91 heatmap = pad_grid(heatmap, new_h, new_w)92 padded_grid = pad_grid(grid, new_h, new_w)93 heatmap += padded_grid94 if heatmap is not None:95 draw_step(heatmap, f"{title}_{hex_key(4)}")9697def main():98 for func in FUNCS:99 if INVERT:100 grids = (func(number, LEVEL).invert().to_array() for number in NUMBERS)101 else:102 grids = (func(number, LEVEL).to_array() for number in NUMBERS)103 generate_steps(func.__name__, grids, MODE)104105if __name__ == "__main__":106 main()