| | import numpy as np |
| | import cv2 |
| | from vedo import Mesh, Plane, Plotter, screenshot |
| | import imageio.v2 as imageio |
| | |
| | import re |
| | import os |
| | from .visual import get_ptc |
| | from PIL import Image |
| | from tqdm import tqdm |
| |
|
| | screenshot_scale = 3 |
| |
|
| | PLAY_OBS_BEFORE_PRED = True |
| | obs_dir = "" |
| | cam = dict( |
| | position=(-3.85922, -4.78140, 2.689328), |
| | focal_point=(0.192544, 4.77379e-3, 0.0127248), |
| | viewup=(0.0724348, 0.109097, 0.991388), |
| | distance=5.25119, |
| | clipping_range=(4.38228, 6.36775), |
| | ) |
| |
|
| | _green= [0.4, 0.7, 0.5] |
| | _blue =[0.7, 0.9, 1.0] |
| | _dark_blue =[0.03, 0.4, 0.7] |
| | _orange = [0.9, 0.7, 0.2] |
| |
|
| | def get_mesh(mesh_name, color='darksalmon', mesh_opacity=1.0, mesh_lighting='default', rotation=[0, 0, 0], offset=[0, 0, 0], scale=0): |
| | offset = np.array(offset) |
| | |
| | mesh = Mesh(mesh_name, c=color, alpha=mesh_opacity).lighting(mesh_lighting) |
| | if scale == 0: |
| | bnd = np.array(mesh.bounds()) |
| | scale = 1 / max(bnd[1]-bnd[0], bnd[3]-bnd[2], bnd[5]-bnd[4]) |
| | mesh.scale(scale) |
| | mesh.pos(offset) |
| | mesh.rotate_x(rotation[0]) |
| | mesh.rotate_y(rotation[1]) |
| | mesh.rotate_z(rotation[2]) |
| | |
| | |
| | return mesh, scale |
| |
|
| | def save_png_rm_bg(filename, im, bg_color_min=[0, 255, 100], bg_color_max=None, rgb=False): |
| | |
| | |
| | |
| |
|
| | if bg_color_max is None: |
| | bg_color_max = bg_color_min |
| | |
| | |
| | |
| | |
| |
|
| | |
| | min = np.array(bg_color_min, np.uint8) |
| | max = np.array(bg_color_max, np.uint8) |
| |
|
| | |
| | |
| | mask = cv2.inRange(im, min, max) |
| | |
| | |
| | |
| |
|
| | |
| | alpha = (im[:, :, 0] * 0 + 255) |
| |
|
| | |
| | alpha[mask > 0] = 0 |
| |
|
| | |
| | if rgb: |
| | im = cv2.merge((im[:, :, 0], im[:, :, 1], im[:, :, 2], alpha)) |
| | else: |
| | im = cv2.merge((im[:, :, 2], im[:, :, 1], im[:, :, 0], alpha)) |
| |
|
| | |
| | mask = im[:, :, 3] != 0. |
| | coords = np.argwhere(mask) |
| | y0, x0 = coords.min(axis=0) |
| | y1, x1 = coords.max(axis=0) + 1 |
| | |
| |
|
| | |
| | cv2.imwrite(filename, im) |
| |
|
| | def save_plot_as_transparent_png(plt, out_filename): |
| | |
| | bg_col = [255, 255, 255] |
| | plt.background(c1=bg_col) |
| | save_png_rm_bg(out_filename, plt.screenshot(asarray=True), bg_color_min=bg_col) |
| |
|
| |
|
| | def get_mesh_shadow(mesh, offset=[0, 0, 0], plane_normal=(0, 0, 1), direction=[0.1, -1.8, 3]): |
| | shadow = [] |
| | shad_col = np.array([0.8, 0.8, 0.8]) |
| | min_z = mesh.vertices.min(axis=0)[2] |
| | |
| | plane = Plane(pos=np.array([0, 0, min_z]) + np.array(offset), normal=plane_normal, s=[7, 7]).alpha(0.2) |
| | shad = mesh.clone().project_on_plane(plane, direction=-np.array(direction) + np.array(offset)) |
| | shad.c(shad_col).alpha(1).lighting("off").use_bounds(False) |
| | shadow = shad |
| | return shadow |
| |
|
| | def plot_meshes(mesh_files, cam, mesh_color=[1, 1, 1], rotation=[0, 0, 0]): |
| | |
| | mesh_opacity = 0.8 |
| | plot_shadows = True |
| | |
| | pass |
| |
|
| | def create_visual(mesh_files, color='coral', dest_name="", x=0,y=0,z=0, type='mesh', mesh_lighting='plastic', obs_dir=""): |
| | meshes, scales =[], [] |
| | bg_col = [255, 255, 255] |
| | plotter = Plotter(bg=[255, 255, 255], offscreen=True) |
| |
|
| | frame_files = [] |
| | |
| | for file in tqdm(mesh_files): |
| | mesh, scale = get_mesh(file, color=color, rotation=[x,y,z], mesh_lighting=mesh_lighting, scale=0.6) |
| | |
| | |
| | |
| | plotter.clear() |
| | |
| | shadow = get_mesh_shadow(mesh) |
| | |
| | |
| | |
| | plotter.show(mesh, shadow, __doc__, interactive=False, camera=cam, resetcam=True, zoom=2) |
| | frame_path =file[:-4] + ".png" |
| | frame_files.append(frame_path) |
| | screenshot(frame_path, scale=1) |
| | save_png_rm_bg(file[:-4]+"new.png", plotter.screenshot(asarray=True), bg_color_min=bg_col) |
| |
|
| | |
| | filename = os.path.join(dest_name + '.gif') |
| | create_transparent_gif(frame_files, dest_name, obs_dir) |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | def create_transparent_gif(frame_files, dest_name, obs_dir): |
| | images = [] |
| | if "obs" not in dest_name and PLAY_OBS_BEFORE_PRED: |
| | |
| | obs_files = [os.path.join(obs_dir, f) for f in os.listdir(obs_dir) if f.endswith('new.png')] |
| | |
| | obs_files = sort_list(obs_files) |
| | for i, frame in enumerate(obs_files): |
| | im = Image.open(frame) |
| | images.append(im) |
| | |
| | |
| | frame_files = [f.replace('.png', 'new.png') for f in frame_files] |
| | frame_files = sort_list(frame_files) |
| | |
| | |
| | for frame in frame_files: |
| | im = Image.open(frame) |
| | images.append(im) |
| |
|
| | |
| | images[0].save( |
| | os.path.join(dest_name + '_tranp.gif'), |
| | format="GIF", |
| | save_all=True, |
| | loop=1, |
| | append_images=images[1:], |
| | duration=0.033, |
| | disposal=2, |
| | optimize=True, |
| | quality=85, |
| | colors=64 |
| | ) |
| | |
| | |
| | for im in images: |
| | im.close() |
| |
|
| | def sort_list(l): |
| | try: |
| | return list(sorted(l, key=lambda x: int(re.search(r'\d+(?=\.)', x).group()))) |
| | except AttributeError: |
| | return sorted(l) |
| | |
| |
|
| | def visual_gt(mesh_files, color, x,y,z, type='mesh'): |
| | bg_col = [255, 255, 255] |
| | plotter = Plotter(bg=[255, 255, 255], offscreen=True) |
| |
|
| | frame_files = [] |
| | |
| | for file in mesh_files: |
| | |
| | if type == 'mesh': |
| | mesh, scale = get_mesh(file, color=color, rotation=[x,y,z], mesh_lighting='plastic') |
| | |
| | |
| | else: |
| | mesh, scale = get_ptc(file, rotation=[x,y,z]) |
| | mesh.c([0.5,0.5,0.5]) |
| | |
| | plotter.clear() |
| | |
| | shadow = get_mesh_shadow(mesh) |
| | |
| | |
| | plotter.show(mesh, shadow, __doc__, interactive=False, camera=cam, resetcam=True, zoom=2) |
| | frame_path =file[:-4] + ".png" |
| | frame_files.append(frame_path) |
| | screenshot(frame_path, scale=1) |
| | save_png_rm_bg(file[:-4]+"new.png", plotter.screenshot(asarray=True), bg_color_min=bg_col) |
| |
|
| |
|
| | def plot_two_mesh(meshfile1, meshfile2, color, x,y,z): |
| | plotter = Plotter(bg=[255, 255, 255], offscreen=True) |
| | mesh1, scale = get_ptc(meshfile1, rotation=[x,y,z]) |
| | mesh1.alpha(1.0).c([0.5,0.5,0.5]) |
| | |
| | |
| | |
| | mesh2, scale = get_mesh(meshfile2, color=color, rotation=[x,y,z], mesh_lighting='plastic') |
| | |
| | shadow = get_mesh_shadow(mesh2) |
| | plotter.show(mesh1, mesh2, shadow, __doc__, interactive=False, camera=cam, resetcam=True, zoom=2) |
| | frame_path =meshfile2[:-4] + ".png" |
| | |
| | screenshot(frame_path, scale=1) |
| | save_png_rm_bg(meshfile2[:-4]+"both.png", plotter.screenshot(asarray=True), bg_color_min=[255, 255, 255]) |
| | |
| | import argparse |
| |
|
| | |
| | |
| |
|
| | def main(parent_folder, displayed_preds=3): |
| | file_type = '.obj' |
| | x,y,z = 0, 0, -90 |
| | dest_dir = os.path.join(os.path.dirname(parent_folder), 'shadow_gif') |
| | obs_dir = os.path.join(os.path.dirname(parent_folder), 'obs_obj') |
| | os.makedirs(dest_dir, exist_ok=True) |
| | |
| | |
| | existing_gifs = [f for f in os.listdir(dest_dir) if f.endswith('_tranp.gif') and not f.startswith('obs')] |
| | if len(existing_gifs) >= displayed_preds: |
| | print(f"Found {len(existing_gifs)} existing GIFs, which is enough for {displayed_preds} predictions") |
| | return |
| | |
| | print(f"Found {len(existing_gifs)} existing GIFs, need {displayed_preds}, proceeding with generation") |
| | |
| | |
| | subfolders = sorted([f for f in os.listdir(parent_folder) if os.path.isdir(os.path.join(parent_folder, f)) and 'obj' in f]) |
| | for f in subfolders: |
| | folder = os.path.join(parent_folder, f) |
| | dest_name = os.path.join(dest_dir, f) |
| |
|
| | mesh_files = [os.path.join(folder, f) for f in os.listdir(folder) if f.endswith(file_type)] |
| | mesh_files = sort_list(mesh_files) |
| | os.makedirs(dest_dir, exist_ok=True) |
| | |
| | |
| | if 'obs' in f: |
| | create_visual(mesh_files, _green, dest_name, x,y,z, type='mesh', mesh_lighting='plastic', obs_dir=obs_dir) |
| | else: |
| | create_visual(mesh_files, _dark_blue, dest_name, x,y,z, type='mesh', mesh_lighting='plastic', obs_dir=obs_dir) |
| | |
| |
|
| | if __name__ == "__main__": |
| | parser = argparse.ArgumentParser() |
| | |
| | parser.add_argument('-f', '--mesh_parent_folder', type=str, default="final_output/hmp/visuals/amass/SkeletonDiffusion/test/952_WalkTogether/obj") |
| | |
| | args = parser.parse_args() |
| | main(args.mesh_parent_folder) |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| |
|
| |
|
| |
|
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | print("done.") |
| |
|
| |
|