mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Add map_seamless_tiles(...).
This commit is contained in:
parent
36d72baaaa
commit
3573d39860
@ -13,7 +13,10 @@
|
|||||||
"import cv2\n",
|
"import cv2\n",
|
||||||
"\n",
|
"\n",
|
||||||
"from invokeai.backend.vto_workflow.overlay_pattern import generate_dress_mask\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",
|
"id": "dbb53794",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"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": []
|
"source": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
31
invokeai/backend/vto_workflow/seamless_mapping.py
Normal file
31
invokeai/backend/vto_workflow/seamless_mapping.py
Normal 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
|
Loading…
Reference in New Issue
Block a user