Spaces:
Build error
Build error
add: adding model helper
Browse files- app.py +1 -0
- helpers.py +157 -190
- images/08/3-1.jpg +0 -0
app.py
CHANGED
|
@@ -74,6 +74,7 @@ We also released a <b>smaller</b> MonoScene model (Half resolution - w/o 3D CRP)
|
|
| 74 |
"""
|
| 75 |
|
| 76 |
examples = [
|
|
|
|
| 77 |
'images/08/001385.jpg',
|
| 78 |
'images/08/000295.jpg',
|
| 79 |
'images/08/002505.jpg',
|
|
|
|
| 74 |
"""
|
| 75 |
|
| 76 |
examples = [
|
| 77 |
+
'images/08/3-1.jpg',
|
| 78 |
'images/08/001385.jpg',
|
| 79 |
'images/08/000295.jpg',
|
| 80 |
'images/08/002505.jpg',
|
helpers.py
CHANGED
|
@@ -5,36 +5,37 @@ import pandas as pd
|
|
| 5 |
import plotly.express as px
|
| 6 |
import plotly.graph_objects as go
|
| 7 |
|
|
|
|
| 8 |
def read_calib(calib_path):
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
def vox2pix(cam_E, cam_k,
|
| 32 |
-
vox_origin, voxel_size,
|
| 33 |
-
img_W, img_H,
|
| 34 |
scene_size):
|
| 35 |
"""
|
| 36 |
compute the 2D projection of voxels centroids
|
| 37 |
-
|
| 38 |
Parameters:
|
| 39 |
----------
|
| 40 |
cam_E: 4x4
|
|
@@ -50,7 +51,7 @@ def vox2pix(cam_E, cam_k,
|
|
| 50 |
image height
|
| 51 |
scene_size: (3,)
|
| 52 |
scene size in meter: (51.2, 51.2, 6.4) for SemKITTI and (4.8, 4.8, 2.88) for NYUv2
|
| 53 |
-
|
| 54 |
Returns
|
| 55 |
-------
|
| 56 |
projected_pix: (N, 2)
|
|
@@ -61,23 +62,24 @@ def vox2pix(cam_E, cam_k,
|
|
| 61 |
Voxels'distance to the sensor in meter
|
| 62 |
"""
|
| 63 |
# Compute the x, y, z bounding of the scene in meter
|
| 64 |
-
vol_bnds = np.zeros((3,2))
|
| 65 |
-
vol_bnds[:,0] = vox_origin
|
| 66 |
-
vol_bnds[:,1] = vox_origin + np.array(scene_size)
|
| 67 |
|
| 68 |
# Compute the voxels centroids in lidar cooridnates
|
| 69 |
-
vol_dim = np.ceil((vol_bnds[:,1]- vol_bnds[:,0])/
|
|
|
|
| 70 |
xv, yv, zv = np.meshgrid(
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
vox_coords = np.concatenate([
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
|
| 82 |
# Project voxels'centroid from lidar coordinates to camera coordinates
|
| 83 |
cam_pts = fusion.TSDFVolume.vox2world(vox_origin, vox_coords, voxel_size)
|
|
@@ -90,16 +92,14 @@ def vox2pix(cam_E, cam_k,
|
|
| 90 |
# Eliminate pixels outside view frustum
|
| 91 |
pix_z = cam_pts[:, 2]
|
| 92 |
fov_mask = np.logical_and(pix_x >= 0,
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
|
| 99 |
return torch.from_numpy(projected_pix), torch.from_numpy(fov_mask), torch.from_numpy(pix_z)
|
| 100 |
|
| 101 |
|
| 102 |
-
|
| 103 |
def get_grid_coords(dims, resolution):
|
| 104 |
"""
|
| 105 |
:param dims: the dimensions of the grid [x, y, z] (i.e. [256, 256, 32])
|
|
@@ -125,18 +125,25 @@ def get_grid_coords(dims, resolution):
|
|
| 125 |
|
| 126 |
return coords_grid
|
| 127 |
|
|
|
|
| 128 |
def get_projections(img_W, img_H):
|
| 129 |
scale_3ds = [1, 2]
|
| 130 |
data = {}
|
| 131 |
for scale_3d in scale_3ds:
|
| 132 |
-
scene_size = (
|
| 133 |
-
vox_origin = np.array([0, -
|
| 134 |
-
voxel_size = 0.
|
| 135 |
-
|
| 136 |
-
calib = read_calib("calib.txt")
|
| 137 |
-
cam_k =
|
| 138 |
-
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
# compute the 3D-2D mapping
|
| 141 |
projected_pix, fov_mask, pix_z = vox2pix(
|
| 142 |
T_velo_2_cam,
|
|
@@ -146,26 +153,27 @@ def get_projections(img_W, img_H):
|
|
| 146 |
img_W,
|
| 147 |
img_H,
|
| 148 |
scene_size,
|
| 149 |
-
)
|
| 150 |
|
| 151 |
data["projected_pix_{}".format(scale_3d)] = projected_pix
|
| 152 |
data["pix_z_{}".format(scale_3d)] = pix_z
|
| 153 |
-
data["fov_mask_{}".format(scale_3d)] = fov_mask
|
| 154 |
return data
|
| 155 |
|
| 156 |
|
| 157 |
def majority_pooling(grid, k_size=2):
|
| 158 |
result = np.zeros(
|
| 159 |
-
(grid.shape[0] // k_size, grid.shape[1] //
|
|
|
|
| 160 |
)
|
| 161 |
for xx in range(0, int(np.floor(grid.shape[0] / k_size))):
|
| 162 |
for yy in range(0, int(np.floor(grid.shape[1] / k_size))):
|
| 163 |
for zz in range(0, int(np.floor(grid.shape[2] / k_size))):
|
| 164 |
|
| 165 |
sub_m = grid[
|
| 166 |
-
(xx * k_size)
|
| 167 |
-
(yy * k_size)
|
| 168 |
-
(zz * k_size)
|
| 169 |
]
|
| 170 |
unique, counts = np.unique(sub_m, return_counts=True)
|
| 171 |
if True in ((unique != 0) & (unique != 255)):
|
|
@@ -181,156 +189,115 @@ def majority_pooling(grid, k_size=2):
|
|
| 181 |
return result
|
| 182 |
|
| 183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
def draw(
|
| 185 |
voxels,
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
#
|
| 190 |
-
# f,
|
| 191 |
-
voxel_size=0.4,
|
| 192 |
-
# d=7, # 7m - determine the size of the mesh representing the camera
|
| 193 |
):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
|
| 195 |
-
fov_mask = fov_mask.reshape(-1)
|
| 196 |
# Compute the voxels coordinates
|
| 197 |
grid_coords = get_grid_coords(
|
| 198 |
-
[voxels.shape[0], voxels.shape[
|
| 199 |
)
|
| 200 |
|
| 201 |
-
|
| 202 |
# Attach the predicted class to every voxel
|
| 203 |
-
grid_coords = np.vstack(
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
fov_grid_coords = grid_coords[fov_mask, :]
|
| 207 |
-
|
| 208 |
-
# Get the voxels outside FOV
|
| 209 |
-
outfov_grid_coords = grid_coords[~fov_mask, :]
|
| 210 |
|
| 211 |
# Remove empty and unknown voxels
|
| 212 |
-
|
| 213 |
-
(fov_grid_coords[:, 3] > 0) & (fov_grid_coords[:, 3] < 255), :
|
| 214 |
-
]
|
| 215 |
-
# print(np.unique(fov_voxels[:, 3], return_counts=True))
|
| 216 |
-
outfov_voxels = outfov_grid_coords[
|
| 217 |
-
(outfov_grid_coords[:, 3] > 0) & (outfov_grid_coords[:, 3] < 255), :
|
| 218 |
-
]
|
| 219 |
-
|
| 220 |
-
# figure = mlab.figure(size=(1400, 1400), bgcolor=(1, 1, 1))
|
| 221 |
colors = np.array(
|
| 222 |
[
|
| 223 |
-
[
|
| 224 |
-
[
|
| 225 |
-
[
|
| 226 |
-
[
|
| 227 |
-
[
|
| 228 |
-
[
|
| 229 |
-
[255,
|
| 230 |
-
[
|
| 231 |
-
[
|
| 232 |
-
[
|
| 233 |
-
[255,
|
| 234 |
-
[
|
| 235 |
-
[
|
| 236 |
-
[255, 200, 0],
|
| 237 |
-
[255, 120, 50],
|
| 238 |
-
[0, 175, 0],
|
| 239 |
-
[135, 60, 0],
|
| 240 |
-
[150, 240, 80],
|
| 241 |
-
[255, 240, 150],
|
| 242 |
-
[255, 0, 0],
|
| 243 |
]
|
| 244 |
).astype(np.uint8)
|
| 245 |
|
| 246 |
-
pts_colors = [
|
| 247 |
-
|
|
|
|
|
|
|
| 248 |
pts_colors = pts_colors + out_fov_colors
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
y = fov_voxels[:, 1].flatten()
|
| 253 |
-
z = fov_voxels[:, 2].flatten()
|
| 254 |
-
# label = fov_voxels[:, 3].flatten()
|
| 255 |
-
fig = go.Figure(data=[go.Scatter3d(x=x, y=y, z=z,mode='markers',
|
| 256 |
-
marker=dict(
|
| 257 |
-
size=2,
|
| 258 |
color=pts_colors, # set color to an array/list of desired values
|
| 259 |
-
# colorscale='Viridis', # choose a colorscale
|
| 260 |
opacity=1.0,
|
| 261 |
symbol='square'
|
| 262 |
))])
|
|
|
|
| 263 |
fig.update_layout(
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
visible=False,
|
| 273 |
-
range=[-1,55],),
|
| 274 |
-
yaxis = dict(
|
| 275 |
-
backgroundcolor="rgb(255, 255, 255)",
|
| 276 |
-
gridcolor="black",
|
| 277 |
-
showbackground=True,
|
| 278 |
-
zerolinecolor="black",
|
| 279 |
-
visible=False,
|
| 280 |
-
nticks=4, range=[-1,55],),
|
| 281 |
-
zaxis = dict(
|
| 282 |
-
backgroundcolor="rgb(255, 255, 255)",
|
| 283 |
-
gridcolor="black",
|
| 284 |
-
showbackground=True,
|
| 285 |
-
zerolinecolor="black",
|
| 286 |
-
visible=False,
|
| 287 |
-
nticks=4, range=[-1,7],),
|
| 288 |
-
bgcolor="black",
|
| 289 |
-
),
|
| 290 |
-
|
| 291 |
-
)
|
| 292 |
|
| 293 |
-
|
| 294 |
-
# fov_voxels,
|
| 295 |
-
# x=fov_voxels[:, 0], y="y", z="z", color="label")
|
| 296 |
-
# Draw occupied inside FOV voxels
|
| 297 |
-
# plt_plot_fov = mlab.points3d(
|
| 298 |
-
# fov_voxels[:, 0],
|
| 299 |
-
# fov_voxels[:, 1],
|
| 300 |
-
# fov_voxels[:, 2],
|
| 301 |
-
# fov_voxels[:, 3],
|
| 302 |
-
# colormap="viridis",
|
| 303 |
-
# scale_factor=voxel_size - 0.05 * voxel_size,
|
| 304 |
-
# mode="cube",
|
| 305 |
-
# opacity=1.0,
|
| 306 |
-
# vmin=1,
|
| 307 |
-
# vmax=19,
|
| 308 |
-
# )
|
| 309 |
-
|
| 310 |
-
# # Draw occupied outside FOV voxels
|
| 311 |
-
# plt_plot_outfov = mlab.points3d(
|
| 312 |
-
# outfov_voxels[:, 0],
|
| 313 |
-
# outfov_voxels[:, 1],
|
| 314 |
-
# outfov_voxels[:, 2],
|
| 315 |
-
# outfov_voxels[:, 3],
|
| 316 |
-
# colormap="viridis",
|
| 317 |
-
# scale_factor=voxel_size - 0.05 * voxel_size,
|
| 318 |
-
# mode="cube",
|
| 319 |
-
# opacity=1.0,
|
| 320 |
-
# vmin=1,
|
| 321 |
-
# vmax=19,
|
| 322 |
-
# )
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
# plt_plot_fov.glyph.scale_mode = "scale_by_vector"
|
| 327 |
-
# plt_plot_outfov.glyph.scale_mode = "scale_by_vector"
|
| 328 |
-
|
| 329 |
-
# plt_plot_fov.module_manager.scalar_lut_manager.lut.table = colors
|
| 330 |
-
|
| 331 |
-
# outfov_colors = colors
|
| 332 |
-
# outfov_colors[:, :3] = outfov_colors[:, :3] // 3 * 2
|
| 333 |
-
# plt_plot_outfov.module_manager.scalar_lut_manager.lut.table = outfov_colors
|
| 334 |
-
|
| 335 |
-
# mlab.show()
|
| 336 |
-
return fig
|
|
|
|
| 5 |
import plotly.express as px
|
| 6 |
import plotly.graph_objects as go
|
| 7 |
|
| 8 |
+
|
| 9 |
def read_calib(calib_path):
|
| 10 |
+
"""
|
| 11 |
+
Modify from https://github.com/utiasSTARS/pykitti/blob/d3e1bb81676e831886726cc5ed79ce1f049aef2c/pykitti/utils.py#L68
|
| 12 |
+
:param calib_path: Path to a calibration text file.
|
| 13 |
+
:return: dict with calibration matrices.
|
| 14 |
+
"""
|
| 15 |
+
calib_all = {}
|
| 16 |
+
with open(calib_path, "r") as f:
|
| 17 |
+
for line in f.readlines():
|
| 18 |
+
if line == "\n":
|
| 19 |
+
break
|
| 20 |
+
key, value = line.split(":", 1)
|
| 21 |
+
calib_all[key] = np.array([float(x) for x in value.split()])
|
| 22 |
+
|
| 23 |
+
# reshape matrices
|
| 24 |
+
calib_out = {}
|
| 25 |
+
# 3x4 projection matrix for left camera
|
| 26 |
+
calib_out["P2"] = calib_all["P2"].reshape(3, 4)
|
| 27 |
+
calib_out["Tr"] = np.identity(4) # 4x4 matrix
|
| 28 |
+
calib_out["Tr"][:3, :4] = calib_all["Tr"].reshape(3, 4)
|
| 29 |
+
return calib_out
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def vox2pix(cam_E, cam_k,
|
| 33 |
+
vox_origin, voxel_size,
|
| 34 |
+
img_W, img_H,
|
| 35 |
scene_size):
|
| 36 |
"""
|
| 37 |
compute the 2D projection of voxels centroids
|
| 38 |
+
|
| 39 |
Parameters:
|
| 40 |
----------
|
| 41 |
cam_E: 4x4
|
|
|
|
| 51 |
image height
|
| 52 |
scene_size: (3,)
|
| 53 |
scene size in meter: (51.2, 51.2, 6.4) for SemKITTI and (4.8, 4.8, 2.88) for NYUv2
|
| 54 |
+
|
| 55 |
Returns
|
| 56 |
-------
|
| 57 |
projected_pix: (N, 2)
|
|
|
|
| 62 |
Voxels'distance to the sensor in meter
|
| 63 |
"""
|
| 64 |
# Compute the x, y, z bounding of the scene in meter
|
| 65 |
+
vol_bnds = np.zeros((3, 2))
|
| 66 |
+
vol_bnds[:, 0] = vox_origin
|
| 67 |
+
vol_bnds[:, 1] = vox_origin + np.array(scene_size)
|
| 68 |
|
| 69 |
# Compute the voxels centroids in lidar cooridnates
|
| 70 |
+
vol_dim = np.ceil((vol_bnds[:, 1] - vol_bnds[:, 0]) /
|
| 71 |
+
voxel_size).copy(order='C').astype(int)
|
| 72 |
xv, yv, zv = np.meshgrid(
|
| 73 |
+
range(vol_dim[0]),
|
| 74 |
+
range(vol_dim[1]),
|
| 75 |
+
range(vol_dim[2]),
|
| 76 |
+
indexing='ij'
|
| 77 |
+
)
|
| 78 |
vox_coords = np.concatenate([
|
| 79 |
+
xv.reshape(1, -1),
|
| 80 |
+
yv.reshape(1, -1),
|
| 81 |
+
zv.reshape(1, -1)
|
| 82 |
+
], axis=0).astype(int).T
|
| 83 |
|
| 84 |
# Project voxels'centroid from lidar coordinates to camera coordinates
|
| 85 |
cam_pts = fusion.TSDFVolume.vox2world(vox_origin, vox_coords, voxel_size)
|
|
|
|
| 92 |
# Eliminate pixels outside view frustum
|
| 93 |
pix_z = cam_pts[:, 2]
|
| 94 |
fov_mask = np.logical_and(pix_x >= 0,
|
| 95 |
+
np.logical_and(pix_x < img_W,
|
| 96 |
+
np.logical_and(pix_y >= 0,
|
| 97 |
+
np.logical_and(pix_y < img_H,
|
| 98 |
+
pix_z > 0))))
|
|
|
|
| 99 |
|
| 100 |
return torch.from_numpy(projected_pix), torch.from_numpy(fov_mask), torch.from_numpy(pix_z)
|
| 101 |
|
| 102 |
|
|
|
|
| 103 |
def get_grid_coords(dims, resolution):
|
| 104 |
"""
|
| 105 |
:param dims: the dimensions of the grid [x, y, z] (i.e. [256, 256, 32])
|
|
|
|
| 125 |
|
| 126 |
return coords_grid
|
| 127 |
|
| 128 |
+
|
| 129 |
def get_projections(img_W, img_H):
|
| 130 |
scale_3ds = [1, 2]
|
| 131 |
data = {}
|
| 132 |
for scale_3d in scale_3ds:
|
| 133 |
+
scene_size = (4.8, 4.8, 2.88)
|
| 134 |
+
vox_origin = np.array([-1.54591799, 0.8907361, -0.05])
|
| 135 |
+
voxel_size = 0.08
|
| 136 |
+
|
| 137 |
+
calib = read_calib("/monoscene/MonoScene/calib.txt")
|
| 138 |
+
cam_k = np.array([[518.8579, 0, 320], [0, 518.8579, 240], [0, 0, 1]])
|
| 139 |
+
cam_pose = np.asarray([[9.6699458e-01, 4.2662762e-02, 2.5120059e-01, 0.0000000e+00],
|
| 140 |
+
[-2.5147417e-01, 1.0867463e-03,
|
| 141 |
+
9.6786356e-01, 0.0000000e+00],
|
| 142 |
+
[4.1018680e-02, -9.9908894e-01,
|
| 143 |
+
1.1779292e-02, 1.1794727e+00],
|
| 144 |
+
[0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.0000000e+00]])
|
| 145 |
+
T_velo_2_cam = np.linalg.inv(cam_pose)
|
| 146 |
+
|
| 147 |
# compute the 3D-2D mapping
|
| 148 |
projected_pix, fov_mask, pix_z = vox2pix(
|
| 149 |
T_velo_2_cam,
|
|
|
|
| 153 |
img_W,
|
| 154 |
img_H,
|
| 155 |
scene_size,
|
| 156 |
+
)
|
| 157 |
|
| 158 |
data["projected_pix_{}".format(scale_3d)] = projected_pix
|
| 159 |
data["pix_z_{}".format(scale_3d)] = pix_z
|
| 160 |
+
data["fov_mask_{}".format(scale_3d)] = fov_mask
|
| 161 |
return data
|
| 162 |
|
| 163 |
|
| 164 |
def majority_pooling(grid, k_size=2):
|
| 165 |
result = np.zeros(
|
| 166 |
+
(grid.shape[0] // k_size, grid.shape[1] //
|
| 167 |
+
k_size, grid.shape[2] // k_size)
|
| 168 |
)
|
| 169 |
for xx in range(0, int(np.floor(grid.shape[0] / k_size))):
|
| 170 |
for yy in range(0, int(np.floor(grid.shape[1] / k_size))):
|
| 171 |
for zz in range(0, int(np.floor(grid.shape[2] / k_size))):
|
| 172 |
|
| 173 |
sub_m = grid[
|
| 174 |
+
(xx * k_size): (xx * k_size) + k_size,
|
| 175 |
+
(yy * k_size): (yy * k_size) + k_size,
|
| 176 |
+
(zz * k_size): (zz * k_size) + k_size,
|
| 177 |
]
|
| 178 |
unique, counts = np.unique(sub_m, return_counts=True)
|
| 179 |
if True in ((unique != 0) & (unique != 255)):
|
|
|
|
| 189 |
return result
|
| 190 |
|
| 191 |
|
| 192 |
+
def get_grid_coords(dims, resolution):
|
| 193 |
+
"""
|
| 194 |
+
:param dims: the dimensions of the grid [x, y, z] (i.e. [256, 256, 32])
|
| 195 |
+
:return coords_grid: is the center coords of voxels in the grid
|
| 196 |
+
"""
|
| 197 |
+
|
| 198 |
+
g_xx = np.arange(0, dims[0] + 1)
|
| 199 |
+
g_yy = np.arange(0, dims[1] + 1)
|
| 200 |
+
|
| 201 |
+
g_zz = np.arange(0, dims[2] + 1)
|
| 202 |
+
|
| 203 |
+
# Obtaining the grid with coords...
|
| 204 |
+
xx, yy, zz = np.meshgrid(g_xx[:-1], g_yy[:-1], g_zz[:-1])
|
| 205 |
+
coords_grid = np.array([xx.flatten(), yy.flatten(), zz.flatten()]).T
|
| 206 |
+
coords_grid = coords_grid.astype(np.float)
|
| 207 |
+
|
| 208 |
+
coords_grid = (coords_grid * resolution) + resolution / 2
|
| 209 |
+
|
| 210 |
+
temp = np.copy(coords_grid)
|
| 211 |
+
temp[:, 0] = coords_grid[:, 1]
|
| 212 |
+
temp[:, 1] = coords_grid[:, 0]
|
| 213 |
+
coords_grid = np.copy(temp)
|
| 214 |
+
|
| 215 |
+
return coords_grid
|
| 216 |
+
|
| 217 |
+
|
| 218 |
def draw(
|
| 219 |
voxels,
|
| 220 |
+
cam_pose,
|
| 221 |
+
vox_origin,
|
| 222 |
+
voxel_size=0.08,
|
| 223 |
+
d=0.75, # 0.75m - determine the size of the mesh representing the camera
|
|
|
|
|
|
|
|
|
|
| 224 |
):
|
| 225 |
+
# Compute the coordinates of the mesh representing camera
|
| 226 |
+
y = d * 480 / (2 * 518.8579)
|
| 227 |
+
x = d * 640 / (2 * 518.8579)
|
| 228 |
+
tri_points = np.array(
|
| 229 |
+
[
|
| 230 |
+
[0, 0, 0],
|
| 231 |
+
[x, y, d],
|
| 232 |
+
[-x, y, d],
|
| 233 |
+
[-x, -y, d],
|
| 234 |
+
[x, -y, d],
|
| 235 |
+
]
|
| 236 |
+
)
|
| 237 |
+
tri_points = np.hstack([tri_points, np.ones((5, 1))])
|
| 238 |
+
|
| 239 |
+
tri_points = (cam_pose @ tri_points.T).T
|
| 240 |
+
x = tri_points[:, 0] - vox_origin[0]
|
| 241 |
+
y = tri_points[:, 1] - vox_origin[1]
|
| 242 |
+
z = tri_points[:, 2] - vox_origin[2]
|
| 243 |
+
triangles = [
|
| 244 |
+
(0, 1, 2),
|
| 245 |
+
(0, 1, 4),
|
| 246 |
+
(0, 3, 4),
|
| 247 |
+
(0, 2, 3),
|
| 248 |
+
]
|
| 249 |
|
|
|
|
| 250 |
# Compute the voxels coordinates
|
| 251 |
grid_coords = get_grid_coords(
|
| 252 |
+
[voxels.shape[0], voxels.shape[2], voxels.shape[1]], voxel_size
|
| 253 |
)
|
| 254 |
|
|
|
|
| 255 |
# Attach the predicted class to every voxel
|
| 256 |
+
grid_coords = np.vstack(
|
| 257 |
+
(grid_coords.T, np.moveaxis(voxels, [0, 1, 2], [0, 2, 1]).reshape(-1))
|
| 258 |
+
).T
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
|
| 260 |
# Remove empty and unknown voxels
|
| 261 |
+
occupied_voxels = grid_coords[(grid_coords[:, 3] > 0) & (grid_coords[:, 3] < 255)]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
colors = np.array(
|
| 263 |
[
|
| 264 |
+
[22, 191, 206, 255],
|
| 265 |
+
[214, 38, 40, 255],
|
| 266 |
+
[43, 160, 43, 255],
|
| 267 |
+
[158, 216, 229, 255],
|
| 268 |
+
[114, 158, 206, 255],
|
| 269 |
+
[204, 204, 91, 255],
|
| 270 |
+
[255, 186, 119, 255],
|
| 271 |
+
[147, 102, 188, 255],
|
| 272 |
+
[30, 119, 181, 255],
|
| 273 |
+
[188, 188, 33, 255],
|
| 274 |
+
[255, 127, 12, 255],
|
| 275 |
+
[196, 175, 214, 255],
|
| 276 |
+
[153, 153, 153, 255],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
]
|
| 278 |
).astype(np.uint8)
|
| 279 |
|
| 280 |
+
pts_colors = [
|
| 281 |
+
f'rgb({colors[int(i)][0]}, {colors[int(i)][1]}, {colors[int(i)][2]})' for i in occupied_voxels[:, 3]]
|
| 282 |
+
out_fov_colors = [
|
| 283 |
+
f'rgb({colors[int(i)][0]//3*2}, {colors[int(i)][1]//3*2}, {colors[int(i)][2]//3*2})' for i in occupied_voxels[:, 3]]
|
| 284 |
pts_colors = pts_colors + out_fov_colors
|
| 285 |
+
fig = go.Figure(data=[go.Scatter3d(x=occupied_voxels[:, 0], y=occupied_voxels[:, 1], z=occupied_voxels[:, 2], mode='markers',
|
| 286 |
+
marker=dict(
|
| 287 |
+
size=4,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
color=pts_colors, # set color to an array/list of desired values
|
|
|
|
| 289 |
opacity=1.0,
|
| 290 |
symbol='square'
|
| 291 |
))])
|
| 292 |
+
|
| 293 |
fig.update_layout(
|
| 294 |
+
scene=dict(
|
| 295 |
+
aspectmode='data',
|
| 296 |
+
yaxis=dict(visible=False, showticklabels=False),
|
| 297 |
+
bgcolor="black",
|
| 298 |
+
),
|
| 299 |
+
|
| 300 |
+
)
|
| 301 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
|
| 303 |
+
return fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
images/08/3-1.jpg
ADDED
|