first commit

This commit is contained in:
Yiheng
2024-05-24 18:51:50 +08:00
commit fa7ade0f75
2 changed files with 136 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
from .image_kmeans_filter import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
+133
View File
@@ -0,0 +1,133 @@
import numpy as np
from PIL import Image
import torch
import cv2
# Tensor to PIL
def tensor2pil(image):
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
# PIL to Tensor
def pil2tensor(image):
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
class ImageKmeansFilter:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": ("IMAGE", ),
"k": ("INT", {"default": 18}),
},
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = "apply_kmeans_filter"
CATEGORY = "Tools"
def reduce_colors_kmeans(image, n_clusters=8):
"""
使用 K-means 聚类算法减少图像颜色。
Args:
image: PIL Image 对象.
n_clusters: 聚类数量,即最终图像的颜色数量.
Returns:
颜色减少后的 PIL Image 对象.
"""
# 将 PIL Image 转换为 NumPy 数组
img = np.array(image)
# OpenCV 期望颜色通道顺序为 BGR,PIL 使用 RGB
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
# 将图像转换为二维数组,每行代表一个像素
pixels = img.reshape((-1, 3))
# 将像素数据类型转换为 float32
pixels = np.float32(pixels)
# 定义 K-means 聚类参数
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# 执行 K-means 聚类
_, labels, centers = cv2.kmeans(pixels, n_clusters, None, criteria, 10, cv2.KMEANS_PP_CENTERS)
# 将聚类中心转换为 uint8 类型
centers = np.uint8(centers)
# 使用聚类标签重建图像
reduced_image = centers[labels.flatten()]
# 将图像 reshape 回原始尺寸
reduced_image = reduced_image.reshape(img.shape)
# 将图像转换回 RGB 色彩空间
reduced_image = cv2.cvtColor(reduced_image, cv2.COLOR_BGR2RGB)
# 将 NumPy 数组转换回 PIL Image
reduced_image = Image.fromarray(reduced_image)
return reduced_image
def apply_kmeans_filter(self, image, k):
tensors = []
if len(image) > 1:
for img in image:
pil_image = None
# PIL Image
pil_image = tensor2pil(img)
# Apply Median Fliter
new_img = self.reduce_colors_kmeans(pil_image, k)
# Output image
out_image = (pil2tensor(new_img) if pil_image else img)
tensors.append(out_image)
tensors = torch.cat(tensors, dim=0)
else:
pil_image = None
img = image
# PIL Image
pil_image = tensor2pil(img)
# Apply Median Fliter
new_img = self.reduce_colors_kmeans(pil_image, k)
# Output image
out_image = (pil2tensor(new_img) if pil_image else img)
tensors = out_image
return (tensors, )
# Set the web directory, any .js file in that directory will be loaded by the frontend as a frontend extension
# WEB_DIRECTORY = "./somejs"
# A dictionary that contains all nodes you want to export with their names
# NOTE: names should be globally unique
NODE_CLASS_MAPPINGS = {
"ImageKmeansFilter": ImageKmeansFilter
}
# A dictionary that contains the friendly/humanly readable titles for the nodes
NODE_DISPLAY_NAME_MAPPINGS = {
"ImageKmeansFilter": "Apply Kmeans Filter"
}