mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
- Even_spilt overlap renamed to overlap_fraction
- min_overlap removed * restrictions and round_to_8 - min_overlap handles tile size > image size by clipping the num tiles to 1. - Updated assert test on min_overlap.
This commit is contained in:
parent
4c97b619fb
commit
fefb78795f
@ -88,7 +88,7 @@ class CalculateImageTilesEvenSplitInvocation(BaseInvocation):
|
||||
ge=1,
|
||||
description="Number of tiles to divide image into on the y axis",
|
||||
)
|
||||
overlap: float = InputField(
|
||||
overlap_fraction: float = InputField(
|
||||
default=0.25,
|
||||
ge=0,
|
||||
lt=1,
|
||||
@ -101,7 +101,7 @@ class CalculateImageTilesEvenSplitInvocation(BaseInvocation):
|
||||
image_width=self.image_width,
|
||||
num_tiles_x=self.num_tiles_x,
|
||||
num_tiles_y=self.num_tiles_y,
|
||||
overlap=self.overlap,
|
||||
overlap_fraction=self.overlap_fraction,
|
||||
)
|
||||
return CalculateImageTilesOutput(tiles=tiles)
|
||||
|
||||
@ -120,18 +120,9 @@ class CalculateImageTilesMinimumOverlapInvocation(BaseInvocation):
|
||||
image_height: int = InputField(
|
||||
ge=1, default=1024, description="The image height, in pixels, to calculate tiles for."
|
||||
)
|
||||
tile_width: int = InputField(ge=1, default=576, multiple_of=8, description="The tile width, in pixels.")
|
||||
tile_height: int = InputField(ge=1, default=576, multiple_of=8, description="The tile height, in pixels.")
|
||||
min_overlap: int = InputField(
|
||||
default=128,
|
||||
ge=0,
|
||||
multiple_of=8,
|
||||
description="Minimum overlap between adjacent tiles, in pixels(must be a multiple of 8).",
|
||||
)
|
||||
round_to_8: bool = InputField(
|
||||
default=False,
|
||||
description="Round outputs down to the nearest 8 (for pulling from a large noise field)",
|
||||
)
|
||||
tile_width: int = InputField(ge=1, default=576, description="The tile width, in pixels.")
|
||||
tile_height: int = InputField(ge=1, default=576, description="The tile height, in pixels.")
|
||||
min_overlap: int = InputField(default=128, ge=0, description="Minimum overlap between adjacent tiles, in pixels.")
|
||||
|
||||
def invoke(self, context: InvocationContext) -> CalculateImageTilesOutput:
|
||||
tiles = calc_tiles_min_overlap(
|
||||
@ -140,7 +131,6 @@ class CalculateImageTilesMinimumOverlapInvocation(BaseInvocation):
|
||||
tile_height=self.tile_height,
|
||||
tile_width=self.tile_width,
|
||||
min_overlap=self.min_overlap,
|
||||
round_to_8=self.round_to_8,
|
||||
)
|
||||
return CalculateImageTilesOutput(tiles=tiles)
|
||||
|
||||
|
@ -102,7 +102,7 @@ def calc_tiles_with_overlap(
|
||||
|
||||
|
||||
def calc_tiles_even_split(
|
||||
image_height: int, image_width: int, num_tiles_x: int, num_tiles_y: int, overlap: float = 0
|
||||
image_height: int, image_width: int, num_tiles_x: int, num_tiles_y: int, overlap_fraction: float = 0
|
||||
) -> list[Tile]:
|
||||
"""Calculate the tile coordinates for a given image shape with the number of tiles requested.
|
||||
|
||||
@ -111,7 +111,7 @@ def calc_tiles_even_split(
|
||||
image_width (int): The image width in px.
|
||||
num_x_tiles (int): The number of tile to split the image into on the X-axis.
|
||||
num_y_tiles (int): The number of tile to split the image into on the Y-axis.
|
||||
overlap (float, optional): The target overlap amount of the tiles size. Defaults to 0.
|
||||
overlap_fraction (float, optional): The target overlap as fraction of the tiles size. Defaults to 0.
|
||||
|
||||
Returns:
|
||||
list[Tile]: A list of tiles that cover the image shape. Ordered from left-to-right, top-to-bottom.
|
||||
@ -119,11 +119,15 @@ def calc_tiles_even_split(
|
||||
|
||||
# Ensure tile size is divisible by 8
|
||||
if image_width % LATENT_SCALE_FACTOR != 0 or image_height % LATENT_SCALE_FACTOR != 0:
|
||||
raise ValueError(f"image size (({image_width}, {image_height})) must be divisible by 8")
|
||||
raise ValueError(f"image size (({image_width}, {image_height})) must be divisible by {LATENT_SCALE_FACTOR}")
|
||||
|
||||
# Calculate the overlap size based on the percentage and adjust it to be divisible by 8 (rounding up)
|
||||
overlap_x = LATENT_SCALE_FACTOR * math.ceil(int((image_width / num_tiles_x) * overlap) / LATENT_SCALE_FACTOR)
|
||||
overlap_y = LATENT_SCALE_FACTOR * math.ceil(int((image_height / num_tiles_y) * overlap) / LATENT_SCALE_FACTOR)
|
||||
overlap_x = LATENT_SCALE_FACTOR * math.ceil(
|
||||
int((image_width / num_tiles_x) * overlap_fraction) / LATENT_SCALE_FACTOR
|
||||
)
|
||||
overlap_y = LATENT_SCALE_FACTOR * math.ceil(
|
||||
int((image_height / num_tiles_y) * overlap_fraction) / LATENT_SCALE_FACTOR
|
||||
)
|
||||
|
||||
# Calculate the tile size based on the number of tiles and overlap, and ensure it's divisible by 8 (rounding down)
|
||||
tile_size_x = LATENT_SCALE_FACTOR * math.floor(
|
||||
@ -184,11 +188,11 @@ def calc_tiles_min_overlap(
|
||||
Returns:
|
||||
list[Tile]: A list of tiles that cover the image shape. Ordered from left-to-right, top-to-bottom.
|
||||
"""
|
||||
assert image_height >= tile_height
|
||||
assert image_width >= tile_width
|
||||
|
||||
assert min_overlap < tile_height
|
||||
assert min_overlap < tile_width
|
||||
|
||||
# The If Else catches the case when the tile size is larger than the images size and just clips the number of tiles to 1
|
||||
num_tiles_x = math.ceil((image_width - min_overlap) / (tile_width - min_overlap)) if tile_width < image_width else 1
|
||||
num_tiles_y = (
|
||||
math.ceil((image_height - min_overlap) / (tile_height - min_overlap)) if tile_height < image_height else 1
|
||||
@ -200,14 +204,10 @@ def calc_tiles_min_overlap(
|
||||
# Calculate tile coordinates. (Ignore overlap values for now.)
|
||||
for tile_idx_y in range(num_tiles_y):
|
||||
top = (tile_idx_y * (image_height - tile_height)) // (num_tiles_y - 1) if num_tiles_y > 1 else 0
|
||||
if round_to_8:
|
||||
top = LATENT_SCALE_FACTOR * (top // LATENT_SCALE_FACTOR)
|
||||
bottom = top + tile_height
|
||||
|
||||
for tile_idx_x in range(num_tiles_x):
|
||||
left = (tile_idx_x * (image_width - tile_width)) // (num_tiles_x - 1) if num_tiles_x > 1 else 0
|
||||
if round_to_8:
|
||||
left = LATENT_SCALE_FACTOR * (left // LATENT_SCALE_FACTOR)
|
||||
right = left + tile_width
|
||||
|
||||
tile = Tile(
|
||||
|
@ -74,6 +74,9 @@ def seam_blend(ia1: np.ndarray, ia2: np.ndarray, blend_amount: int, x_seam: bool
|
||||
return result
|
||||
|
||||
# Assume RGB and convert to grey
|
||||
# Could offer other options for the luminance conversion
|
||||
# BT.709 [0.2126, 0.7152, 0.0722], BT.2020 [0.2627, 0.6780, 0.0593])
|
||||
# it might not have a huge impact due to the blur that is applied over the seam
|
||||
iag1 = np.dot(ia1, [0.2989, 0.5870, 0.1140]) # BT.601 perceived brightness
|
||||
iag2 = np.dot(ia2, [0.2989, 0.5870, 0.1140])
|
||||
|
||||
@ -92,6 +95,7 @@ def seam_blend(ia1: np.ndarray, ia2: np.ndarray, blend_amount: int, x_seam: bool
|
||||
min_x = gutter
|
||||
|
||||
# Calc the energy in the difference
|
||||
# Could offer different energy calculations e.g. Sobel or Scharr
|
||||
energy = np.abs(np.gradient(ia, axis=0)) + np.abs(np.gradient(ia, axis=1))
|
||||
|
||||
# Find the starting position of the seam
|
||||
@ -107,6 +111,7 @@ def seam_blend(ia1: np.ndarray, ia2: np.ndarray, blend_amount: int, x_seam: bool
|
||||
lowest_energy_line[max_y - 1] = np.argmin(res[max_y - 1, min_x : max_x - 1])
|
||||
|
||||
# Calc the path of the seam
|
||||
# could offer options for larger search than just 1 pixel by adjusting lpos and rpos
|
||||
for ypos in range(max_y - 2, -1, -1):
|
||||
lowest_pos = lowest_energy_line[ypos + 1]
|
||||
lpos = lowest_pos - 1
|
||||
|
@ -371,8 +371,8 @@ def test_calc_tiles_min_overlap_difficult_size_div8():
|
||||
(128, 128, 128, 128, 127, False), # OK
|
||||
(128, 128, 128, 128, 0, False), # OK
|
||||
(128, 128, 64, 64, 0, False), # OK
|
||||
(128, 128, 129, 128, 0, True), # tile_height exceeds image_height.
|
||||
(128, 128, 128, 129, 0, True), # tile_width exceeds image_width.
|
||||
(128, 128, 129, 128, 0, False), # tile_height exceeds image_height defaults to 1 tile.
|
||||
(128, 128, 128, 129, 0, False), # tile_width exceeds image_width defaults to 1 tile.
|
||||
(128, 128, 64, 128, 64, True), # overlap equals tile_height.
|
||||
(128, 128, 128, 64, 64, True), # overlap equals tile_width.
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user