File size: 5,811 Bytes
8813b45 a3afcbc 724cc25 a3afcbc da4ae8f 724cc25 da4ae8f 420d591 da4ae8f 420d591 da4ae8f 420d591 da4ae8f 724cc25 a3afcbc a6d4f44 2808776 a6d4f44 a3afcbc 4415e8d a3afcbc 35c91c9 a3afcbc 8813b45 724cc25 11827d2 724cc25 11827d2 724cc25 |
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 |
import trimesh
import numpy as np
from copy import deepcopy
from PIL import Image
from . import color_mappings
def line(p1, p2, c=(255,0,0), resolution=10, radius=0.05):
'''draws a 3d cylinder along the line (p1, p2)'''
# check colors
if len(c) == 1:
c = [c[0]]*4
elif len(c) == 3:
c = [*c, 255]
elif len(c) != 4:
raise ValueError(f'{c} is not a valid color (must have 1,3, or 4 elements).')
# compute length and direction of segment
p1, p2 = np.asarray(p1), np.asarray(p2)
l = np.linalg.norm(p2-p1)
direction = (p2 - p1) / l
# point z along direction of segment
T = np.eye(4)
T[:3, 2] = direction
T[:3, 3] = (p1+p2)/2
#reorthogonalize basis
b0, b1 = T[:3, 0], T[:3, 1]
if np.abs(np.dot(b0, direction)) < np.abs(np.dot(b1, direction)):
T[:3, 1] = -np.cross(b0, direction)
else:
T[:3, 0] = np.cross(b1, direction)
# generate and transform mesh
mesh = trimesh.primitives.Cylinder(radius=radius, height=l, transform=T)
# apply uniform color
mesh.visual.vertex_colors = np.ones_like(mesh.visual.vertex_colors)*c
return mesh
def show_wf(row, radius=10, show_vertices=False):
EDGE_CLASSES = ['eave',
'ridge',
'step_flashing',
'rake',
'flashing',
'post',
'valley',
'hip',
'transition_line']
out_meshes = []
if show_vertices:
out_meshes.extend([trimesh.primitives.Sphere(radius=radius+5, center = center, color=(255,0,0)) for center in row['wf_vertices']])
if 'edge_semantics' not in row:
print ("Warning: edge semantics is not here, skipping")
out_meshes.extend([line(a,b, radius=radius, c=(214, 251, 248)) for a,b in np.stack([*row['wf_vertices']])[np.stack(row['wf_edges'])]])
elif len(np.stack(row['wf_edges'])) == len(row['edge_semantics']):
out_meshes.extend([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'])])
else:
print ("Warning: edge semantics has different length compared to edges, skipping semantics")
out_meshes.extend([line(a,b, radius=radius, c=(214, 251, 248)) for a,b in np.stack([*row['wf_vertices']])[np.stack(row['wf_edges'])]])
return out_meshes
# 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'])]
def show_grid(edges, meshes=None, row_length=5):
'''
edges: list of list of meshes
meshes: optional corresponding list of meshes
row_length: number of meshes per row
returns trimesh.Scene()
'''
T = np.eye(4)
out = []
edges = [sum(e[1:], e[0]) for e in edges]
row_height = 1.1 * max((e.extents for e in edges), key=lambda e: e[1])[1]
col_width = 1.1 * max((e.extents for e in edges), key=lambda e: e[0])[0]
# print(row_height, col_width)
if meshes is None:
meshes = [None]*len(edges)
for i, (gt, mesh) in enumerate(zip(edges, meshes), start=0):
mesh = deepcopy(mesh)
gt = deepcopy(gt)
if i%row_length != 0:
T[0, 3] += col_width
else:
T[0, 3] = 0
T[1, 3] += row_height
# print(T[0,3]/col_width, T[2,3]/row_height)
if mesh is not None:
mesh.apply_transform(T)
out.append(mesh)
gt.apply_transform(T)
out.append(gt)
out.extend([mesh, gt])
return trimesh.Scene(out)
def visualize_order_images(row_order):
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']))
def create_image_grid(images, target_length=312, num_per_row=2):
# Calculate the target size for the first image
first_img = images[0]
aspect_ratio = first_img.width / first_img.height
new_width = int((target_length ** 2 * aspect_ratio) ** 0.5)
new_height = int((target_length ** 2 / aspect_ratio) ** 0.5)
# Resize the first image
resized_images = [img.resize((new_width, new_height), Image.Resampling.LANCZOS) for img in images]
# Calculate the grid size
num_rows = (len(resized_images) + num_per_row - 1) // num_per_row
grid_width = new_width * num_per_row
grid_height = new_height * num_rows
# Create a new image for the grid
grid_img = Image.new('RGB', (grid_width, grid_height))
# Paste the images into the grid
for i, img in enumerate(resized_images):
x_offset = (i % num_per_row) * new_width
y_offset = (i // num_per_row) * new_height
grid_img.paste(img, (x_offset, y_offset))
return grid_img
import matplotlib.pyplot as plt
def visualize_depth(depth, min_depth=None, max_depth=None, cmap='rainbow'):
depth = np.array(depth)
if min_depth is None:
min_depth = np.min(depth)
if max_depth is None:
max_depth = np.max(depth)
# Normalize the depth to be between 0 and 1
depth = (depth - min_depth) / (max_depth - min_depth)
depth = np.clip(depth, 0, 1)
# Use the matplotlib colormap to convert the depth to an RGB image
cmap = plt.get_cmap(cmap)
depth_image = (cmap(depth) * 255).astype(np.uint8)
# Convert the depth image to a PIL image
depth_image = Image.fromarray(depth_image)
return depth_image |