Add FloodFill node

This commit is contained in:
nkchocoai
2024-02-12 15:05:44 +09:00
parent 00bc634a7c
commit 967fa13f43
4 changed files with 1985 additions and 2 deletions
+3 -1
View File
@@ -1,13 +1,14 @@
from .py.node.calc_max_font_size import CalcMaxFontSize
from .py.node.segs_to_region import SegsToRegion
from .py.node.extract_dominant_color import ExtractDominantColor
from .py.node.colors import GetComplementaryColor
from .py.node.colors import GetComplementaryColor, FloodFill
NODE_CLASS_MAPPINGS = {
"SegsToRegion": SegsToRegion,
"CalcMaxFontSize": CalcMaxFontSize,
"ExtractDominantColor": ExtractDominantColor,
"GetComplementaryColor": GetComplementaryColor,
"TextOnSegsFloodFill": FloodFill,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -15,6 +16,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"CalcMaxFontSize": "CalcMaxFontSize",
"ExtractDominantColor": "ExtractDominantColor",
"GetComplementaryColor": "GetComplementaryColor",
"TextOnSegsFloodFill": "FloodFill",
}
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
+90 -1
View File
@@ -1,4 +1,7 @@
from PIL import ImageColor
from PIL import Image, ImageColor, ImageDraw
import numpy as np
import torch
from .base import BaseNode
@@ -37,3 +40,89 @@ class GetComplementaryColor(BaseNode):
r2, g2, b2 = ImageColor.getcolor(alt_color_code, "RGB")
return (r2, g2, b2, color_code)
class FloodFill(BaseNode):
RETURN_TYPES = ("IMAGE", "INT", "INT", "INT")
RETURN_NAMES = (
"image",
"filled_color_r",
"filled_color_g",
"filled_color_b",
)
FUNCTION = "flood_fill"
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"x": ("INT", {"default": 0, "min": 0, "max": 99999, "step": 1}),
"y": ("INT", {"default": 0, "min": 0, "max": 99999, "step": 1}),
"pick_color": ("BOOLEAN", {"default": True}),
"r": ("INT", {"default": 255, "min": 0, "max": 255, "step": 1}),
"g": ("INT", {"default": 255, "min": 0, "max": 255, "step": 1}),
"b": ("INT", {"default": 255, "min": 0, "max": 255, "step": 1}),
"threshold": ("INT", {"default": 50, "min": 0, "max": 1000, "step": 1}),
}
}
def flood_fill(self, image, x, y, pick_color, r, g, b, threshold):
p = (x, y)
i = 255.0 * image[0].cpu().numpy()
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
img = img.convert("RGB")
if pick_color:
r, g, b = img.getpixel(p)
self._flood_fill(img, p, (r, g, b), thresh=threshold)
filled_image = np.array(img).astype(np.float32) / 255.0
filled_image = torch.from_numpy(filled_image)[None,]
return filled_image, r, g, b
# refer. https://github.com/python-pillow/Pillow/blob/5d6f22da122c6620331fd11bc8fd8a88cbc11132/src/PIL/ImageDraw.py#L897
def _flood_fill(self, image, xy, value, thresh):
pixel = image.load()
x, y = xy
try:
background = pixel[x, y]
# if _color_diff(value, background) <= thresh:
# return # seed point already has fill color
pixel[x, y] = value
except (ValueError, IndexError):
return # seed point outside image
edge = {(x, y)}
# use a set to keep record of current and previous edge pixels
# to reduce memory consumption
full_edge = set()
while edge:
new_edge = set()
for x, y in edge: # 4 adjacent method
for s, t in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
# If already processed, or if a coordinate is negative, skip
if (s, t) in full_edge or s < 0 or t < 0:
continue
try:
p = pixel[s, t]
except (ValueError, IndexError):
pass
else:
full_edge.add((s, t))
fill = self._color_diff(p, background) <= thresh
if fill:
pixel[s, t] = value
new_edge.add((s, t))
full_edge = edge # discard pixels processed
edge = new_edge
# refer. https://github.com/python-pillow/Pillow/blob/5d6f22da122c6620331fd11bc8fd8a88cbc11132/src/PIL/ImageDraw.py#L1076
def _color_diff(self, color1, color2) -> float:
"""
Uses 1-norm distance to calculate difference between two values.
"""
if isinstance(color2, tuple):
return sum(abs(color1[i] - color2[i]) for i in range(0, len(color2)))
else:
return abs(color1 - color2)
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB