Files
Fill 0bcd5c3c7c optimized + Scheduling + % complete in console
added the ability to schedule some values in the FX nodes, as well as optimized some code to make them a little faster. Iv also added a % complete print in the console so you can see how far along the processing is =)
2024-05-11 08:54:22 +09:00

79 lines
2.9 KiB
Python

import torch
import numpy as np
from PIL import Image
from colorsys import rgb_to_hsv
import sys
class FL_PixelSort:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"images": ("IMAGE",),
},
"optional": {
"direction": (["Horizontal", "Vertical"],),
"threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
"smoothing": ("FLOAT", {"default": 0.1, "min": 0.0, "max": 1.0, "step": 0.01}),
"rotation": ("INT", {"default": 0, "min": 0, "max": 3, "step": 1}),
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "pixel_sort_saturation"
CATEGORY = "🏵️Fill Nodes"
def t2p(self, t):
if t is not None:
i = 255.0 * t.cpu().numpy().squeeze()
p = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
return p
def saturation(self, pixel):
r, g, b = pixel
_, s, _ = rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)
return s
def pixel_sort_saturation(self, images, direction="Horizontal", threshold=0.5, smoothing=0.1, rotation=0):
out = []
total_images = len(images)
for i, img in enumerate(images, start=1):
p = self.t2p(img)
sorted_image = self.sort_pixels(p, self.saturation, threshold, smoothing, rotation)
o = np.array(sorted_image.convert("RGB")).astype(np.float32) / 255.0
o = torch.from_numpy(o).unsqueeze(0)
out.append(o)
# Print progress update
progress = i / total_images * 100
sys.stdout.write(f"\rProcessing images: {progress:.2f}%")
sys.stdout.flush()
# Print a new line after the progress update
print()
out = torch.cat(out, 0)
return (out,)
def sort_pixels(self, image, value, threshold, smoothing, rotation=0):
pixels = np.rot90(np.array(image), rotation)
values = np.apply_along_axis(value, 2, pixels)
edges = np.apply_along_axis(lambda row: np.convolve(row, [-1, 1], 'same'), 0, values > threshold)
edges = np.maximum(edges, 0)
edges = np.minimum(edges, 1)
edges = np.convolve(edges.flatten(), np.ones(int(smoothing * pixels.shape[1])), 'same').reshape(edges.shape)
intervals = [np.flatnonzero(row) for row in edges]
for row, key in enumerate(values):
order = np.split(key, intervals[row])
for index, interval in enumerate(order[1:]):
order[index + 1] = np.argsort(interval) + intervals[row][index]
order[0] = range(order[0].size)
order = np.concatenate(order)
for channel in range(3):
pixels[row, :, channel] = pixels[row, order.astype('uint32'), channel]
return Image.fromarray(np.rot90(pixels, -rotation))