FastSplatStyler / utils.py
incrl's picture
Initial Upload (attempt 2)
5b557cf verified
import torch
import numpy as np
from imageio import imread, imwrite
from skimage.transform import resize
import os
from scipy.ndimage import binary_erosion, binary_dilation, distance_transform_cdt, grey_dilation
import matplotlib.pyplot as plt
import json
def ensure_dir(file_path):
directory = os.path.dirname(file_path)
if not os.path.exists(directory):
os.makedirs(directory)
def loadJSON(file):
with open(file) as f:
result = json.load(f)
return result
def saveJSON(data,file):
with open(file, 'w') as outfile:
json.dump(data, outfile)
def loadImage(filename, asTensor = True, imagenet_mean = False, shape = None):
image = imread(filename)
if image.ndim == 2:
image = np.stack((image,image,image),axis=2)
image = image[:,:,:3]/255 # No alpha channels
if shape is not None:
image = resize(image, shape)
if imagenet_mean:
mean = np.array([0.485, 0.456, 0.406])
std = np.array([0.229, 0.224, 0.225])
image = (image - mean)/std
# Reorganize for torch
if asTensor:
image = np.transpose(image,(2,0,1))
image = np.expand_dims(image,axis=0)
return torch.tensor(image,dtype=torch.float)
else:
return image
def loadMask(filename, asTensor = True, shape = None):
image = imread(filename)
if image.ndim == 3:
image = image[:,:,0]
if shape is not None:
image = resize(image, shape)
mask = image >= 128
# Reorganize for torch
if asTensor:
mask = np.expand_dims(mask,axis=0)
return torch.tensor(mask,dtype=torch.bool)
else:
return mask
def toTensor(numpy_data):
image = np.transpose(numpy_data,(2,0,1))
image = np.expand_dims(image,axis=0)
return torch.tensor(image,dtype=torch.float)
def toTorch(numpy_data):
return toTensor(numpy_data)
def toNumpy(tensor, permute=True):
image = np.squeeze(tensor.detach().clone().cpu().numpy())
if permute:
image = np.transpose(image,(1,2,0))
return image
def makeCanvas(x,original):
if torch.is_tensor(original):
original = toNumpy(original)
if x.ndim > 1:
if x.shape[-1] == original.shape[-1]:
return original
rows,cols,_ = original.shape
if x.ndim > 1:
return np.zeros((rows,cols,x.shape[-1]))
else:
return np.zeros((rows,cols))
def reverse_selection(s):
return [0, 5, 6, 7, 8, 1, 2, 3, 4][s]
def extrapolate_image(im, numpy = False):
rows,cols,ch = im.shape
if numpy:
result = np.zeros((rows+1,cols+1,ch))
else:
result = torch.zeros((rows+1,cols+1,ch))
result[:rows,:cols] = im
# Extrapolate last column
result[:rows,cols] = 2*result[:rows,cols-1] - result[:rows,cols-2]
# Extrapolate last row
result[rows] = 2*result[rows-1] - result[rows-2]
return result
def bilinear_interpolate(im, x, y, numpy = False):
if numpy:
im = extrapolate_image(im,numpy=True)
x = np.asarray(x)
y = np.asarray(y)
x0 = np.floor(x).astype(int)
x1 = x0 + 1
y0 = np.floor(y).astype(int)
y1 = y0 + 1
x0 = np.clip(x0, 0, im.shape[1]-1);
x1 = np.clip(x1, 0, im.shape[1]-1);
y0 = np.clip(y0, 0, im.shape[0]-1);
y1 = np.clip(y1, 0, im.shape[0]-1);
Ia = im[ y0, x0 ]
Ib = im[ y1, x0 ]
Ic = im[ y0, x1 ]
Id = im[ y1, x1 ]
wa = (x1-x) * (y1-y)
wb = (x1-x) * (y-y0)
wc = (x-x0) * (y1-y)
wd = (x-x0) * (y-y0)
wa = np.expand_dims(wa,axis=1)
wb = np.expand_dims(wb,axis=1)
wc = np.expand_dims(wc,axis=1)
wd = np.expand_dims(wd,axis=1)
else:
im = im[0].permute((1,2,0)).float()
im = extrapolate_image(im)
x0 = torch.floor(x).long()
x1 = x0 + 1
y0 = torch.floor(y).long()
y1 = y0 + 1
x0 = torch.clip(x0, 0, im.shape[1]-1);
x1 = torch.clip(x1, 0, im.shape[1]-1);
y0 = torch.clip(y0, 0, im.shape[0]-1);
y1 = torch.clip(y1, 0, im.shape[0]-1);
Ia = im[y0,x0]
Ib = im[y1,x0]
Ic = im[y0,x1]
Id = im[y1,x1]
wa = (x1-x) * (y1-y)
wb = (x1-x) * (y-y0)
wc = (x-x0) * (y1-y)
wd = (x-x0) * (y-y0)
wa = torch.unsqueeze(wa,dim=1)
wb = torch.unsqueeze(wb,dim=1)
wc = torch.unsqueeze(wc,dim=1)
wd = torch.unsqueeze(wd,dim=1)
return wa*Ia + wb*Ib + wc*Ic + wd*Id
def cosineWeighting(rows,cols):
phi_vals = np.linspace(-np.pi/2,np.pi/2,rows)
cosines = np.cos(phi_vals)
result = np.zeros((rows,cols))
for i in range(rows):
result[i, :] = cosines[i]
return result
def cross(a,b):
# Computes the cross product of two torch tensors
out_i = a[:,1]*b[:,2] - a[:,2]*b[:,1]
out_j = a[:,2]*b[:,0] - a[:,0]*b[:,2]
out_k = a[:,0]*b[:,1] - a[:,1]*b[:,0]
out = torch.stack((out_i,out_j,out_k),dim=1)
return out
def interpolatePointCloud2D(source_points,source_features,target_x,target_y,extrapolate=True):
#from scipy.interpolate import LinearNDInterpolator as Interpolater
from scipy.interpolate import CloughTocher2DInterpolator as Interpolater
from scipy.interpolate import NearestNDInterpolator as Extrapolater
interp = Interpolater(source_points,source_features)
result = interp(target_x,target_y)
chk = np.isnan(result)
if chk.any() and extrapolate:
nearest = Extrapolater(source_points,source_features)
return np.where(chk, nearest(target_x,target_y), result)
else:
result = np.where(chk, 0, result)
return result