Commit
·
724cc25
1
Parent(s):
2808776
add more vis
Browse files- hoho/color_mappings.py +24 -0
- hoho/hoho.py +60 -0
- hoho/vis.py +70 -0
hoho/color_mappings.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
| 1 |
gestalt_color_mapping = {
|
| 2 |
"unclassified": (215, 62, 138),
|
| 3 |
"apex": (235, 88, 48),
|
|
@@ -26,6 +28,7 @@ gestalt_color_mapping = {
|
|
| 26 |
"other_wall": (112, 61, 240),
|
| 27 |
"trim": (151, 206, 58),
|
| 28 |
"unknown": (127, 127, 127),
|
|
|
|
| 29 |
}
|
| 30 |
|
| 31 |
ade20k_color_mapping = {
|
|
@@ -180,3 +183,24 @@ ade20k_color_mapping = {
|
|
| 180 |
'clock': (102, 255, 0),
|
| 181 |
'flag': (92, 0, 255),
|
| 182 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
|
| 3 |
gestalt_color_mapping = {
|
| 4 |
"unclassified": (215, 62, 138),
|
| 5 |
"apex": (235, 88, 48),
|
|
|
|
| 28 |
"other_wall": (112, 61, 240),
|
| 29 |
"trim": (151, 206, 58),
|
| 30 |
"unknown": (127, 127, 127),
|
| 31 |
+
"transition_line": (0,0,0),
|
| 32 |
}
|
| 33 |
|
| 34 |
ade20k_color_mapping = {
|
|
|
|
| 183 |
'clock': (102, 255, 0),
|
| 184 |
'flag': (92, 0, 255),
|
| 185 |
}
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
# edge_colors = np.asarray([(214, 251, 248),
|
| 189 |
+
# (13, 94, 47),
|
| 190 |
+
# (54, 243, 63),
|
| 191 |
+
# (187, 123, 236),
|
| 192 |
+
# (162, 162, 32),
|
| 193 |
+
# (169, 255, 219),
|
| 194 |
+
# (8, 89, 52),
|
| 195 |
+
# (85, 27, 65),
|
| 196 |
+
# (0, 0, 0)]
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
# edge_colors = np.array([[ 54, 243, 63],
|
| 200 |
+
# [214, 251, 248],
|
| 201 |
+
# [169, 255, 219],
|
| 202 |
+
# [ 13, 94, 47],
|
| 203 |
+
# [162, 162, 32],
|
| 204 |
+
# [187, 123, 236],
|
| 205 |
+
# [ 85, 27, 65],
|
| 206 |
+
# [ 0, 0, 0]])
|
hoho/hoho.py
CHANGED
|
@@ -176,6 +176,66 @@ def proc(row, split='train'):
|
|
| 176 |
return Sample(out)
|
| 177 |
|
| 178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
class Sample(Dict):
|
| 180 |
def __repr__(self):
|
| 181 |
return str({k: v.shape if hasattr(v, 'shape') else [type(v[0])] if isinstance(v, list) else type(v) for k,v in self.items()})
|
|
|
|
| 176 |
return Sample(out)
|
| 177 |
|
| 178 |
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
from . import read_write_colmap
|
| 183 |
+
def decode_colmap(s):
|
| 184 |
+
# with open('colmap_solve/points3D.bin', 'wb') as stream:
|
| 185 |
+
|
| 186 |
+
with temp_working_directory():
|
| 187 |
+
|
| 188 |
+
with open('points3D.bin', 'wb') as stream:
|
| 189 |
+
stream.write(s['points3d'])
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
with open('cameras.bin', 'wb') as stream:
|
| 193 |
+
stream.write(s['cameras'])
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
with open('images.bin', 'wb') as stream:
|
| 197 |
+
stream.write(s['images'])
|
| 198 |
+
|
| 199 |
+
|
| 200 |
+
cameras, images, points3D = read_write_colmap.read_model(
|
| 201 |
+
path='.', ext='.bin'
|
| 202 |
+
)
|
| 203 |
+
return cameras, images, points3D
|
| 204 |
+
|
| 205 |
+
from PIL import Image
|
| 206 |
+
import io
|
| 207 |
+
def decode(row):
|
| 208 |
+
cameras, images, points3D = decode_colmap(row)
|
| 209 |
+
|
| 210 |
+
out = {}
|
| 211 |
+
|
| 212 |
+
for k, v in row.items():
|
| 213 |
+
# colname = k.split('.')[0]
|
| 214 |
+
if k in {'ade20k', 'depthcm', 'gestalt'}:
|
| 215 |
+
# print(k, len(v), type(v))
|
| 216 |
+
v = [Image.open(io.BytesIO(im)) for im in v]
|
| 217 |
+
if k in out:
|
| 218 |
+
out[k].extend(v)
|
| 219 |
+
else:
|
| 220 |
+
out[k] = v
|
| 221 |
+
elif k in {'wireframe', 'mesh'}:
|
| 222 |
+
# out.update({a: b.tolist() for a,b in v.items()})
|
| 223 |
+
v = dict(np.load(io.BytesIO(v)))
|
| 224 |
+
out.update({a: b for a,b in v.items()})
|
| 225 |
+
elif k in 'kr':
|
| 226 |
+
out[k.upper()] = v
|
| 227 |
+
elif k == 'cameras':
|
| 228 |
+
out[k] = cameras
|
| 229 |
+
elif k == 'images':
|
| 230 |
+
out[k] = images
|
| 231 |
+
elif k =='points3d':
|
| 232 |
+
out[k] = points3D
|
| 233 |
+
else:
|
| 234 |
+
out[k] = v
|
| 235 |
+
|
| 236 |
+
return Sample(out)
|
| 237 |
+
|
| 238 |
+
|
| 239 |
class Sample(Dict):
|
| 240 |
def __repr__(self):
|
| 241 |
return str({k: v.shape if hasattr(v, 'shape') else [type(v[0])] if isinstance(v, list) else type(v) for k,v in self.items()})
|
hoho/vis.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
| 1 |
import trimesh
|
| 2 |
import numpy as np
|
| 3 |
from copy import deepcopy
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
def line(p1, p2, c=(255,0,0), resolution=10, radius=0.05):
|
| 6 |
'''draws a 3d cylinder along the line (p1, p2)'''
|
|
@@ -38,6 +41,19 @@ def line(p1, p2, c=(255,0,0), resolution=10, radius=0.05):
|
|
| 38 |
|
| 39 |
return mesh
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
|
| 42 |
def show_grid(edges, meshes=None, row_length=5):
|
| 43 |
'''
|
|
@@ -85,3 +101,57 @@ def show_grid(edges, meshes=None, row_length=5):
|
|
| 85 |
return trimesh.Scene(out)
|
| 86 |
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import trimesh
|
| 2 |
import numpy as np
|
| 3 |
from copy import deepcopy
|
| 4 |
+
from PIL import Image
|
| 5 |
+
|
| 6 |
+
from . import color_mappings
|
| 7 |
|
| 8 |
def line(p1, p2, c=(255,0,0), resolution=10, radius=0.05):
|
| 9 |
'''draws a 3d cylinder along the line (p1, p2)'''
|
|
|
|
| 41 |
|
| 42 |
return mesh
|
| 43 |
|
| 44 |
+
def show_wf(row, radius=10):
|
| 45 |
+
EDGE_CLASSES = ['eave',
|
| 46 |
+
'ridge',
|
| 47 |
+
'step_flashing',
|
| 48 |
+
'rake',
|
| 49 |
+
'flashing',
|
| 50 |
+
'post',
|
| 51 |
+
'valley',
|
| 52 |
+
'hip',
|
| 53 |
+
'transition_line']
|
| 54 |
+
return [line(a,b, radius=radius, c=color_mappings.gestalt_color_mapping[EDGE_CLASSES[cls_id]]) for (a,b), cls_id in zip(np.stack([*row['wf_vertices']])[np.stack(row['wf_edges'])], row['edge_semantics'])]
|
| 55 |
+
# return [line(a,b, radius=radius, c=color_mappings.edge_colors[cls_id]) for (a,b), cls_id in zip(np.stack([*row['wf_vertices']])[np.stack(row['wf_edges'])], row['edge_semantics'])]
|
| 56 |
+
|
| 57 |
|
| 58 |
def show_grid(edges, meshes=None, row_length=5):
|
| 59 |
'''
|
|
|
|
| 101 |
return trimesh.Scene(out)
|
| 102 |
|
| 103 |
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
def visualize_order_images(row_order):
|
| 107 |
+
return create_image_grid(row_order['ade20k'] + row_order['gestalt'] + [visualize_depth(dm) for dm in row_order['depthcm']], num_per_row=len(row_order['ade20k']))
|
| 108 |
+
|
| 109 |
+
def create_image_grid(images, target_length=312, num_per_row=2):
|
| 110 |
+
# Calculate the target size for the first image
|
| 111 |
+
first_img = images[0]
|
| 112 |
+
aspect_ratio = first_img.width / first_img.height
|
| 113 |
+
new_width = int((target_length ** 2 * aspect_ratio) ** 0.5)
|
| 114 |
+
new_height = int((target_length ** 2 / aspect_ratio) ** 0.5)
|
| 115 |
+
|
| 116 |
+
# Resize the first image
|
| 117 |
+
resized_images = [img.resize((new_width, new_height), Image.Resampling.LANCZOS) for img in images]
|
| 118 |
+
|
| 119 |
+
# Calculate the grid size
|
| 120 |
+
num_rows = (len(resized_images) + num_per_row - 1) // num_per_row
|
| 121 |
+
grid_width = new_width * num_per_row
|
| 122 |
+
grid_height = new_height * num_rows
|
| 123 |
+
|
| 124 |
+
# Create a new image for the grid
|
| 125 |
+
grid_img = Image.new('RGB', (grid_width, grid_height))
|
| 126 |
+
|
| 127 |
+
# Paste the images into the grid
|
| 128 |
+
for i, img in enumerate(resized_images):
|
| 129 |
+
x_offset = (i % num_per_row) * new_width
|
| 130 |
+
y_offset = (i // num_per_row) * new_height
|
| 131 |
+
grid_img.paste(img, (x_offset, y_offset))
|
| 132 |
+
|
| 133 |
+
return grid_img
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
import matplotlib
|
| 137 |
+
def visualize_depth(depth, min_depth=None, max_depth=None, cmap='rainbow'):
|
| 138 |
+
depth = np.array(depth)
|
| 139 |
+
|
| 140 |
+
if min_depth is None:
|
| 141 |
+
min_depth = np.min(depth)
|
| 142 |
+
if max_depth is None:
|
| 143 |
+
max_depth = np.max(depth)
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
# Normalize the depth to be between 0 and 1
|
| 147 |
+
depth = (depth - min_depth) / (max_depth - min_depth)
|
| 148 |
+
depth = np.clip(depth, 0, 1)
|
| 149 |
+
|
| 150 |
+
# Use the matplotlib colormap to convert the depth to an RGB image
|
| 151 |
+
cmap = matplotlib.cm.get_cmap(cmap)
|
| 152 |
+
depth_image = (cmap(depth) * 255).astype(np.uint8)
|
| 153 |
+
|
| 154 |
+
# Convert the depth image to a PIL image
|
| 155 |
+
depth_image = Image.fromarray(depth_image)
|
| 156 |
+
|
| 157 |
+
return depth_image
|