examples/air/viz.py (36 lines of code) (raw):

# Copyright (c) 2017-2019 Uber Technologies, Inc. # SPDX-License-Identifier: Apache-2.0 import math from collections import namedtuple import numpy as np from PIL import Image, ImageDraw def bounding_box(z_where, x_size): """This doesn't take into account interpolation, but it's close enough to be usable.""" w = x_size / z_where.s h = x_size / z_where.s xtrans = -z_where.x / z_where.s * x_size / 2. ytrans = -z_where.y / z_where.s * x_size / 2. x = (x_size - w) / 2 + xtrans # origin is top left y = (x_size - h) / 2 + ytrans return (x, y), w, h def arr2img(arr): # arr is expected to be a 2d array of floats in [0,1] return Image.frombuffer('L', arr.shape, (arr * 255).astype(np.uint8).tostring(), 'raw', 'L', 0, 1) def img2arr(img): # assumes color image # returns an array suitable for sending to visdom return np.array(img.getdata(), np.uint8).reshape(img.size + (3,)).transpose((2, 0, 1)) def colors(k): return [(255, 0, 0), (0, 255, 0), (0, 0, 255)][k % 3] def draw_one(imgarr, z_arr): # Note that this clipping makes the visualisation somewhat # misleading, as it incorrectly suggests objects occlude one # another. clipped = np.clip(imgarr.detach().cpu().numpy(), 0, 1) img = arr2img(clipped).convert('RGB') draw = ImageDraw.Draw(img) for k, z in enumerate(z_arr): # It would be better to use z_pres to change the opacity of # the bounding boxes, but I couldn't make that work with PIL. # Instead this darkens the color, and skips boxes altogether # when z_pres==0. if z.pres > 0: (x, y), w, h = bounding_box(z, imgarr.size(0)) color = tuple(map(lambda c: int(c * z.pres), colors(k))) draw.rectangle([x, y, x + w, y + h], outline=color) is_relaxed = any(z.pres != math.floor(z.pres) for z in z_arr) fmtstr = '{:.1f}' if is_relaxed else '{:.0f}' draw.text((0, 0), fmtstr.format(sum(z.pres for z in z_arr)), fill='white') return img2arr(img) def draw_many(imgarrs, z_arr): # canvases is expected to be a (n,w,h) numpy array # z_where_arr is expected to be a list of length n return [draw_one(imgarr, z) for (imgarr, z) in zip(imgarrs.cpu(), z_arr)] z_obj = namedtuple('z', 's,x,y,pres') # Map a tensor of latents (as produced by latents_to_tensor) to a list # of z_obj named tuples. def tensor_to_objs(latents): return [[z_obj._make(step) for step in z] for z in latents]