|
|
from vedo import Mesh, Points, Plotter, screenshot, Arrow, Light, Plane |
|
|
import imageio |
|
|
import os |
|
|
import numpy as np |
|
|
from scipy.interpolate import Rbf, NearestNDInterpolator as Near |
|
|
import re |
|
|
|
|
|
screenshot_scale = 3 |
|
|
|
|
|
cam = dict( |
|
|
position=(-3.85922, -4.78140, 0.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), |
|
|
) |
|
|
|
|
|
_red = [0.9, 0.1, 0.1] |
|
|
_green= [0.4, 1.0, 0.8] |
|
|
_blue =[0.7, 0.9, 1.0] |
|
|
_dark_blue =[0.03, 0.4, 0.7] |
|
|
|
|
|
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 get_lights(light_color=[255, 255, 245], offset=[0, 0, 0], intensity_mult=1): |
|
|
|
|
|
|
|
|
orig = np.array([0, 0, 0]) + np.array(offset) |
|
|
phl = Arrow(np.array([0.1, 0.1, 10]) + offset, orig, c=light_color).scale(0.2) |
|
|
pfl = Arrow(np.array([1.5, 0.1, 0.3]) + offset, orig, c=light_color).scale(0.2) |
|
|
pbl = Arrow(np.array([-1.5, 0.1, 0.3]) + offset, orig, c=light_color).scale(0.2) |
|
|
prl = Arrow(np.array([0.1, -1.5, 0.3]) + offset, orig, c=light_color).scale(0.2) |
|
|
pll = Arrow(np.array([0.1, 1.5, 0.3]) + offset, orig, c=light_color).scale(0.2) |
|
|
hl = Light(phl, intensity=0.7 * intensity_mult, angle=180, ) |
|
|
rl = Light(pfl, intensity=0.6 * intensity_mult, angle=180, ) |
|
|
ll = Light(pbl, intensity=0.6 * intensity_mult, angle=180, ) |
|
|
bl = Light(pll, intensity=0.6 * intensity_mult, angle=180, ) |
|
|
fl = Light(prl, intensity=1 * intensity_mult, angle=180, ) |
|
|
lights = [hl, fl, bl, ll, rl] |
|
|
return lights |
|
|
|
|
|
def get_mesh(mesh_name, 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=_blue, 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 get_ptc(ptc_name, rotation=[0, 0, 0], offset=[0, 0, 0], scale=0, color=_dark_blue): |
|
|
offset = np.array(offset) |
|
|
|
|
|
mesh = Points(Mesh(ptc_name), r=1).c([0.5,0.5,0.5]).alpha(0.8) |
|
|
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 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.points().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 create_visual(mesh_files, directory, x,y,z, type='mesh'): |
|
|
meshes, scales =[], [] |
|
|
|
|
|
plotter = Plotter(bg=[255, 255, 255], offscreen=True) |
|
|
|
|
|
frame_files = [] |
|
|
|
|
|
for file in mesh_files: |
|
|
if type == 'mesh': |
|
|
mesh, scale = get_mesh(file, rotation=[x,y,z], mesh_lighting='metallic') |
|
|
else: |
|
|
mesh, scale = get_ptc(file) |
|
|
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) |
|
|
|
|
|
|
|
|
filename = os.path.join(directory, type+'_animation.gif') |
|
|
with imageio.get_writer(filename, mode='I', duration=0.2) as writer: |
|
|
for filename in frame_files: |
|
|
image = imageio.imread(filename) |
|
|
writer.append_data(image) |
|
|
|
|
|
|
|
|
|
|
|
def create_mesh_animation(mesh_files, directory, x,y,z): |
|
|
|
|
|
|
|
|
meshes = [Mesh(f) for f in mesh_files] |
|
|
|
|
|
|
|
|
plotter = Plotter(bg=[255, 255, 255], offscreen=True) |
|
|
|
|
|
|
|
|
frame_files = [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for frame_id, mesh in enumerate(meshes): |
|
|
mesh.rotate_x(x).rotate_y(y).rotate_z(z).lighting('metallic') |
|
|
shadow = get_mesh_shadow(mesh) |
|
|
scalars = 1- mesh.vertices[:, 2] |
|
|
mesh.cmap('Blues', scalars) |
|
|
|
|
|
plotter.clear() |
|
|
|
|
|
plotter.show(mesh, shadow, __doc__, interactive=False, camera=cam, resetcam=True, zoom=2) |
|
|
frame_path = mesh_files[frame_id][:-4] + ".png" |
|
|
frame_files.append(frame_path) |
|
|
screenshot(frame_path, scale=1) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
filename = os.path.join(directory, 'mesh_animation.gif') |
|
|
with imageio.get_writer(filename, mode='I', duration=0.2) as writer: |
|
|
for f in frame_files: |
|
|
image = imageio.imread(f) |
|
|
writer.append_data(image) |
|
|
os.system("""convert -trim {0} "{1}" """.format(f, f)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_point_cloud_animation(files, directory, x,y,z): |
|
|
|
|
|
meshes = [Points(Mesh(f), r=1) for f in files] |
|
|
|
|
|
|
|
|
plotter = Plotter(bg=[255, 255, 255], offscreen=True) |
|
|
|
|
|
|
|
|
frame_files = [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for frame_id, mesh in enumerate(meshes): |
|
|
mesh.rotate_x(x).rotate_y(y).rotate_z(z).c([0.5,0.5,0.5]) |
|
|
shadow = get_mesh_shadow(mesh) |
|
|
|
|
|
|
|
|
plotter.clear() |
|
|
plotter.show(mesh, shadow, __doc__, interactive=False, camera=cam, resetcam=True, zoom=2) |
|
|
|
|
|
frame_path = files[frame_id][:-4] + ".png" |
|
|
frame_files.append(frame_path) |
|
|
screenshot(frame_path, scale=1) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
filename = os.path.join(directory, 'pct_animation.gif') |
|
|
with imageio.get_writer(filename, mode='I', duration=0.2) as writer: |
|
|
for f in frame_files: |
|
|
image = imageio.imread(f) |
|
|
writer.append_data(image) |
|
|
os.system("""convert -trim {0} "{1}" """.format(f, f)) |
|
|
|
|
|
|
|
|
|
|
|
def point_cloud_colormap(gt_ptc, ptc, corr_num): |
|
|
|
|
|
s1, _ = get_ptc(gt_ptc, color=_red) |
|
|
s2, _ = get_ptc(ptc, color=_blue) |
|
|
|
|
|
landmarks1 = s1.vertices[:corr_num,:] |
|
|
landmarks2 = s2.vertices[:corr_num,:] |
|
|
|
|
|
x, y, z = np.split(landmarks1, 3, axis=1) |
|
|
desc = x**2 + y**2 + z**2 |
|
|
|
|
|
|
|
|
itr = Near(landmarks1, desc) |
|
|
|
|
|
|
|
|
xi, yi, zi = np.split(s2.vertices, 3, axis=1) |
|
|
interpolated_desc = itr(xi, yi, zi) |
|
|
|
|
|
s2.cmap('coolwarm', interpolated_desc.squeeze()).add_scalarbar(title='error') |
|
|
|
|
|
|
|
|
plotter = Plotter() |
|
|
|
|
|
plotter.show(s2, __doc__, axes=True) |
|
|
|
|
|
|
|
|
def mesh_colormap(gt_mesh, mesh, corr_num): |
|
|
|
|
|
s1, _ = get_ptc(gt_ptc, color=_red) |
|
|
s2, _ = get_ptc(ptc, color=_blue) |
|
|
|
|
|
landmarks1 = s1.vertices[:corr_num,:] |
|
|
landmarks2 = s2.vertices[:corr_num,:] |
|
|
|
|
|
x, y, z = np.split(landmarks1, 3, axis=1) |
|
|
desc = x**2 + y**2 + z**2 |
|
|
|
|
|
|
|
|
itr = Near(landmarks1, desc) |
|
|
|
|
|
|
|
|
xi, yi, zi = np.split(s2.vertices, 3, axis=1) |
|
|
interpolated_desc = itr(xi, yi, zi) |
|
|
|
|
|
s2.cmap('coolwarm', interpolated_desc.squeeze()).add_scalarbar(title='error') |
|
|
|
|
|
|
|
|
plotter = Plotter() |
|
|
|
|
|
plotter.show(s2, __doc__, axes=True) |
|
|
|
|
|
|
|
|
def plot_two_mesh(meshfile1, meshfile2, 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.2,0.2,0.2]) |
|
|
|
|
|
|
|
|
|
|
|
mesh2, scale = get_mesh(meshfile2, rotation=[x,y,z], mesh_lighting='shiny') |
|
|
scalars = 1- mesh2.vertices[:, 2] |
|
|
mesh2.cmap('Blues', scalars) |
|
|
plotter.show(mesh1, mesh2, __doc__, interactive=False, camera=cam, resetcam=True, zoom=2) |
|
|
frame_path =meshfile2[:-4] + ".png" |
|
|
|
|
|
screenshot(frame_path, scale=1) |
|
|
os.system("""convert -trim {0} "{1}" """.format(frame_path, frame_path)) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
folder = '/home/wiss/sang/git/implicit_neuro_morph/jax_implicit_neuro_morph/exp/smal/2024_04_18_15_11_59/reconstructions' |
|
|
prefix = 'shape_0_to_4000_' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
folder = '/home/wiss/sang/git/implicit_neuro_morph/jax_implicit_neuro_morph/exp/smal/2024_04_18_15_11_59/eval' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
prefix = 'shape_0_to_4000_' |
|
|
mesh1 = 'gt_pointcloud_y.ply' |
|
|
mesh2 = 'step_10_mesh.ply' |
|
|
|
|
|
meshfile1 = os.path.join(folder, prefix + mesh1) |
|
|
meshfile2 = os.path.join(folder, prefix + mesh2) |
|
|
|
|
|
plot_two_mesh(meshfile1, meshfile2, 0, 0, -30) |
|
|
|
|
|
|