Add map_seamless_tiles(...).

This commit is contained in:
Ryan Dick 2024-07-25 14:48:39 -04:00
parent 36d72baaaa
commit 3573d39860
2 changed files with 57 additions and 1 deletions

View File

@ -13,7 +13,10 @@
"import cv2\n",
"\n",
"from invokeai.backend.vto_workflow.overlay_pattern import generate_dress_mask\n",
"from invokeai.backend.vto_workflow.extract_channel import extract_channel, ImageChannel\n"
"from invokeai.backend.vto_workflow.extract_channel import extract_channel, ImageChannel\n",
"from invokeai.backend.vto_workflow.seamless_mapping import map_seamless_tiles\n",
"\n",
"\n"
]
},
{
@ -83,6 +86,28 @@
"id": "dbb53794",
"metadata": {},
"outputs": [],
"source": [
"expanded_pattern = map_seamless_tiles(seamless_tile=pattern_image, target_hw=(model_image.height, model_image.width), num_repeats_h=5.0)\n",
"expanded_pattern"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2a12c166",
"metadata": {},
"outputs": [],
"source": [
"expanded_pattern = map_seamless_tiles(seamless_tile=pattern_image, target_hw=(model_image.height, model_image.width), num_repeats_h=1.0)\n",
"expanded_pattern"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f4f22d02",
"metadata": {},
"outputs": [],
"source": []
}
],

View File

@ -0,0 +1,31 @@
import math
import numpy as np
from PIL import Image
def map_seamless_tiles(seamless_tile: Image.Image, target_hw: tuple[int, int], num_repeats_h: float) -> Image.Image:
"""Map seamless tiles to a target size with a given number of repeats along the height dimension."""
# TODO(ryand): Add option to flip odd rows and columns if the tile is not seamless.
# - May also want the option to decide on a per-axis basis.
target_h, target_w = target_hw
# Calculate the height of the tile that is necessary to achieve the desired number of repeats.
# Take the ceiling so that the last tile overflows the target height.
target_tile_h = math.ceil(target_h / num_repeats_h)
# Resize the tile to the target height.
# Determine the target_tile_w that preserves the original aspect ratio.
target_tile_w = int(target_tile_h / seamless_tile.height * seamless_tile.width)
resized_tile = seamless_tile.resize((target_tile_w, target_tile_h))
# Repeat the tile along the height and width dimensions.
num_repeats_h_int = math.ceil(num_repeats_h)
num_repeats_w_int = math.ceil(target_w / target_tile_w)
seamless_tiles_np = np.array(resized_tile)
repeated_tiles_np = np.tile(seamless_tiles_np, (num_repeats_h_int, num_repeats_w_int, 1))
# Crop the repeated tiles to the target size.
output_pattern = Image.fromarray(repeated_tiles_np[:target_h, :target_w])
return output_pattern