| import json |
| import time |
|
|
| import numpy as np |
|
|
| from scipy import ndimage |
| from scipy.stats import mode |
| from src.utils import matrix2answer |
|
|
|
|
| def find_grid(image, frame=False, possible_colors=None): |
| """Looks for the grid in image and returns color and size""" |
| grid_color = -1 |
| size = [1, 1] |
|
|
| if possible_colors is None: |
| possible_colors = list(range(10)) |
|
|
| for color in possible_colors: |
| for i in range(size[0] + 1, image.shape[0] // 2 + 1): |
| if (image.shape[0] + 1) % i == 0: |
| step = (image.shape[0] + 1) // i |
| if (image[(step - 1) :: step] == color).all(): |
| size[0] = i |
| grid_color = color |
| for i in range(size[1] + 1, image.shape[1] // 2 + 1): |
| if (image.shape[1] + 1) % i == 0: |
| step = (image.shape[1] + 1) // i |
| if (image[:, (step - 1) :: step] == color).all(): |
| size[1] = i |
| grid_color = color |
|
|
| if grid_color == -1 and not frame: |
| color_candidate = image[0, 0] |
| if ( |
| (image[0] == color_candidate).all() |
| and (image[-1] == color_candidate).all() |
| and (image[:, -1] == color_candidate).all() |
| and (image[:, 0] == color_candidate).all() |
| ): |
| grid_color, size, _ = find_grid( |
| image[1 : image.shape[0] - 1, 1 : image.shape[1] - 1], frame=True, possible_colors=[color_candidate] |
| ) |
| return grid_color, size, frame |
| else: |
| return grid_color, size, frame |
|
|
| return grid_color, size, frame |
|
|
|
|
| def find_color_boundaries(array, color): |
| """Looks for the boundaries of any color and returns them""" |
| if not (array == color).any(): |
| return None |
| ind_0 = np.arange(array.shape[0]) |
| ind_1 = np.arange(array.shape[1]) |
|
|
| temp_0 = ind_0[(array == color).max(axis=1)] |
| min_0, max_0 = temp_0.min(), temp_0.max() |
|
|
| temp_1 = ind_1[(array == color).max(axis=0)] |
| min_1, max_1 = temp_1.min(), temp_1.max() |
|
|
| return min_0, max_0, min_1, max_1 |
|
|
|
|
| def get_color_max(image, color): |
| """Returns the part of the image inside the color boundaries""" |
| boundaries = find_color_boundaries(image, color) |
| if boundaries: |
| return (0, image[boundaries[0] : boundaries[1] + 1, boundaries[2] : boundaries[3] + 1]) |
| else: |
| return 1, None |
|
|
|
|
| def get_pixel(image, i, j): |
| """Returns the pixel by coordinates""" |
| if i >= image.shape[0] or j >= image.shape[1]: |
| return 1, None |
| return 0, image[i : i + 1, j : j + 1] |
|
|
|
|
| def get_pixel_fixed(image, i): |
| return 0, np.array([[i]]) |
|
|
|
|
| def get_grid(image, grid_size, cell, frame=False): |
| """ returns the particular cell form the image with grid""" |
| if frame: |
| return get_grid(image[1 : image.shape[0] - 1, 1 : image.shape[1] - 1], grid_size, cell, frame=False) |
| if cell[0] >= grid_size[0] or cell[1] >= grid_size[1]: |
| return 1, None |
| steps = ((image.shape[0] + 1) // grid_size[0], (image.shape[1] + 1) // grid_size[1]) |
| block = image[steps[0] * cell[0] : steps[0] * (cell[0] + 1) - 1, steps[1] * cell[1] : steps[1] * (cell[1] + 1) - 1] |
| return 0, block |
|
|
|
|
| def get_half(image, side): |
| """ returns the half of the image""" |
| if side not in ["l", "r", "t", "b", "long1", "long2"]: |
| return 1, None |
| if side == "l": |
| return 0, image[:, : (image.shape[1]) // 2] |
| elif side == "r": |
| return 0, image[:, -((image.shape[1]) // 2) :] |
| elif side == "b": |
| return 0, image[-((image.shape[0]) // 2) :, :] |
| elif side == "t": |
| return 0, image[: (image.shape[0]) // 2, :] |
| elif side == "long1": |
| if image.shape[0] >= image.shape[1]: |
| return get_half(image, "t") |
| else: |
| return get_half(image, "l") |
| elif side == "long2": |
| if image.shape[0] >= image.shape[1]: |
| return get_half(image, "b") |
| else: |
| return get_half(image, "r") |
|
|
|
|
| def get_corner(image, side): |
| """Return one quadrant of the image; tl/tr/bl/br follow row-0-at-top conventions.""" |
| if side not in ["tl", "tr", "bl", "br"]: |
| return 1, None |
| size = (image.shape[0]) // 2, (image.shape[1]) // 2 |
| if side == "tl": |
| return 0, image[: size[0], : size[1]] |
| if side == "tr": |
| return 0, image[: size[0], -size[1] :] |
| if side == "bl": |
| return 0, image[-size[0] :, : size[1]] |
| if side == "br": |
| return 0, image[-size[0] :, -size[1] :] |
|
|
|
|
| def get_k_part(image, num, k): |
| if image.shape[0] > image.shape[1]: |
| max_axis = 0 |
| max_shape = image.shape[0] |
| else: |
| max_axis = 1 |
| max_shape = image.shape[1] |
|
|
| if max_shape % num != 0: |
| return 1, None |
| size = max_shape // num |
|
|
| if max_axis == 0: |
| return 0, image[k * size : (k + 1) * size] |
| else: |
| return 0, image[:, k * size : (k + 1) * size] |
|
|
|
|
| def get_rotation(image, k): |
| return 0, np.rot90(image, k) |
|
|
|
|
| def get_transpose(image): |
| return 0, np.transpose(image) |
|
|
|
|
| def get_roll(image, shift, axis): |
| return 0, np.roll(image, shift=shift, axis=axis) |
|
|
|
|
| def get_cut_edge(image, l, r, t, b): |
| """deletes pixels from some sided of an image""" |
| return 0, image[t : image.shape[0] - b, l : image.shape[1] - r] |
|
|
|
|
| def get_resize(image, scale): |
| """ resizes image according to scale""" |
| if isinstance(scale, int): |
| if image.shape[0] % scale != 0 or image.shape[1] % scale != 0: |
| return 1, None |
| if image.shape[0] < scale or image.shape[1] < scale: |
| return 2, None |
|
|
| arrays = [] |
| size = image.shape[0] // scale, image.shape[1] // scale |
| for i in range(scale): |
| for j in range(scale): |
| arrays.append(image[i::scale, j::scale]) |
|
|
| |
| |
| result = mode(np.stack(arrays), axis=0, keepdims=True).mode[0] |
| else: |
| size = int(image.shape[0] / scale), int(image.shape[1] / scale) |
| result = [] |
| for i in range(size[0]): |
| result.append([]) |
| for j in range(size[1]): |
| result[-1].append(image[int(i * scale), int(j * scale)]) |
|
|
| result = np.uint8(result) |
|
|
| return 0, result |
|
|
|
|
| def get_resize_to(image, size_x, size_y): |
| """ resizes image according to scale""" |
| scale_x = image.shape[0] // size_x |
| scale_y = image.shape[1] // size_y |
| if scale_x == 0 or scale_y == 0: |
| return 3, None |
| if image.shape[0] % scale_x != 0 or image.shape[1] % scale_y != 0: |
| return 1, None |
| if image.shape[0] < scale_x or image.shape[1] < scale_y: |
| return 2, None |
|
|
| arrays = [] |
| for i in range(scale_x): |
| for j in range(scale_y): |
| arrays.append(image[i::scale_x, j::scale_y]) |
|
|
| result = mode(np.stack(arrays), axis=0, keepdims=True).mode[0] |
|
|
| return 0, result |
|
|
|
|
| def get_reflect(image, side): |
| """ returns images generated by reflections of the input""" |
| if side not in ["r", "l", "t", "b", "rt", "rb", "lt", "lb"]: |
| return 1, None |
| try: |
| if side == "r": |
| result = np.zeros((image.shape[0], image.shape[1] * 2 - 1)) |
| result[:, : image.shape[1]] = image |
| result[:, -image.shape[1] :] = image[:, ::-1] |
| elif side == "l": |
| result = np.zeros((image.shape[0], image.shape[1] * 2 - 1)) |
| result[:, : image.shape[1]] = image[:, ::-1] |
| result[:, -image.shape[1] :] = image |
| elif side == "b": |
| result = np.zeros((image.shape[0] * 2 - 1, image.shape[1])) |
| result[: image.shape[0], :] = image |
| result[-image.shape[0] :, :] = image[::-1] |
| elif side == "t": |
| result = np.zeros((image.shape[0] * 2 - 1, image.shape[1])) |
| result[: image.shape[0], :] = image[::-1] |
| result[-image.shape[0] :, :] = image |
|
|
| elif side == "rb": |
| result = np.zeros((image.shape[0] * 2 - 1, image.shape[1] * 2 - 1)) |
| result[: image.shape[0], : image.shape[1]] = image |
| result[: image.shape[0], -image.shape[1] :] = image[:, ::-1] |
| result[-image.shape[0] :, : image.shape[1]] = image[::-1, :] |
| result[-image.shape[0] :, -image.shape[1] :] = image[::-1, ::-1] |
|
|
| elif side == "rt": |
| result = np.zeros((image.shape[0] * 2 - 1, image.shape[1] * 2 - 1)) |
| result[: image.shape[0], : image.shape[1]] = image[::-1, :] |
| result[: image.shape[0], -image.shape[1] :] = image[::-1, ::-1] |
| result[-image.shape[0] :, : image.shape[1]] = image |
| result[-image.shape[0] :, -image.shape[1] :] = image[:, ::-1] |
|
|
| elif side == "lt": |
| result = np.zeros((image.shape[0] * 2 - 1, image.shape[1] * 2 - 1)) |
| result[: image.shape[0], : image.shape[1]] = image[::-1, ::-1] |
| result[: image.shape[0], -image.shape[1] :] = image[::-1, :] |
| result[-image.shape[0] :, : image.shape[1]] = image[:, ::-1] |
| result[-image.shape[0] :, -image.shape[1] :] = image |
|
|
| elif side == "lb": |
| result = np.zeros((image.shape[0] * 2 - 1, image.shape[1] * 2 - 1)) |
| result[: image.shape[0], : image.shape[1]] = image[:, ::-1] |
| result[: image.shape[0], -image.shape[1] :] = image |
| result[-image.shape[0] :, : image.shape[1]] = image[::-1, ::-1] |
| result[-image.shape[0] :, -image.shape[1] :] = image[::-1, :] |
| except: |
| return 2, None |
|
|
| return 0, result |
|
|
|
|
| def get_color_swap(image, color_1, color_2): |
| """swapping two colors""" |
| if not (image == color_1).any() and not (image == color_2).any(): |
| return 1, None |
| result = image.copy() |
| result[image == color_1] = color_2 |
| result[image == color_2] = color_1 |
| return 0, result |
|
|
|
|
| def get_cut(image, x1, y1, x2, y2): |
| if x1 >= x2 or y1 >= y2: |
| return 1, None |
| else: |
| return 0, image[x1:x2, y1:y2] |
|
|
|
|
| def get_min_block(image, full=True): |
| if full: |
| structure = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] |
| else: |
| structure = [[0, 1, 0], [1, 1, 1], [0, 1, 0]] |
| masks, n_masks = ndimage.label(image, structure=structure) |
| sizes = [(masks == i).sum() for i in range(1, n_masks + 1)] |
|
|
| if n_masks == 0: |
| return 2, None |
|
|
| min_n = np.argmin(sizes) + 1 |
|
|
| boundaries = find_color_boundaries(masks, min_n) |
| if boundaries: |
| return (0, image[boundaries[0] : boundaries[1] + 1, boundaries[2] : boundaries[3] + 1]) |
| else: |
| return 1, None |
|
|
|
|
| def get_min_block_mask(image, full=True): |
| if full: |
| structure = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] |
| else: |
| structure = [[0, 1, 0], [1, 1, 1], [0, 1, 0]] |
| masks, n_masks = ndimage.label(image, structure=structure) |
| sizes = [(masks == i).sum() for i in range(1, n_masks + 1)] |
|
|
| if n_masks == 0: |
| return 2, None |
|
|
| min_n = np.argmin(sizes) + 1 |
| return 0, masks == min_n |
|
|
|
|
| def get_max_block_mask(image, full=True): |
| if full: |
| structure = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] |
| else: |
| structure = [[0, 1, 0], [1, 1, 1], [0, 1, 0]] |
| masks, n_masks = ndimage.label(image, structure=structure) |
| sizes = [(masks == i).sum() for i in range(1, n_masks + 1)] |
|
|
| if n_masks == 0: |
| return 2, None |
|
|
| min_n = np.argmax(sizes) + 1 |
| return 0, masks == min_n |
|
|
|
|
| def get_max_block(image, full=True): |
| if full: |
| structure = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] |
| else: |
| structure = [[0, 1, 0], [1, 1, 1], [0, 1, 0]] |
| masks, n_masks = ndimage.label(image, structure=structure) |
| sizes = [(masks == i).sum() for i in range(1, n_masks + 1)] |
|
|
| if n_masks == 0: |
| return 2, None |
|
|
| max_n = np.argmax(sizes) + 1 |
|
|
| boundaries = find_color_boundaries(masks, max_n) |
| if boundaries: |
| return (0, image[boundaries[0] : boundaries[1] + 1, boundaries[2] : boundaries[3] + 1]) |
| else: |
| return 1, None |
|
|
|
|
| def get_block_with_side_colors(image, block_type="min", structure=0): |
| if structure == 0: |
| structure = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] |
| else: |
| structure = [[0, 1, 0], [1, 1, 1], [0, 1, 0]] |
| masks, n_masks = ndimage.label(image, structure=structure) |
|
|
| if n_masks == 0: |
| return 2, None |
|
|
| unique_nums = [] |
| for i in range(1, n_masks + 1): |
| unique = np.unique(image[masks == i]) |
| unique_nums.append(len(unique)) |
|
|
| if block_type == "min": |
| n = np.argmin(unique_nums) + 1 |
| else: |
| n = np.argmax(unique_nums) + 1 |
|
|
| boundaries = find_color_boundaries(masks, n) |
| if boundaries: |
| return (0, image[boundaries[0] : boundaries[1] + 1, boundaries[2] : boundaries[3] + 1]) |
| else: |
| return 1, None |
|
|
|
|
| def get_block_with_side_colors_count(image, block_type="min", structure=0): |
| if structure == 0: |
| structure = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] |
| else: |
| structure = [[0, 1, 0], [1, 1, 1], [0, 1, 0]] |
| masks, n_masks = ndimage.label(image, structure=structure) |
| if n_masks == 0: |
| return 2, None |
|
|
| unique_nums = [] |
| for i in range(1, n_masks + 1): |
| unique, counts = np.unique(image[masks == i], return_counts=True) |
| unique_nums.append(min(counts)) |
|
|
| if block_type == "min": |
| n = np.argmin(unique_nums) + 1 |
| else: |
| n = np.argmax(unique_nums) + 1 |
|
|
| boundaries = find_color_boundaries(masks, n) |
| if boundaries: |
| return (0, image[boundaries[0] : boundaries[1] + 1, boundaries[2] : boundaries[3] + 1]) |
| else: |
| return 1, None |
|
|
|
|
| def get_color(color_dict, colors): |
| """ retrive the absolute number corresponding a color set by color_dict""" |
| for i, color in enumerate(colors): |
| for data in color: |
| equal = True |
| for k, v in data.items(): |
| if k not in color_dict or v != color_dict[k]: |
| equal = False |
| break |
| if equal: |
| return i |
| return -1 |
|
|
|
|
| def get_mask_from_block(image, color): |
| if color in np.unique(image, return_counts=False): |
| return 0, image == color |
| else: |
| return 1, None |
|
|
|
|
| def get_background(image, color): |
| return 0, np.uint8(np.ones_like(image) * color) |
|
|
|
|
| def get_mask_from_max_color_coverage(image, color): |
| if color in np.unique(image, return_counts=False): |
| boundaries = find_color_boundaries(image, color) |
| result = (image.copy() * 0).astype(bool) |
| result[boundaries[0] : boundaries[1] + 1, boundaries[2] : boundaries[3] + 1] = True |
| return 0, result |
| else: |
| return 1, None |
|
|
|
|
| def add_unique_colors(image, result, colors=None): |
| """adds information about colors unique for some parts of the image""" |
| if colors is None: |
| colors = np.unique(image) |
|
|
| unique_side = [False for i in range(10)] |
| unique_corner = [False for i in range(10)] |
|
|
| half_size = (((image.shape[0] + 1) // 2), ((image.shape[1] + 1) // 2)) |
| for (image_part, side, unique_list) in [ |
| (image[: half_size[0]], "bottom", unique_side), |
| (image[-half_size[0] :], "top", unique_side), |
| (image[:, : half_size[1]], "right", unique_side), |
| (image[:, -half_size[1] :], "left", unique_side), |
| (image[: half_size[0], : half_size[1]], "tl", unique_corner), |
| (image[: half_size[0], -half_size[1] :], "tr", unique_corner), |
| (image[-half_size[0] :, : half_size[1]], "bl", unique_corner), |
| (image[-half_size[0] :, -half_size[1] :], "br", unique_corner), |
| ]: |
| unique = np.uint8(np.unique(image_part)) |
| if len(unique) == len(colors) - 1: |
| color = [x for x in colors if x not in unique][0] |
| unique_list[color] = True |
| result["colors"][color].append({"type": "unique", "side": side}) |
|
|
| for i in range(10): |
| if unique_corner[i]: |
| result["colors"][i].append({"type": "unique", "side": "corner"}) |
| if unique_side[i]: |
| result["colors"][i].append({"type": "unique", "side": "side"}) |
| if unique_side[i] or unique_corner[i]: |
| result["colors"][i].append({"type": "unique", "side": "any"}) |
|
|
| return |
|
|
|
|
| def add_center_color(image, result, colors=None): |
| i = image.shape[0] // 4 |
| j = image.shape[1] // 4 |
| center = image[i : image.shape[0] - i, j : image.shape[1] - j] |
| values, counts = np.unique(center, return_counts=True) |
| if len(counts) > 0: |
| ind = np.argmax(counts) |
| color = values[ind] |
| result["colors"][color].append({"type": "center"}) |
|
|
|
|
| def get_color_scheme(image, target_image=None, params=None): |
| """processes original image and returns dict color scheme""" |
| result = { |
| "grid_color": -1, |
| "colors": [[], [], [], [], [], [], [], [], [], []], |
| "colors_sorted": [], |
| "grid_size": [1, 1], |
| } |
|
|
| if params is None: |
| params = ["coverage", "unique", "corners", "top", "grid"] |
|
|
| |
|
|
| unique, counts = np.unique(image, return_counts=True) |
| colors = [unique[i] for i in np.argsort(counts)] |
|
|
| result["colors_sorted"] = colors |
| result["colors_num"] = len(colors) |
|
|
| for color in range(10): |
| |
| result["colors"][color].append({"type": "abs", "k": color}) |
|
|
| if len(colors) == 2 and 0 in colors: |
| result["colors"][[x for x in colors if x != 0][0]].append({"type": "non_zero"}) |
|
|
| if "coverage" in params: |
| for k, color in enumerate(colors): |
| |
| result["colors"][color].append({"type": "min", "k": k}) |
| |
| result["colors"][color].append({"type": "max", "k": len(colors) - k - 1}) |
|
|
| if "unique" in params: |
| add_unique_colors(image, result, colors=None) |
| add_center_color(image, result) |
|
|
| if "corners" in params: |
| |
| result["colors"][image[0, 0]].append({"type": "corner", "side": "tl"}) |
| result["colors"][image[0, -1]].append({"type": "corner", "side": "tr"}) |
| result["colors"][image[-1, 0]].append({"type": "corner", "side": "bl"}) |
| result["colors"][image[-1, -1]].append({"type": "corner", "side": "br"}) |
|
|
| if "top" in params: |
| |
| for k in range(10): |
| mask = image == k |
| is_on_top0 = mask.min(axis=0).any() |
| is_on_top1 = mask.min(axis=1).any() |
| if is_on_top0: |
| result["colors"][k].append({"type": "on_top", "side": "0"}) |
| if is_on_top1: |
| result["colors"][k].append({"type": "on_top", "side": "1"}) |
| if is_on_top1 or is_on_top0: |
| result["colors"][k].append({"type": "on_top", "side": "any"}) |
|
|
| if "grid" in params: |
| grid_color, grid_size, frame = find_grid(image) |
| if grid_color >= 0: |
| result["grid_color"] = grid_color |
| result["grid_size"] = grid_size |
| result["grid_frame"] = frame |
| result["colors"][grid_color].append({"type": "grid"}) |
|
|
| return result |
|
|
|
|
| def add_block(target_dict, image, params_list): |
| array_hash = hash(matrix2answer(image)) |
| if array_hash not in target_dict["arrays"]: |
| target_dict["arrays"][array_hash] = {"array": image, "params": []} |
|
|
| for params in params_list: |
| params_hash = get_dict_hash(params) |
| target_dict["arrays"][array_hash]["params"].append(params) |
| target_dict["params"][params_hash] = array_hash |
|
|
|
|
| def get_original(image): |
| return 0, image |
|
|
|
|
| def get_inversed_colors(image): |
| unique = np.unique(image) |
| if len(unique) != 2: |
| return 1, None |
| result = image.copy() |
| result[image == unique[0]] = unique[1] |
| result[image == unique[1]] = unique[0] |
| return 0, result |
|
|
|
|
| def generate_blocks(image, result, max_time=600, max_blocks=200000, max_masks=200000, target_image=None, params=None): |
| all_params = [ |
| "initial", |
| "background", |
| "min_max_blocks", |
| "block_with_side_colors", |
| "max_area_covered", |
| "grid_cells", |
| "halves", |
| "corners", |
| "rotate", |
| "transpose", |
| "cut_edges", |
| "resize", |
| "reflect", |
| "cut_parts", |
| "swap_colors", |
| "k_part", |
| ] |
|
|
| if not params: |
| params = all_params |
|
|
| start_time = time.time() |
|
|
| result["blocks"] = {"arrays": {}, "params": {}} |
|
|
| if "initial" in params: |
| |
| add_block(result["blocks"], image, [[{"type": "original"}]]) |
|
|
| |
| status, block = get_inversed_colors(image) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block(result["blocks"], block, [[{"type": "inversed_colors"}]]) |
|
|
| |
| if ( |
| ("min_max_blocks" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| |
| for full in [True, False]: |
| status, block = get_max_block(image, full) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block(result["blocks"], block, [[{"type": "max_block", "full": full}]]) |
|
|
| if ( |
| ("block_with_side_colors" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| |
| for block_type in ["min", "max"]: |
| for structure in [0, 1]: |
| status, block = get_block_with_side_colors(image, block_type, structure) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block( |
| result["blocks"], |
| block, |
| [[{"type": "block_with_side_colors", "block_type": block_type, "structure": structure}]], |
| ) |
| for block_type in ["min", "max"]: |
| for structure in [0, 1]: |
| status, block = get_block_with_side_colors_count(image, block_type, structure) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block( |
| result["blocks"], |
| block, |
| [[{"type": "block_with_side_colors_count", "block_type": block_type, "structure": structure}]], |
| ) |
| |
| |
| if ("background" in params) and (time.time() - start_time < max_time): |
| |
| for color in range(10): |
| status, block = get_background(image, color) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| params_list = [] |
| for color_dict in result["colors"][color].copy(): |
| params_list.append([{"type": "background", "color": color_dict}]) |
| add_block(result["blocks"], block, params_list) |
|
|
| |
| if ("max_area_covered" in params) and (time.time() - start_time < max_time): |
| |
| for color in result["colors_sorted"]: |
| status, block = get_color_max(image, color) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| params_list = [] |
| for color_dict in result["colors"][color].copy(): |
| params_list.append([{"type": "color_max", "color": color_dict}]) |
| add_block(result["blocks"], block, params_list) |
|
|
| |
| if ( |
| ("grid_cells" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| if result["grid_color"] > 0: |
| for i in range(result["grid_size"][0]): |
| for j in range(result["grid_size"][1]): |
| status, block = get_grid(image, result["grid_size"], (i, j), frame=result["grid_frame"]) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block( |
| result["blocks"], |
| block, |
| [ |
| [ |
| { |
| "type": "grid", |
| "grid_size": result["grid_size"], |
| "cell": [i, j], |
| "frame": result["grid_frame"], |
| } |
| ] |
| ], |
| ) |
|
|
| |
| if ("halves" in params) and (time.time() - start_time < max_time) and (len(result["blocks"]["arrays"]) < max_blocks): |
| for side in ["l", "r", "t", "b", "long1", "long2"]: |
| status, block = get_half(image, side=side) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block(result["blocks"], block, [[{"type": "half", "side": side}]]) |
|
|
| |
| if ("pixels" in params) and (time.time() - start_time < max_time) and (len(result["blocks"]["arrays"]) < max_blocks): |
| stop = False |
| for i in range(image.shape[0]): |
| if stop: |
| break |
| for j in range(image.shape[1]): |
| status, block = get_pixel(image, i=i, j=j) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block(result["blocks"], block, [[{"type": "pixel", "i": i, "j": j}]]) |
| if len(result["blocks"]["arrays"]) >= max_blocks: |
| stop = True |
| break |
|
|
| |
| if ( |
| ("pixel_fixed" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| for i in range(10): |
| status, block = get_pixel_fixed(image, i=i) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block(result["blocks"], block, [[{"type": "pixel_fixed", "i": i}]]) |
|
|
| |
| if ("k_part" in params) and (time.time() - start_time < max_time) and (len(result["blocks"]["arrays"]) < max_blocks): |
| for num in [3, 4]: |
| for k in range(num): |
| status, block = get_k_part(image, num=num, k=k) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block(result["blocks"], block, [[{"type": "k_part", "num": num, "k": k}]]) |
|
|
| |
| if ( |
| ("corners" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| for side in ["tl", "tr", "bl", "br"]: |
| status, block = get_corner(image, side=side) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| add_block(result["blocks"], block, [[{"type": "corner", "side": side}]]) |
|
|
| main_blocks_num = len(result["blocks"]) |
|
|
| |
| if ("rotate" in params) and (time.time() - start_time < max_time) and (len(result["blocks"]["arrays"]) < max_blocks): |
| current_blocks = result["blocks"]["arrays"].copy() |
| for k in range(1, 4): |
| for key, data in current_blocks.items(): |
| status, block = get_rotation(data["array"], k=k) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| params_list = [i + [{"type": "rotation", "k": k}] for i in data["params"]] |
| add_block(result["blocks"], block, params_list) |
|
|
| |
| if ( |
| ("transpose" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| current_blocks = result["blocks"]["arrays"].copy() |
| for key, data in current_blocks.items(): |
| status, block = get_transpose(data["array"]) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| params_list = [i + [{"type": "transpose"}] for i in data["params"]] |
| add_block(result["blocks"], block, params_list) |
|
|
| |
| if ( |
| ("cut_edges" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| current_blocks = result["blocks"]["arrays"].copy() |
| for l, r, t, b in [ |
| (1, 1, 1, 1), |
| (1, 0, 0, 0), |
| (0, 1, 0, 0), |
| (0, 0, 1, 0), |
| (0, 0, 0, 1), |
| (1, 1, 0, 0), |
| (1, 0, 0, 1), |
| (0, 0, 1, 1), |
| (0, 1, 1, 0), |
| ]: |
| if time.time() - start_time < max_time: |
| for key, data in current_blocks.items(): |
| status, block = get_cut_edge(data["array"], l=l, r=r, t=t, b=b) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| params_list = [ |
| i + [{"type": "cut_edge", "l": l, "r": r, "t": t, "b": b}] for i in data["params"] |
| ] |
| add_block(result["blocks"], block, params_list) |
|
|
| |
| if ("resize" in params) and (time.time() - start_time < max_time) and (len(result["blocks"]["arrays"]) < max_blocks): |
| current_blocks = result["blocks"]["arrays"].copy() |
| for scale in [2, 3, 1 / 2, 1 / 3]: |
| for key, data in current_blocks.items(): |
| status, block = get_resize(data["array"], scale) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| params_list = [i + [{"type": "resize", "scale": scale}] for i in data["params"]] |
| add_block(result["blocks"], block, params_list) |
|
|
| for size_x, size_y in [(2, 2), (3, 3)]: |
| for key, data in current_blocks.items(): |
| status, block = get_resize_to(data["array"], size_x, size_y) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| params_list = [ |
| i + [{"type": "resize_to", "size_x": size_x, "size_y": size_y}] for i in data["params"] |
| ] |
| add_block(result["blocks"], block, params_list) |
|
|
| |
| if ( |
| ("reflect" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| current_blocks = result["blocks"]["arrays"].copy() |
| for side in ["r", "l", "t", "b", "rt", "rb", "lt", "lb"]: |
| if time.time() - start_time < max_time: |
| for key, data in current_blocks.items(): |
| status, block = get_reflect(data["array"], side) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| params_list = [i + [{"type": "reflect", "side": side}] for i in data["params"]] |
| add_block(result["blocks"], block, params_list) |
|
|
| |
| if ( |
| ("cut_parts" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| max_x = image.shape[0] |
| max_y = image.shape[1] |
| min_block_size = 2 |
| stop = False |
| for x1 in range(0, max_x - min_block_size): |
| if stop: |
| break |
| if time.time() - start_time < max_time: |
| if max_x - x1 <= min_block_size: |
| continue |
| for x2 in range(x1 + min_block_size, max_x): |
| if stop: |
| break |
| for y1 in range(0, max_y - min_block_size): |
| if stop: |
| break |
| if max_y - y1 <= min_block_size: |
| continue |
| for y2 in range(y1 + min_block_size, max_y): |
| status, block = get_cut(image, x1, y1, x2, y2) |
| if status == 0: |
| add_block( |
| result["blocks"], block, [[{"type": "cut", "x1": x1, "x2": x2, "y1": y1, "y2": y2}]] |
| ) |
| if len(result["blocks"]["arrays"]) >= max_blocks: |
| stop = True |
| break |
|
|
| list_param_list = [] |
| list_blocks = [] |
|
|
| |
| if ( |
| ("swap_colors" in params) |
| and (time.time() - start_time < max_time) |
| and (len(result["blocks"]["arrays"]) < max_blocks) |
| ): |
| current_blocks = result["blocks"]["arrays"].copy() |
| |
| |
| budget = max_blocks - len(result["blocks"]["arrays"]) |
| stop = False |
| for color_1 in range(9): |
| if stop: |
| break |
| if time.time() - start_time < max_time: |
| for color_2 in range(color_1 + 1, 10): |
| if stop: |
| break |
| for key, data in current_blocks.items(): |
| if stop: |
| break |
| status, block = get_color_swap(data["array"], color_1, color_2) |
| if status == 0 and block.shape[0] > 0 and block.shape[1] > 0: |
| for color_dict_1 in result["colors"][color_1].copy(): |
| if stop: |
| break |
| for color_dict_2 in result["colors"][color_2].copy(): |
| list_param_list.append( |
| [ |
| j |
| + [{"type": "color_swap", "color_1": color_dict_1, "color_2": color_dict_2}] |
| for j in data["params"] |
| ] |
| ) |
| list_blocks.append(block) |
| if len(list_blocks) >= budget: |
| stop = True |
| break |
|
|
| for block, params_list in zip(list_blocks, list_param_list): |
| add_block(result["blocks"], block, params_list) |
|
|
| if time.time() - start_time > max_time: |
| print("Time is over") |
| if len(result["blocks"]["arrays"]) >= max_blocks: |
| print("Max number of blocks exceeded") |
| return result |
|
|
|
|
| def generate_masks(image, result, max_time=600, max_blocks=200000, max_masks=200000, target_image=None, params=None): |
| start_time = time.time() |
|
|
| all_params = ["initial_masks", "additional_masks", "coverage_masks", "min_max_masks"] |
|
|
| if not params: |
| params = all_params |
|
|
| result["masks"] = {"arrays": {}, "params": {}} |
|
|
| |
| current_blocks = result["blocks"]["arrays"].copy() |
| if ("initial_masks" in params) and (time.time() - start_time < max_time * 2): |
| stop = False |
| for key, data in current_blocks.items(): |
| if stop: |
| break |
| for color in result["colors_sorted"]: |
| status, mask = get_mask_from_block(data["array"], color) |
| if status == 0 and mask.shape[0] > 0 and mask.shape[1] > 0: |
| params_list = [ |
| {"operation": "none", "params": {"block": i, "color": color_dict}} |
| for i in data["params"] |
| for color_dict in result["colors"][color] |
| ] |
| add_block(result["masks"], mask, params_list) |
| if len(result["masks"]["arrays"]) >= max_masks: |
| stop = True |
| break |
|
|
| initial_masks = result["masks"]["arrays"].copy() |
| if ( |
| ("initial_masks" in params) |
| and (time.time() - start_time < max_time * 2) |
| and (len(result["masks"]["arrays"]) < max_masks) |
| ): |
| for key, mask in initial_masks.items(): |
| add_block( |
| result["masks"], |
| np.logical_not(mask["array"]), |
| [{"operation": "not", "params": param["params"]} for param in mask["params"]], |
| ) |
| if len(result["masks"]["arrays"]) >= max_masks: |
| break |
|
|
| initial_masks = result["masks"]["arrays"].copy() |
| masks_to_add = [] |
| processed = [] |
| if ("additional_masks" in params) and (time.time() - start_time < max_time * 2): |
| |
| |
| |
| budget = max(0, max_masks - len(result["masks"]["arrays"])) |
| stop = False |
| for key1, mask1 in initial_masks.items(): |
| if stop: |
| break |
| processed.append(key1) |
| if time.time() - start_time < max_time * 2 and ( |
| target_image is None |
| or (target_image.shape == mask1["array"].shape) |
| or (target_image.shape == mask1["array"].T.shape) |
| ): |
| for key2, mask2 in initial_masks.items(): |
| if stop: |
| break |
| if key2 in processed: |
| continue |
| if (mask1["array"].shape[0] == mask2["array"].shape[0]) and ( |
| mask1["array"].shape[1] == mask2["array"].shape[1] |
| ): |
| params_list_and = [] |
| params_list_or = [] |
| params_list_xor = [] |
| for param1 in mask1["params"]: |
| for param2 in mask2["params"]: |
| params_list_and.append( |
| {"operation": "and", "params": {"mask1": param1, "mask2": param2}} |
| ) |
| params_list_or.append({"operation": "or", "params": {"mask1": param1, "mask2": param2}}) |
| params_list_xor.append( |
| {"operation": "xor", "params": {"mask1": param1, "mask2": param2}} |
| ) |
| masks_to_add.append( |
| (result["masks"], np.logical_and(mask1["array"], mask2["array"]), params_list_and) |
| ) |
| masks_to_add.append( |
| (result["masks"], np.logical_or(mask1["array"], mask2["array"]), params_list_or) |
| ) |
| masks_to_add.append( |
| (result["masks"], np.logical_xor(mask1["array"], mask2["array"]), params_list_xor) |
| ) |
| if len(masks_to_add) >= budget: |
| stop = True |
| break |
|
|
| for path, array, params_list in masks_to_add: |
| add_block(path, array, params_list) |
| |
| if ("coverage_masks" in params) and (time.time() - start_time < max_time * 2): |
| for color in result["colors_sorted"][1:]: |
| status, mask = get_mask_from_max_color_coverage(image, color) |
| if status == 0 and mask.shape[0] > 0 and mask.shape[1] > 0: |
| params_list = [ |
| {"operation": "coverage", "params": {"color": color_dict}} |
| for color_dict in result["colors"][color].copy() |
| ] |
| add_block(result["masks"], mask, params_list) |
| |
| if ("min_max_masks" in params) and (time.time() - start_time < max_time * 2): |
| status, mask = get_min_block_mask(image) |
| if status == 0 and mask.shape[0] > 0 and mask.shape[1] > 0: |
| params_list = [{"operation": "min_block"}] |
| add_block(result["masks"], mask, params_list) |
| status, mask = get_max_block_mask(image) |
| if status == 0 and mask.shape[0] > 0 and mask.shape[1] > 0: |
| params_list = [{"operation": "max_block"}] |
| add_block(result["masks"], mask, params_list) |
| if time.time() - start_time > max_time: |
| print("Time is over") |
| if len(result["masks"]["arrays"]) >= max_masks: |
| print("Max number of masks exceeded") |
| return result |
|
|
|
|
| def process_image( |
| image, max_time=600, max_blocks=200000, max_masks=200000, target_image=None, params=None, color_params=None |
| ): |
| """processes the original image and returns dict with structured image blocks""" |
|
|
| result = get_color_scheme(image, target_image=target_image, params=color_params) |
| result = generate_blocks(image, result, max_time, max_blocks, max_masks, target_image, params) |
| result = generate_masks(image, result, max_time, max_blocks, max_masks, target_image, params) |
|
|
| return result |
|
|
|
|
| def get_mask_from_block_params(image, params, block_cache=None, mask_cache=None, color_scheme=None): |
| if mask_cache is None: |
| mask_cache = {"arrays": {}, "params": {}} |
| dict_hash = get_dict_hash(params) |
| if dict_hash in mask_cache: |
| mask = mask_cache["arrays"][mask_cache["params"][dict_hash]]["array"] |
| if len(mask) == 0: |
| return 1, None |
| else: |
| return 0, mask |
|
|
| if params["operation"] == "none": |
| status, block = get_predict(image, params["params"]["block"], block_cache, color_scheme) |
| if status != 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 1, None |
| if not color_scheme: |
| color_scheme = get_color_scheme(image) |
| color_num = get_color(params["params"]["color"], color_scheme["colors"]) |
| if color_num < 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 2, None |
| status, mask = get_mask_from_block(block, color_num) |
| if status != 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 6, None |
| add_block(mask_cache, mask, [params]) |
| return 0, mask |
| elif params["operation"] == "not": |
| new_params = params.copy() |
| new_params["operation"] = "none" |
| status, mask = get_mask_from_block_params( |
| image, new_params, block_cache=block_cache, color_scheme=color_scheme, mask_cache=mask_cache |
| ) |
| if status != 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 3, None |
| mask = np.logical_not(mask) |
| add_block(mask_cache, mask, [params]) |
| return 0, mask |
| elif params["operation"] in ["and", "or", "xor"]: |
| new_params = params["params"]["mask1"] |
| status, mask1 = get_mask_from_block_params( |
| image, new_params, block_cache=block_cache, color_scheme=color_scheme, mask_cache=mask_cache |
| ) |
| if status != 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 4, None |
| new_params = params["params"]["mask2"] |
| status, mask2 = get_mask_from_block_params( |
| image, new_params, block_cache=block_cache, color_scheme=color_scheme, mask_cache=mask_cache |
| ) |
| if status != 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 5, None |
| if mask1.shape[0] != mask2.shape[0] or mask1.shape[1] != mask2.shape[1]: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 6, None |
| if params["operation"] == "and": |
| mask = np.logical_and(mask1, mask2) |
| elif params["operation"] == "or": |
| mask = np.logical_or(mask1, mask2) |
| elif params["operation"] == "xor": |
| mask = np.logical_xor(mask1, mask2) |
| add_block(mask_cache, mask, [params]) |
| return 0, mask |
| elif params["operation"] == "coverage": |
| if not color_scheme: |
| color_scheme = get_color_scheme(image) |
| color_num = get_color(params["params"]["color"], color_scheme["colors"]) |
| if color_num < 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 2, None |
| status, mask = get_mask_from_max_color_coverage(image, color_num) |
| if status != 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 6, None |
| add_block(mask_cache, mask, [params]) |
| return 0, mask |
| elif params["operation"] == "min_block": |
| status, mask = get_min_block_mask(image) |
| if status != 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 6, None |
| add_block(mask_cache, mask, [params]) |
| return 0, mask |
| elif params["operation"] == "max_block": |
| status, mask = get_max_block_mask(image) |
| if status != 0: |
| add_block(mask_cache, np.array([[]]), [params]) |
| return 6, None |
| add_block(mask_cache, mask, [params]) |
| return 0, mask |
|
|
|
|
| def get_dict_hash(d): |
| return hash(json.dumps(d, sort_keys=True)) |
|
|
|
|
| def get_predict(image, transforms, block_cache=None, color_scheme=None): |
| """ applies the list of transforms to the image""" |
| params_hash = get_dict_hash(transforms) |
| if params_hash in block_cache["params"]: |
| if block_cache["params"][params_hash] is None: |
| return 1, None |
| else: |
| return 0, block_cache["arrays"][block_cache["params"][params_hash]]["array"] |
|
|
| if not color_scheme: |
| color_scheme = get_color_scheme(image) |
|
|
| if len(transforms) > 1: |
| status, previous_image = get_predict(image, transforms[:-1], block_cache=block_cache, color_scheme=color_scheme) |
| if status != 0: |
| return status, None |
| else: |
| previous_image = image |
|
|
| transform = transforms[-1] |
| function = globals()["get_" + transform["type"]] |
| params = transform.copy() |
| params.pop("type") |
| for color_name in ["color", "color_1", "color_2"]: |
| if color_name in params: |
| params[color_name] = get_color(params[color_name], color_scheme["colors"]) |
| if params[color_name] < 0: |
| return 2, None |
| status, result = function(previous_image, **params) |
|
|
| if status != 0 or len(result) == 0 or len(result[0]) == 0: |
| block_cache["params"][params_hash] = None |
| return 1, None |
|
|
| add_block(block_cache, result, [transforms]) |
| return 0, result |
|
|
|
|
| def filter_colors(sample): |
| |
| all_colors = [] |
| for color_scheme1 in sample["train"]: |
| list_of_colors = [get_dict_hash(color_dict) for i in range(10) for color_dict in color_scheme1["colors"][i]] |
| all_colors.append(list_of_colors) |
| for j in range(1, len(sample["train"])): |
| all_colors[0] = [x for x in all_colors[0] if x in all_colors[j]] |
| keep_colors = set(all_colors[0]) |
|
|
| for color_scheme1 in sample["train"]: |
| for i in range(10): |
| j = 0 |
| while j < len(color_scheme1["colors"][i]): |
| if get_dict_hash(color_scheme1["colors"][i][j]) in keep_colors: |
| j += 1 |
| else: |
| del color_scheme1["colors"][i][j] |
|
|
| delete_colors = [] |
| color_scheme0 = sample["train"][0] |
| for i in range(10): |
| if len(color_scheme0["colors"][i]) > 1: |
| for j, color_dict1 in enumerate(color_scheme0["colors"][i][::-1][:-1]): |
| hash1 = get_dict_hash(color_dict1) |
| delete = True |
| for color_dict2 in color_scheme0["colors"][i][::-1][j + 1 :]: |
| hash2 = get_dict_hash(color_dict2) |
| for color_scheme1 in list(sample["train"][1:]) + list(sample["test"]): |
| found = False |
| for k in range(10): |
| hash_array = [get_dict_hash(color_dict) for color_dict in color_scheme1["colors"][k]] |
| if hash1 in hash_array and hash2 in hash_array: |
| found = True |
| break |
| if not found: |
| delete = False |
| break |
| if delete: |
| delete_colors.append(hash1) |
| break |
|
|
| for color_scheme1 in sample["train"]: |
| for i in range(10): |
| j = 0 |
| while j < len(color_scheme1["colors"][i]): |
| if get_dict_hash(color_scheme1["colors"][i][j]) in delete_colors: |
| del color_scheme1["colors"][i][j] |
| else: |
| j += 1 |
| return |
|
|
|
|
| def filter_blocks(sample, arrays_type="blocks", max_time=60): |
| """De-duplicate equivalent param lists across images. |
| |
| This is O(n_blocks * m_params^2 * n_images * k_blocks_per_image) in the worst case, |
| which explodes on heavy preprocessor sets. A wall-clock budget (`max_time`) bounds |
| the filtering step so a pathological input can't wedge the worker for hours — we |
| simply stop early and leave the remaining duplicates in place (correctness is |
| preserved; only downstream speed suffers slightly). |
| """ |
| start_time = time.time() |
| delete_blocks = [] |
| list_of_lists_of_sets = [] |
| for arrays_list in [x[arrays_type]["arrays"].values() for x in sample["train"][1:]] + [ |
| x[arrays_type]["arrays"].values() for x in sample["test"] |
| ]: |
| list_of_lists_of_sets.append([]) |
| for array in arrays_list: |
| list_of_lists_of_sets[-1].append({get_dict_hash(params_dict) for params_dict in array["params"]}) |
|
|
| bailed = False |
| for initial_array in sample["train"][0][arrays_type]["arrays"].values(): |
| if time.time() - start_time > max_time: |
| bailed = True |
| break |
| if len(initial_array["params"]) > 1: |
| for j, params_dict1 in enumerate(initial_array["params"][::-1][:-1]): |
| hash1 = get_dict_hash(params_dict1) |
| delete = True |
| for params_dict1 in initial_array["params"][::-1][j + 1 :]: |
| hash2 = get_dict_hash(params_dict1) |
| for lists_of_sets in list_of_lists_of_sets: |
| found = False |
| for hash_set in lists_of_sets: |
| if hash1 in hash_set and hash2 in hash_set: |
| found = True |
| break |
| if not found: |
| delete = False |
| break |
| if delete: |
| delete_blocks.append(hash1) |
| break |
| if bailed: |
| print(f"filter_{arrays_type} budget exceeded; skipping remaining dedup") |
|
|
| for arrays_list in [x[arrays_type]["arrays"].values() for x in sample["train"]] + [ |
| x[arrays_type]["arrays"].values() for x in sample["test"] |
| ]: |
| for array in arrays_list: |
| params_list = array["params"] |
| j = 0 |
| while j < len(params_list): |
| if get_dict_hash(params_list[j]) in delete_blocks: |
| del params_list[j] |
| else: |
| j += 1 |
| return |
|
|
|
|
| def extract_target_blocks(sample, color_params=None): |
| target_blocks_cache = [] |
| params = ["initial", "block_with_side_colors", "min_max_blocks", "max_area_covered", "cut_parts"] |
| for n in range(len(sample["train"])): |
| target_image = np.uint8(sample["train"][n]["output"]) |
| target_blocks_cache.append(get_color_scheme(target_image, params=color_params)) |
| target_blocks_cache[-1].update(generate_blocks(target_image, target_blocks_cache[-1], params=params)) |
| final_arrays = list( |
| set.intersection( |
| *[set(target_blocks_cache[n]["blocks"]["arrays"].keys()) for n in range(len(target_blocks_cache))] |
| ) |
| ) |
| for i, key in enumerate(final_arrays): |
| for n in range(len(sample["train"])): |
| params_list = [[{"type": "target", "k": i}]] |
| add_block( |
| sample["train"][n]["blocks"], target_blocks_cache[0]["blocks"]["arrays"][key]["array"], params_list |
| ) |
| for n in range(len(sample["test"])): |
| params_list = [[{"type": "target", "k": i}]] |
| add_block(sample["test"][n]["blocks"], target_blocks_cache[0]["blocks"]["arrays"][key]["array"], params_list) |
|
|
|
|
| def preprocess_sample( |
| sample, |
| params=None, |
| color_params=None, |
| process_whole_ds=False, |
| max_blocks=200000, |
| max_masks=200000, |
| max_time=600, |
| ): |
| """ make the whole preprocessing for particular sample |
| |
| Extra knobs (all optional, defaults preserve historical behaviour): |
| - max_blocks / max_masks: per-image caps on the abstraction search space. |
| - max_time: per-image wall-time budget (seconds) for block/mask generation. |
| """ |
|
|
| for n, image in enumerate(sample["train"]): |
| original_image = np.uint8(image["input"]) |
| target_image = np.uint8(sample["train"][n]["output"]) |
| sample["train"][n].update(get_color_scheme(original_image, target_image=target_image, params=color_params)) |
| for n, image in enumerate(sample["test"]): |
| original_image = np.uint8(image["input"]) |
| sample["test"][n].update(get_color_scheme(original_image, params=color_params)) |
|
|
| filter_colors(sample) |
|
|
| for n, image in enumerate(sample["train"]): |
| original_image = np.uint8(image["input"]) |
| target_image = np.uint8(sample["train"][n]["output"]) |
| sample["train"][n].update( |
| generate_blocks( |
| original_image, |
| sample["train"][n], |
| max_time=max_time, |
| max_blocks=max_blocks, |
| max_masks=max_masks, |
| target_image=target_image, |
| params=params, |
| ) |
| ) |
| for n, image in enumerate(sample["test"]): |
| original_image = np.uint8(image["input"]) |
| sample["test"][n].update( |
| generate_blocks( |
| original_image, |
| sample["test"][n], |
| max_time=max_time, |
| max_blocks=max_blocks, |
| max_masks=max_masks, |
| params=params, |
| ) |
| ) |
|
|
| if params is not None and "target" in params: |
| extract_target_blocks(sample, color_params) |
| filter_blocks(sample) |
|
|
| for n, image in enumerate(sample["train"]): |
| original_image = np.uint8(image["input"]) |
| target_image = np.uint8(sample["train"][n]["output"]) |
| sample["train"][n].update( |
| generate_masks( |
| original_image, |
| sample["train"][n], |
| max_time=max_time, |
| max_blocks=max_blocks, |
| max_masks=max_masks, |
| target_image=target_image, |
| params=params, |
| ) |
| ) |
| for n, image in enumerate(sample["test"]): |
| original_image = np.uint8(image["input"]) |
| sample["test"][n].update( |
| generate_masks( |
| original_image, |
| sample["test"][n], |
| max_time=max_time, |
| max_blocks=max_blocks, |
| max_masks=max_masks, |
| params=params, |
| ) |
| ) |
|
|
| return sample |
|
|