CorpByMask node add crop_box input
This commit is contained in:
+30
-24
@@ -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]
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user