DvD / datasets /util.py
hanquansanren's picture
Add application file
05fb4ab
import cv2
import numpy as np
import torch
from packaging import version
def define_mask_zero_borders(image, epsilon=1e-6):
"""Computes the binary mask, equal to 0 when image is 0 and 1 otherwise."""
if isinstance(image, np.ndarray):
if len(image.shape) == 4:
if image.shape[1] == 3:
# image b, 3, H, W
image = image.transpose(0, 2, 3, 1)
# image is b, H, W, 3
occ_mask = np.logical_and(np.logical_and(image[:, :, :, 0] < epsilon,
image[:, :, :, 1] < epsilon),
image[:, :, :, 2] < epsilon)
else:
if image.shape[0] == 3:
# image 3, H, W
image = image.transpose(1, 2, 0)
# image is H, W, 3
occ_mask = np.logical_and(np.logical_and(image[:, :, 0] < epsilon,
image[:, :, 1] < epsilon),
image[:, :, 2] < epsilon)
mask = ~occ_mask
mask = mask.astype(np.bool) if version.parse(torch.__version__) >= version.parse("1.1") else mask.astype(np.uint8)
else:
# torch tensor
if len(image.shape) == 4:
if image.shape[1] == 3:
# image b, 3, H, W
image = image.permute(0, 2, 3, 1)
occ_mask = image[:, :, :, 0].le(epsilon) & image[:, :, :, 1].le(epsilon) & image[:, :, :, 2].le(epsilon)
else:
if image.shape[0] == 3:
# image 3, H, W
image = image.permute(1, 2, 0)
occ_mask = image[:, :, 0].le(epsilon) & image[:, :, 1].le(epsilon) & image[:, :, 2].le(epsilon)
mask = ~occ_mask
mask = mask.bool() if version.parse(torch.__version__) >= version.parse("1.1") else mask.byte()
return mask
def split2list(images, split, default_split=0.9):
if isinstance(split, str):
with open(split) as f:
split_values = [x.strip() == '1' for x in f.readlines()]
assert(len(images) == len(split_values))
elif split is None:
split_values = np.random.uniform(0, 1, len(images)) < default_split
else:
try:
split = float(split)
except TypeError:
print("Invalid Split value, it must be either a filepath or a float")
raise
split_values = np.random.uniform(0,1,len(images)) < split
train_samples = [sample for sample, split in zip(images, split_values) if split]
test_samples = [sample for sample, split in zip(images, split_values) if not split]
return train_samples, test_samples
def resize_keeping_aspect_ratio(image, size):
h, w, _ = image.shape
if h > w:
ratio = float(size) / float(h)
else:
ratio = float(size) / float(w)
new_h = int(h*ratio)
new_w = int(w*ratio)
return cv2.resize(image, (new_w, new_h)), ratio
def pad_to_same_shape(im1, im2):
# pad to same shape
if im1.shape[0] <= im2.shape[0]:
pad_y_1 = im2.shape[0] - im1.shape[0]
pad_y_2 = 0
else:
pad_y_1 = 0
pad_y_2 = im1.shape[0] - im2.shape[0]
if im1.shape[1] <= im2.shape[1]:
pad_x_1 = im2.shape[1] - im1.shape[1]
pad_x_2 = 0
else:
pad_x_1 = 0
pad_x_2 = im1.shape[1] - im2.shape[1]
im1 = cv2.copyMakeBorder(im1, 0, pad_y_1, 0, pad_x_1, cv2.BORDER_CONSTANT)
im2 = cv2.copyMakeBorder(im2, 0, pad_y_2, 0, pad_x_2, cv2.BORDER_CONSTANT)
shape = im1.shape
return im1, im2
def pad_to_size(im, size):
# load_size first h then w
if not isinstance(size, tuple):
size = (size, size)
# pad to same shape
if im.shape[0] < size[0]:
pad_y_1 = size[0] - im.shape[0]
else:
pad_y_1 = 0
if im.shape[1] < size[1]:
pad_x_1 = size[1] - im.shape[1]
else:
pad_x_1 = 0
im = cv2.copyMakeBorder(im, 0, pad_y_1, 0, pad_x_1, cv2.BORDER_CONSTANT)
return im
def center_pad(im, size):
# load_size first h then w
if not isinstance(size, tuple):
size = (size, size)
# pad to same shape
if im.shape[0] < size[0]:
pad_y_1 = size[0] - im.shape[0]
else:
pad_y_1 = 0
if im.shape[1] < size[1]:
pad_x_1 = size[1] - im.shape[1]
else:
pad_x_1 = 0
im = cv2.copyMakeBorder(im, pad_y_1//2, pad_y_1-pad_y_1//2, pad_x_1//2, pad_x_1-pad_x_1//2, cv2.BORDER_CONSTANT)
return im
def center_crop(img, size):
"""
Get the center crop of the input image
Args:
img: input image [HxWxC]
size: load_size of the center crop (tuple) (width, height)
Output:
img_pad: center crop
x, y: coordinates of the crop
"""
if not isinstance(size, tuple):
size = (size, size)
#load_size is W,H
img = img.copy()
h, w = img.shape[:2]
pad_w = 0
pad_h = 0
if w < size[0]:
pad_w = np.int(np.ceil((size[0] - w) / 2))
if h < size[1]:
pad_h = np.int(np.ceil((size[1] - h) / 2))
img_pad = cv2.copyMakeBorder(img,
pad_h,
pad_h,
pad_w,
pad_w,
cv2.BORDER_CONSTANT,
value=[0, 0, 0])
h, w = img_pad.shape[:2]
x1 = w // 2 - size[0] // 2
y1 = h // 2 - size[1] // 2
img_pad = img_pad[y1:y1 + size[1], x1:x1 + size[0], :]
return img_pad, x1, y1
def crop(img, size, x1, y1):
"""
Get the center crop of the input image
Args:
img: input image [HxWxC]
size: load_size of the center crop (tuple) (width, height)
Output:
img_pad: center crop
x, y: coordinates of the crop
"""
if not isinstance(size, tuple):
size = (size, size)
#load_size is W,H
img = img.copy()
h, w = img.shape[:2]
pad_w = 0
pad_h = 0
if w < (x1 + size[0]):
pad_w = np.int(np.ceil(((size[0] + x1) - w) / 2))
if h < (y1+size[1]):
pad_h = np.int(np.ceil(((y1+size[1]) - h) / 2))
img_pad = cv2.copyMakeBorder(img,
pad_h,
pad_h,
pad_w,
pad_w,
cv2.BORDER_CONSTANT,
value=[0, 0, 0])
h, w = img_pad.shape[:2]
img_pad = img_pad[y1:y1 + size[1], x1:x1 + size[0], :]
return img_pad, x1, y1