Spaces:
Sleeping
Sleeping
File size: 7,375 Bytes
c6147a7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | import numpy as np
import torch
def disp_color_func(disp):
"""
Based on color histogram, convert the gray disp into color disp map.
The histogram consists of 7 bins, value of each is e.g. [114.0, 185.0, 114.0, 174.0, 114.0, 185.0, 114.0]
Accumulate each bin, named cbins, and scale it to [0,1], e.g. [0.114, 0.299, 0.413, 0.587, 0.701, 0.886, 1.0]
For each value in disp, we have to find which bin it belongs to
Therefore, we have to compare it with every value in cbins
Finally, we have to get the ratio of it accounts for the bin, and then we can interpolate it with the histogram map
For example, 0.780 belongs to the 5th bin, the ratio is (0.780-0.701)/0.114,
then we can interpolate it into 3 channel with the 5th [0, 1, 0] and 6th [0, 1, 1] channel-map
Inputs:
disp: numpy array, disparity gray map in (Height * Width, 1) layout, value range [0,1]
Outputs:
disp: numpy array, disparity color map in (Height * Width, 3) layout, value range [0,1]
"""
map = np.array([
[0, 0, 0, 114],
[0, 0, 1, 185],
[1, 0, 0, 114],
[1, 0, 1, 174],
[0, 1, 0, 114],
[0, 1, 1, 185],
[1, 1, 0, 114],
[1, 1, 1, 0]
])
# grab the last element of each column and convert into float type, e.g. 114 -> 114.0
# the final result: [114.0, 185.0, 114.0, 174.0, 114.0, 185.0, 114.0]
bins = map[0:map.shape[0] - 1, map.shape[1] - 1].astype(float)
# reshape the bins from [7] into [7,1]
bins = bins.reshape((bins.shape[0], 1))
# accumulate element in bins, and get [114.0, 299.0, 413.0, 587.0, 701.0, 886.0, 1000.0]
cbins = np.cumsum(bins)
# divide the last element in cbins, e.g. 1000.0
bins = bins / cbins[cbins.shape[0] - 1]
# divide the last element of cbins, e.g. 1000.0, and reshape it, final shape [6,1]
cbins = cbins[0:cbins.shape[0] - 1] / cbins[cbins.shape[0] - 1]
cbins = cbins.reshape((cbins.shape[0], 1))
# transpose disp array, and repeat disp 6 times in axis-0, 1 times in axis-1, final shape=[6, Height*Width]
ind = np.tile(disp.T, (6, 1))
tmp = np.tile(cbins, (1, disp.size))
# get the number of disp's elements bigger than each value in cbins, and sum up the 6 numbers
b = (ind > tmp).astype(int)
s = np.sum(b, axis=0)
bins = 1 / bins
# add an element 0 ahead of cbins, [0, cbins]
t = cbins
cbins = np.zeros((cbins.size + 1, 1))
cbins[1:] = t
# get the ratio and interpolate it
disp = (disp - cbins[s]) * bins[s]
disp = map[s, 0:3] * np.tile(1 - disp, (1, 3)) + map[s + 1, 0:3] * np.tile(disp, (1, 3))
return disp
def gen_disp_error_colormap():
"""
format:[[min_error<= this_error<=max_error, RGB],
[min_error<= this_error<=max_error, RGB],
...
[min_error<= this_error<=max_error, RGB],]
unit: pixel
"""
cols = np.array(
[[0 / 3.0, 0.1875 / 3.0, 49, 54, 149],
[0.1875 / 3.0, 0.375 / 3.0, 69, 117, 180],
[0.375 / 3.0, 0.75 / 3.0, 116, 173, 209],
[0.75 / 3.0, 1.5 / 3.0, 171, 217, 233],
[1.5 / 3.0, 3 / 3.0, 224, 243, 248],
[3 / 3.0, 6 / 3.0, 254, 224, 144],
[6 / 3.0, 12 / 3.0, 253, 174, 97],
[12 / 3.0, 24 / 3.0, 244, 109, 67],
[24 / 3.0, 48 / 3.0, 215, 48, 39],
[48 / 3.0, np.inf, 165, 0, 38]], dtype=np.float32)
cols[:, 2: 5] /= 255.
return cols
error_colormap = gen_disp_error_colormap()
def disp_error_image_func(D_est_tensor, D_gt_tensor, abs_thres=3., rel_thres=0.05, dilate_radius=1):
"""
D_est_tensor: estimated disparity, BHW
D_gt_tensor: ground-truth disparity, BHW
abs_thres: abs(D_est - D_gt) > abs_thres? outliers : zeros
"""
D_gt_np = D_gt_tensor.detach().cpu().numpy()
D_est_np = D_est_tensor.detach().cpu().numpy()
B, H, W = D_gt_np.shape
# valid mask
mask = D_gt_np > 1e-3
# error in percentage. When error <= 1, the pixel is valid since <= 3px & 5%
error = np.abs(D_gt_np - D_est_np)
error[np.logical_not(mask)] = 0 # remove the invalid pixels
error[mask] = np.minimum(error[mask] / abs_thres, (error[mask] / D_gt_np[mask]) / rel_thres)
# get colormap
cols = error_colormap
# create error image
error_image = np.zeros([B, H, W, 3], dtype=np.float32)
for i in range(cols.shape[0]):
error_image[np.logical_and(error >= cols[i][0], error < cols[i][1])] = cols[i, 2:] # find out the correspondant range, give RGB values
# TODO: imdilate
# error_image = cv2.imdilate(D_err, strel('disk', dilate_radius));
# remove the color in invalid pixels
error_image[np.logical_not(mask)] = 0.
# show color tag in the top-left cornor of the image
for i in range(cols.shape[0]):
distance = 20
error_image[:, :10, i * distance:(i + 1) * distance, :] = cols[i, 2:]
return torch.from_numpy(np.ascontiguousarray(error_image.transpose([0, 3, 1, 2])))
def gen_dep_error_colormap(max_range=2):
"""
format:[[min_error<= this_error<=max_error, RGB],
[min_error<= this_error<=max_error, RGB],
...
[min_error<= this_error<=max_error, RGB],]
unit: meter
range: (0, max_range) meters
"""
max_range = max_range / 0.9
cols = np.array(
[[0.0 * max_range, 0.1 * max_range, 49, 54, 149],
[0.1 * max_range, 0.2 * max_range, 69, 117, 180],
[0.2 * max_range, 0.3 * max_range, 116, 173, 209],
[0.3 * max_range, 0.4 * max_range, 171, 217, 233],
[0.4 * max_range, 0.5 * max_range, 224, 243, 248],
[0.5 * max_range, 0.6 * max_range, 254, 224, 144],
[0.6 * max_range, 0.7 * max_range, 253, 174, 97],
[0.7 * max_range, 0.8 * max_range, 244, 109, 67],
[0.8 * max_range, 0.9 * max_range, 215, 48, 39],
[0.9 * max_range, np.inf, 165, 0, 38]], dtype=np.float32)
cols[:, 2: 5] /= 255.
return cols
dep_error_colormap = gen_dep_error_colormap(max_range=2.)
def dep_error_image_func(D_est_tensor, D_gt_tensor):
"""
D_est_tensor: estimated depth, BHW
D_gt_tensor: ground-truth depth, BHW
abs_thres: abs(D_est - D_gt) > abs_thres? outliers : zeros
"""
D_gt_np = D_gt_tensor.detach().cpu().numpy()
D_est_np = D_est_tensor.detach().cpu().numpy()
B, H, W = D_gt_np.shape
# valid mask
mask = D_gt_np > 1e-3
# error in percentage. When error <= 1, the pixel is valid since <= 3px & 5%
error = np.abs(D_gt_np - D_est_np)
error[np.logical_not(mask)] = 0 # remove the invalid pixels
# get colormap
cols = error_colormap
# create error image
error_image = np.zeros([B, H, W, 3], dtype=np.float32)
for i in range(cols.shape[0]):
error_image[np.logical_and(error >= cols[i][0], error < cols[i][1])] = cols[i, 2:] # find out the correspondant range, give RGB values
# TODO: imdilate
# error_image = cv2.imdilate(D_err, strel('disk', dilate_radius));
# remove the color in invalid pixels
error_image[np.logical_not(mask)] = 0.
# show color tag in the top-left cornor of the image
for i in range(cols.shape[0]):
distance = 20
error_image[:, :10, i * distance:(i + 1) * distance, :] = cols[i, 2:]
return torch.from_numpy(np.ascontiguousarray(error_image.transpose([0, 3, 1, 2]))) |