CorpByMask node add crop_box input

This commit is contained in:
chflame
2024-03-07 18:28:27 +08:00
parent 77c22b5fd7
commit a429917568
2 changed files with 120 additions and 24 deletions
+30 -24
View File
@@ -22,6 +22,7 @@ class CropByMask:
"right_reserve": ("INT", {"default": 20, "min": -9999, "max": 9999, "step": 1}),
},
"optional": {
"crop_box": ("BOX",),
}
}
@@ -32,15 +33,16 @@ class CropByMask:
OUTPUT_NODE = True
def crop_by_mask(self, image, mask_for_crop, invert_mask, detect,
top_reserve, bottom_reserve, left_reserve, right_reserve
):
top_reserve, bottom_reserve,
left_reserve, right_reserve,
crop_box=None
):
ret_images = []
ret_masks = []
l_images = []
l_masks = []
for l in image:
l_images.append(torch.unsqueeze(l, 0))
if mask_for_crop.dim() == 2:
@@ -54,28 +56,32 @@ class CropByMask:
l_masks.append(tensor2pil(torch.unsqueeze(mask_for_crop, 0)).convert('L'))
_mask = mask2image(mask_for_crop)
bluredmask = gaussian_blur(_mask, 20).convert('L')
x = 0
y = 0
width = 0
height = 0
if detect == "min_bounding_rect":
(x, y, width, height) = min_bounding_rect(bluredmask)
elif detect == "max_inscribed_rect":
(x, y, width, height) = max_inscribed_rect(bluredmask)
else:
(x, y, width, height) = mask_area(_mask)
log(f"{NODE_NAME}: Box detected. x={x},y={y},width={width},height={height}")
canvas_width, canvas_height = tensor2pil(torch.unsqueeze(image[0], 0)).convert('RGB').size
x1 = x - left_reserve if x - left_reserve > 0 else 0
y1 = y - top_reserve if y - top_reserve > 0 else 0
x2 = x + width + right_reserve if x + width + right_reserve < canvas_width else canvas_width
y2 = y + height + bottom_reserve if y + height + bottom_reserve < canvas_height else canvas_height
preview_image = tensor2pil(mask_for_crop).convert('RGB')
preview_image = draw_rect(preview_image, x, y, width, height, line_color="#F00000", line_width=(width+height)//100)
preview_image = draw_rect(preview_image, x1, y1, x2 - x1, y2 - y1,
line_color="#00F000", line_width=(width+height)//200)
crop_box = (x1, y1, x2, y2)
if crop_box is None:
bluredmask = gaussian_blur(_mask, 20).convert('L')
x = 0
y = 0
width = 0
height = 0
if detect == "min_bounding_rect":
(x, y, width, height) = min_bounding_rect(bluredmask)
elif detect == "max_inscribed_rect":
(x, y, width, height) = max_inscribed_rect(bluredmask)
else:
(x, y, width, height) = mask_area(_mask)
log(f"{NODE_NAME}: Box detected. x={x},y={y},width={width},height={height}")
canvas_width, canvas_height = tensor2pil(torch.unsqueeze(image[0], 0)).convert('RGB').size
x1 = x - left_reserve if x - left_reserve > 0 else 0
y1 = y - top_reserve if y - top_reserve > 0 else 0
x2 = x + width + right_reserve if x + width + right_reserve < canvas_width else canvas_width
y2 = y + height + bottom_reserve if y + height + bottom_reserve < canvas_height else canvas_height
crop_box = (x1, y1, x2, y2)
preview_image = draw_rect(preview_image, x, y, width, height, line_color="#F00000",
line_width=(width + height) // 100)
preview_image = draw_rect(preview_image, crop_box[0], crop_box[1],
crop_box[2] - crop_box[0], crop_box[3] - crop_box[1],
line_color="#00F000",
line_width=(crop_box[2] - crop_box[0] + crop_box[3] - crop_box[1]) // 200)
for i in range(len(l_images)):
_canvas = tensor2pil(l_images[i]).convert('RGB')
_mask = l_masks[0]
+90
View File
@@ -16,6 +16,7 @@ import scipy.ndimage
import cv2
import random
import time
from tqdm import tqdm
from functools import lru_cache
from typing import Union, List
from PIL import Image, ImageFilter, ImageChops, ImageDraw, ImageOps, ImageEnhance, ImageFont
@@ -93,6 +94,12 @@ def pil2cv2(pil_img:Image) -> np.array:
def pil2tensor(image:Image) -> torch.Tensor:
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
def np2pil(np_image:np.ndarray) -> Image:
return Image.fromarray(np_image)
def pil2np(pil_image:Image) -> np.array:
return np.ndarray(pil_image)
def np2tensor(img_np: Union[np.ndarray, List[np.ndarray]]) -> torch.Tensor:
if isinstance(img_np, list):
return torch.cat([np2tensor(img) for img in img_np], dim=0)
@@ -270,6 +277,81 @@ def blend_hard_mix(background_image:Image, layer_image:Image) -> Image:
img = img * mask
return cv22pil(ski2cv2(img))
def tuple_averge(tuples:list) -> tuple:
values = []
ret = []
for i in tuples[0]:
values.append(0)
ret.append(0)
for t in tuples:
for j in range(len(t)):
values[j] += t[j]
for k in range(len(values)):
ret[k] = int(values[k] / len(tuples))
return tuple(ret)
def get_pixel_from_round(image:Image, position:tuple) -> tuple:
(x, y) = position
width, height = image.size
pixels = []
if x > 0:
pixels.append(image.getpixel((x - 1, y)))
if y > 0:
pixels.append(image.getpixel((x - 1, y - 1)))
if y < height:
pixels.append(image.getpixel((x - 1, y + 1)))
if x < width:
pixels.append(image.getpixel((x + 1, y)))
if y > 0:
pixels.append(image.getpixel((x + 1, y - 1)))
if y < height:
pixels.append(image.getpixel((x + 1, y + 1)))
if y > 0:
pixels.append(image.getpixel((x, y-1)))
if y < height:
pixels.append(image.getpixel((x, y + 1)))
return tuple_averge(pixels)
def displace_pixel(image:Image, source_pixel:tuple, target_pixel:tuple) -> Image:
# ret_image = image.copy()
image.putpixel(target_pixel, image.getpixel(source_pixel))
return image
def displace_pixel_np(np_image:np.ndarray, source_pixel:tuple, target_pixel:tuple) -> np.ndarray:
np_image[target_pixel[1], target_pixel[0], :] = np_image[source_pixel[1], source_pixel[0], :]
return np_image
# def de_warp(image:Image) -> Image:
#
# img = pil2cv2(image)
# gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# edges = cv2.Canny(gray, 50, 150, apertureSize=3)
#
# # 霍夫变换
# lines = cv2.HoughLines(edges, 1, np.pi / 180, 0)
# rotate_angle = 0
# for rho, theta in lines[0]:
# a = np.cos(theta)
# b = np.sin(theta)
# x0 = a * rho
# y0 = b * rho
# x1 = int(x0 + 1000 * (-b))
# y1 = int(y0 + 1000 * (a))
# x2 = int(x0 - 1000 * (-b))
# y2 = int(y0 - 1000 * (a))
# if x1 == x2 or y1 == y2:
# continue
# t = float(y2 - y1) / (x2 - x1)
# rotate_angle = math.degrees(math.atan(t)) + 45
# if rotate_angle > 45:
# rotate_angle = -90 + rotate_angle
# elif rotate_angle < -45:
# rotate_angle = 90 + rotate_angle
# rotate_img = scipy.ndimage.rotate(img, rotate_angle)
# return cv22pil(rotate_img)
def shift_image(image:Image, distance_x:int, distance_y:int, background_color:str='#000000', cyclic:bool=False) -> Image:
width = image.width
height = image.height
@@ -348,6 +430,14 @@ def remove_background(image:Image, mask:Image, color:str) -> Image:
ret_image.paste(image, mask=mask)
return ret_image
def sharpen(image:Image) -> Image:
img = pil2cv2(image)
Laplace_kernel = np.array([[-1, -1, -1],
[-1, 9, -1],
[-1, -1, -1]], dtype=np.float32)
ret_image = cv2.filter2D(img, -1, Laplace_kernel)
return cv22pil(ret_image)
def gaussian_blur(image:Image, radius:int) -> Image:
# image = image.convert("RGBA")
ret_image = image.filter(ImageFilter.GaussianBlur(radius=radius))