Original Matlab code https://cs.nyu.edu/~silberman/datasets/nyudepthv2.html
December 17, 2018 ยท View on GitHub
Python port of depth filling code from NYU toolbox
Speed needs to be improved
Uses 'pypardiso' solver
import scipy import skimage import numpy as np from pypardiso import spsolve from PIL import Image
fill_depth_colorization.m
Preprocesses the kinect depth image using a gray scale version of the
RGB image as a weighting for the smoothing. This code is a slight
adaptation of Anat Levin's colorization code:
See: www.cs.huji.ac.il/~yweiss/Colorization/
Args:
imgRgb - HxWx3 matrix, the rgb image for the current frame. This must
be between 0 and 1.
imgDepth - HxW matrix, the depth image for the current frame in
absolute (meters) space.
alpha - a penalty value between 0 and 1 for the current depth values.
def fill_depth_colorization(imgRgb=None, imgDepthInput=None, alpha=1): imgIsNoise = imgDepthInput == 0 maxImgAbsDepth = np.max(imgDepthInput) imgDepth = imgDepthInput / maxImgAbsDepth imgDepth[imgDepth > 1] = 1 (H, W) = imgDepth.shape numPix = H * W indsM = np.arange(numPix).reshape((W, H)).transpose() knownValMask = (imgIsNoise == False).astype(int) grayImg = skimage.color.rgb2gray(imgRgb) winRad = 1 len_ = 0 absImgNdx = 0 len_window = (2 * winRad + 1) ** 2 len_zeros = numPix * len_window
cols = np.zeros(len_zeros) - 1
rows = np.zeros(len_zeros) - 1
vals = np.zeros(len_zeros) - 1
gvals = np.zeros(len_window) - 1
for j in range(W):
for i in range(H):
nWin = 0
for ii in range(max(0, i - winRad), min(i + winRad + 1, H)):
for jj in range(max(0, j - winRad), min(j + winRad + 1, W)):
if ii == i and jj == j:
continue
rows[len_] = absImgNdx
cols[len_] = indsM[ii, jj]
gvals[nWin] = grayImg[ii, jj]
len_ = len_ + 1
nWin = nWin + 1
curVal = grayImg[i, j]
gvals[nWin] = curVal
c_var = np.mean((gvals[:nWin + 1] - np.mean(gvals[:nWin+ 1])) ** 2)
csig = c_var * 0.6
mgv = np.min((gvals[:nWin] - curVal) ** 2)
if csig < -mgv / np.log(0.01):
csig = -mgv / np.log(0.01)
if csig < 2e-06:
csig = 2e-06
gvals[:nWin] = np.exp(-(gvals[:nWin] - curVal) ** 2 / csig)
gvals[:nWin] = gvals[:nWin] / sum(gvals[:nWin])
vals[len_ - nWin:len_] = -gvals[:nWin]
# Now the self-reference (along the diagonal).
rows[len_] = absImgNdx
cols[len_] = absImgNdx
vals[len_] = 1 # sum(gvals(1:nWin))
len_ = len_ + 1
absImgNdx = absImgNdx + 1
vals = vals[:len_]
cols = cols[:len_]
rows = rows[:len_]
A = scipy.sparse.csr_matrix((vals, (rows, cols)), (numPix, numPix))
rows = np.arange(0, numPix)
cols = np.arange(0, numPix)
vals = (knownValMask * alpha).transpose().reshape(numPix)
G = scipy.sparse.csr_matrix((vals, (rows, cols)), (numPix, numPix))
A = A + G
b = np.multiply(vals.reshape(numPix), imgDepth.flatten('F'))
#print ('Solving system..')
new_vals = spsolve(A, b)
new_vals = np.reshape(new_vals, (H, W), 'F')
#print ('Done.')
denoisedDepthImg = new_vals * maxImgAbsDepth
output = denoisedDepthImg.reshape((H, W)).astype('float32')
output = np.multiply(output, (1-knownValMask)) + imgDepthInput
return output