StupidGame's picture
Upload 1941 files
baa8e90
import torch
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFilter
import folder_paths
from . import config
LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
def pil2numpy(image):
return (np.array(image).astype(np.float32) / 255.0)[np.newaxis, :, :, :]
def pil2tensor(image):
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
def tensor2pil(image):
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
def center_of_bbox(bbox):
w, h = bbox[2] - bbox[0], bbox[3] - bbox[1]
return bbox[0] + w/2, bbox[1] + h/2
def combine_masks(masks):
if len(masks) == 0:
return None
else:
initial_cv2_mask = np.array(masks[0][1])
combined_cv2_mask = initial_cv2_mask
for i in range(1, len(masks)):
cv2_mask = np.array(masks[i][1])
if combined_cv2_mask.shape == cv2_mask.shape:
combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
else:
# do nothing - incompatible mask
pass
mask = torch.from_numpy(combined_cv2_mask)
return mask
def combine_masks2(masks):
if len(masks) == 0:
return None
else:
initial_cv2_mask = np.array(masks[0]).astype(np.uint8)
combined_cv2_mask = initial_cv2_mask
for i in range(1, len(masks)):
cv2_mask = np.array(masks[i]).astype(np.uint8)
if combined_cv2_mask.shape == cv2_mask.shape:
combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
else:
# do nothing - incompatible mask
pass
mask = torch.from_numpy(combined_cv2_mask)
return mask
def bitwise_and_masks(mask1, mask2):
mask1 = mask1.cpu()
mask2 = mask2.cpu()
cv2_mask1 = np.array(mask1)
cv2_mask2 = np.array(mask2)
if cv2_mask1.shape == cv2_mask2.shape:
cv2_mask = cv2.bitwise_and(cv2_mask1, cv2_mask2)
return torch.from_numpy(cv2_mask)
else:
# do nothing - incompatible mask shape: mostly empty mask
return mask1
def to_binary_mask(mask, threshold=0):
if len(mask.shape) == 3:
mask = mask.squeeze(0)
mask = mask.clone().cpu()
mask[mask > threshold] = 1.
mask[mask <= threshold] = 0.
return mask
def use_gpu_opencv():
return not config.get_config()['disable_gpu_opencv']
def dilate_mask(mask, dilation_factor, iter=1):
if dilation_factor == 0:
return mask
if len(mask.shape) == 3:
mask = mask.squeeze(0)
kernel = np.ones((abs(dilation_factor), abs(dilation_factor)), np.uint8)
if use_gpu_opencv():
mask = cv2.UMat(mask)
kernel = cv2.UMat(kernel)
if dilation_factor > 0:
result = cv2.dilate(mask, kernel, iter)
else:
result = cv2.erode(mask, kernel, iter)
if use_gpu_opencv():
return result.get()
else:
return result
def dilate_masks(segmasks, dilation_factor, iter=1):
if dilation_factor == 0:
return segmasks
dilated_masks = []
kernel = np.ones((abs(dilation_factor), abs(dilation_factor)), np.uint8)
if use_gpu_opencv():
kernel = cv2.UMat(kernel)
for i in range(len(segmasks)):
cv2_mask = segmasks[i][1]
if use_gpu_opencv():
cv2_mask = cv2.UMat(cv2_mask)
if dilation_factor > 0:
dilated_mask = cv2.dilate(cv2_mask, kernel, iter)
else:
dilated_mask = cv2.erode(cv2_mask, kernel, iter)
if use_gpu_opencv():
dilated_mask = dilated_mask.get()
item = (segmasks[i][0], dilated_mask, segmasks[i][2])
dilated_masks.append(item)
return dilated_masks
def feather_mask(mask, thickness, base_alpha=255):
pil_mask = Image.fromarray(np.uint8(mask * base_alpha))
# Create a feathered mask by applying a Gaussian blur to the mask
blurred_mask = pil_mask.filter(ImageFilter.GaussianBlur(thickness))
feathered_mask = Image.new("L", pil_mask.size, 0)
feathered_mask.paste(blurred_mask, (0, 0), blurred_mask)
return feathered_mask
def subtract_masks(mask1, mask2):
mask1 = mask1.cpu()
mask2 = mask2.cpu()
cv2_mask1 = np.array(mask1) * 255
cv2_mask2 = np.array(mask2) * 255
if cv2_mask1.shape == cv2_mask2.shape:
cv2_mask = cv2.subtract(cv2_mask1, cv2_mask2)
return torch.clamp(torch.from_numpy(cv2_mask) / 255.0, min=0, max=1)
else:
# do nothing - incompatible mask shape: mostly empty mask
return mask1
def add_masks(mask1, mask2):
mask1 = mask1.cpu()
mask2 = mask2.cpu()
cv2_mask1 = np.array(mask1) * 255
cv2_mask2 = np.array(mask2) * 255
if cv2_mask1.shape == cv2_mask2.shape:
cv2_mask = cv2.add(cv2_mask1, cv2_mask2)
return torch.clamp(torch.from_numpy(cv2_mask) / 255.0, min=0, max=1)
else:
# do nothing - incompatible mask shape: mostly empty mask
return mask1
def normalize_region(limit, startp, size):
if startp < 0:
new_endp = min(limit, size)
new_startp = 0
elif startp + size > limit:
new_startp = max(0, limit - size)
new_endp = limit
else:
new_startp = startp
new_endp = min(limit, startp+size)
return int(new_startp), int(new_endp)
def make_crop_region(w, h, bbox, crop_factor, crop_min_size=None):
x1 = bbox[0]
y1 = bbox[1]
x2 = bbox[2]
y2 = bbox[3]
bbox_w = x2 - x1
bbox_h = y2 - y1
crop_w = bbox_w * crop_factor
crop_h = bbox_h * crop_factor
if crop_min_size is not None:
crop_w = max(crop_min_size, crop_w)
crop_h = max(crop_min_size, crop_h)
kernel_x = x1 + bbox_w / 2
kernel_y = y1 + bbox_h / 2
new_x1 = int(kernel_x - crop_w / 2)
new_y1 = int(kernel_y - crop_h / 2)
# make sure position in (w,h)
new_x1, new_x2 = normalize_region(w, new_x1, crop_w)
new_y1, new_y2 = normalize_region(h, new_y1, crop_h)
return [new_x1, new_y1, new_x2, new_y2]
def crop_ndarray4(npimg, crop_region):
x1 = crop_region[0]
y1 = crop_region[1]
x2 = crop_region[2]
y2 = crop_region[3]
cropped = npimg[:, y1:y2, x1:x2, :]
return cropped
def crop_ndarray2(npimg, crop_region):
x1 = crop_region[0]
y1 = crop_region[1]
x2 = crop_region[2]
y2 = crop_region[3]
cropped = npimg[y1:y2, x1:x2]
return cropped
def crop_image(image, crop_region):
return crop_ndarray4(np.array(image), crop_region)
def to_latent_image(pixels, vae):
x = pixels.shape[1]
y = pixels.shape[2]
if pixels.shape[1] != x or pixels.shape[2] != y:
pixels = pixels[:, :x, :y, :]
t = vae.encode(pixels[:, :, :, :3])
return {"samples": t}
def scale_tensor(w, h, image):
image = tensor2pil(image)
scaled_image = image.resize((w, h), resample=LANCZOS)
return pil2tensor(scaled_image)
def scale_tensor_and_to_pil(w, h, image):
image = tensor2pil(image)
return image.resize((w, h), resample=LANCZOS)
def empty_pil_tensor(w=64, h=64):
image = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(image)
draw.rectangle((0, 0, w-1, h-1), fill=(0, 0, 0))
return pil2tensor(image)
class NonListIterable:
def __init__(self, data):
self.data = data
def __getitem__(self, index):
return self.data[index]
# author: Trung0246
def add_folder_path_and_extensions(folder_name, full_folder_paths, extensions):
# Iterate over the list of full folder paths
for full_folder_path in full_folder_paths:
# Use the provided function to add each model folder path
folder_paths.add_model_folder_path(folder_name, full_folder_path)
# Now handle the extensions. If the folder name already exists, update the extensions
if folder_name in folder_paths.folder_names_and_paths:
# Unpack the current paths and extensions
current_paths, current_extensions = folder_paths.folder_names_and_paths[folder_name]
# Update the extensions set with the new extensions
updated_extensions = current_extensions | extensions
# Reassign the updated tuple back to the dictionary
folder_paths.folder_names_and_paths[folder_name] = (current_paths, updated_extensions)
else:
# If the folder name was not present, add_model_folder_path would have added it with the last path
# Now we just need to update the set of extensions as it would be an empty set
# Also ensure that all paths are included (since add_model_folder_path adds only one path at a time)
folder_paths.folder_names_and_paths[folder_name] = (full_folder_paths, extensions)
# wildcard trick is taken from pythongossss's
class AnyType(str):
def __ne__(self, __value: object) -> bool:
return False
any_typ = AnyType("*")