feat(api): histogram equalization and blending for highres tiling
This commit is contained in:
parent
4dc192a2c7
commit
6317094c5f
|
@ -2,7 +2,9 @@ from logging import getLogger
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from typing import List, Protocol, Tuple
|
from typing import List, Protocol, Tuple
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
from skimage.exposure import match_histograms
|
||||||
|
|
||||||
from ..params import TileOrder
|
from ..params import TileOrder
|
||||||
|
|
||||||
|
@ -38,20 +40,23 @@ def process_tile_grid(
|
||||||
tile: int,
|
tile: int,
|
||||||
scale: int,
|
scale: int,
|
||||||
filters: List[TileCallback],
|
filters: List[TileCallback],
|
||||||
|
overlap: float = 0.5,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> Image.Image:
|
) -> Image.Image:
|
||||||
width, height = source.size
|
width, height = source.size
|
||||||
image = Image.new(source.mode, (width * scale, height * scale))
|
|
||||||
|
|
||||||
tiles_x = ceil(width / tile)
|
adj_tile = tile * overlap
|
||||||
tiles_y = ceil(height / tile)
|
tiles_x = ceil(width / adj_tile)
|
||||||
|
tiles_y = ceil(height / adj_tile)
|
||||||
total = tiles_x * tiles_y
|
total = tiles_x * tiles_y
|
||||||
|
|
||||||
|
tiles: List[Tuple[int, int, Image.Image]] = []
|
||||||
|
|
||||||
for y in range(tiles_y):
|
for y in range(tiles_y):
|
||||||
for x in range(tiles_x):
|
for x in range(tiles_x):
|
||||||
idx = (y * tiles_x) + x
|
idx = (y * tiles_x) + x
|
||||||
left = x * tile
|
left = x * adj_tile
|
||||||
top = y * tile
|
top = y * adj_tile
|
||||||
logger.debug("processing tile %s of %s, %s.%s", idx + 1, total, y, x)
|
logger.debug("processing tile %s of %s, %s.%s", idx + 1, total, y, x)
|
||||||
|
|
||||||
tile_image = source.crop((left, top, left + tile, top + tile))
|
tile_image = source.crop((left, top, left + tile, top + tile))
|
||||||
|
@ -60,9 +65,24 @@ def process_tile_grid(
|
||||||
for filter in filters:
|
for filter in filters:
|
||||||
tile_image = filter(tile_image, (left, top, tile))
|
tile_image = filter(tile_image, (left, top, tile))
|
||||||
|
|
||||||
image.paste(tile_image, (left * scale, top * scale))
|
tiles.append((left, top, tile_image))
|
||||||
|
|
||||||
return image
|
scaled_size = (width * scale, height * scale, 3)
|
||||||
|
count = np.zeros_like(scaled_size)
|
||||||
|
value = np.zeros_like(scaled_size)
|
||||||
|
ref = tiles[0][2]
|
||||||
|
|
||||||
|
for left, top, tile_image in tiles:
|
||||||
|
equalized = match_histograms(tile_image, ref, channel_axis=-1)
|
||||||
|
value[
|
||||||
|
top * scale : (top + tile) * scale, left * scale : (left + tile) * scale, :
|
||||||
|
] += np.array(equalized)
|
||||||
|
count[
|
||||||
|
top * scale : (top + tile) * scale, left * scale : (left + tile) * scale, :
|
||||||
|
] += 1
|
||||||
|
|
||||||
|
pixels = np.where(count > 0, value / count, value)
|
||||||
|
return Image.fromarray(pixels)
|
||||||
|
|
||||||
|
|
||||||
def process_tile_spiral(
|
def process_tile_spiral(
|
||||||
|
|
Loading…
Reference in New Issue