fix: compute seam positions from actual tile grid
Replicate SplitImageToTileList's get_grid_coords logic to find real overlap regions between adjacent tiles. Fixes three bugs: 1. Bands were at overlap start instead of center (off by overlap/2) 2. Spurious bands generated beyond the actual tile grid 3. Edge tile seams placed at wrong position (ignoring boundary shift) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,27 +26,45 @@ class GenerateSeamMask:
|
||||
CATEGORY = "image/upscaling"
|
||||
DESCRIPTION = "Generates a mask image with white bands at tile seam positions. Used for targeted seam fix denoising."
|
||||
|
||||
@staticmethod
|
||||
def _get_tile_positions(length, tile_size, overlap):
|
||||
"""Compute 1D tile start/end positions, matching SplitImageToTileList's get_grid_coords."""
|
||||
stride = max(1, tile_size - overlap)
|
||||
positions = []
|
||||
p = 0
|
||||
while p < length:
|
||||
p_end = min(p + tile_size, length)
|
||||
p_start = max(0, p_end - tile_size)
|
||||
positions.append((p_start, p_end))
|
||||
if p_end >= length:
|
||||
break
|
||||
p += stride
|
||||
return positions
|
||||
|
||||
def generate(self, image_width, image_height, tile_width, tile_height, overlap, seam_width):
|
||||
mask = torch.zeros(1, image_height, image_width, 3)
|
||||
|
||||
stride_x = max(1, tile_width - overlap)
|
||||
stride_y = max(1, tile_height - overlap)
|
||||
half_w = seam_width // 2
|
||||
|
||||
# Vertical seam bands
|
||||
x = stride_x
|
||||
while x < image_width:
|
||||
x_start = max(0, x - half_w)
|
||||
x_end = min(image_width, x + half_w)
|
||||
mask[:, :, x_start:x_end, :] = 1.0
|
||||
x += stride_x
|
||||
# Compute actual tile grids (same logic as SplitImageToTileList)
|
||||
x_tiles = self._get_tile_positions(image_width, tile_width, overlap)
|
||||
y_tiles = self._get_tile_positions(image_height, tile_height, overlap)
|
||||
|
||||
# Horizontal seam bands
|
||||
y = stride_y
|
||||
while y < image_height:
|
||||
y_start = max(0, y - half_w)
|
||||
y_end = min(image_height, y + half_w)
|
||||
# Vertical seam bands (between horizontally adjacent tiles)
|
||||
for i in range(len(x_tiles) - 1):
|
||||
ovl_start = max(x_tiles[i][0], x_tiles[i + 1][0])
|
||||
ovl_end = min(x_tiles[i][1], x_tiles[i + 1][1])
|
||||
center = (ovl_start + ovl_end) // 2
|
||||
x_start = max(0, center - half_w)
|
||||
x_end = min(image_width, center + half_w)
|
||||
mask[:, :, x_start:x_end, :] = 1.0
|
||||
|
||||
# Horizontal seam bands (between vertically adjacent tiles)
|
||||
for i in range(len(y_tiles) - 1):
|
||||
ovl_start = max(y_tiles[i][0], y_tiles[i + 1][0])
|
||||
ovl_end = min(y_tiles[i][1], y_tiles[i + 1][1])
|
||||
center = (ovl_start + ovl_end) // 2
|
||||
y_start = max(0, center - half_w)
|
||||
y_end = min(image_height, center + half_w)
|
||||
mask[:, y_start:y_end, :, :] = 1.0
|
||||
y += stride_y
|
||||
|
||||
return (mask,)
|
||||
|
||||
Reference in New Issue
Block a user