195 lines
4.8 KiB
Python
195 lines
4.8 KiB
Python
import torch
|
|
import cv2
|
|
import numpy as np
|
|
from PIL import Image, ImageFilter
|
|
|
|
LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
|
|
|
|
|
|
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])
|
|
combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
|
|
|
|
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)
|
|
combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
|
|
|
|
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)
|
|
cv2_mask = cv2.bitwise_and(cv2_mask1, cv2_mask2)
|
|
mask = torch.from_numpy(cv2_mask)
|
|
return mask
|
|
|
|
|
|
def to_binary_mask(mask):
|
|
mask = mask.clone().cpu()
|
|
mask[mask != 0] = 1.
|
|
return mask
|
|
|
|
|
|
def dilate_mask(mask, dilation_factor, iter=1):
|
|
if dilation_factor == 0:
|
|
return mask
|
|
|
|
kernel = np.ones((dilation_factor,dilation_factor), np.uint8)
|
|
return cv2.dilate(mask, kernel, iter)
|
|
|
|
|
|
def dilate_masks(segmasks, dilation_factor, iter=1):
|
|
if dilation_factor == 0:
|
|
return segmasks
|
|
|
|
dilated_masks = []
|
|
kernel = np.ones((dilation_factor,dilation_factor), np.uint8)
|
|
for i in range(len(segmasks)):
|
|
cv2_mask = segmasks[i][1]
|
|
dilated_mask = cv2.dilate(cv2_mask, kernel, iter)
|
|
item = (segmasks[i][0], dilated_mask, segmasks[i][2])
|
|
dilated_masks.append(item)
|
|
return dilated_masks
|
|
|
|
|
|
def feather_mask(mask, thickness):
|
|
pil_mask = Image.fromarray(np.uint8(mask * 255))
|
|
|
|
# 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
|
|
cv2_mask = cv2.subtract(cv2_mask1, cv2_mask2)
|
|
mask = torch.from_numpy(cv2_mask) / 255.0
|
|
return mask
|
|
|
|
|
|
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):
|
|
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
|
|
|
|
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)
|
|
|
|
|