|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pyrenderer(imw=2048, imh=2048): |
|
|
|
from body_visualizer.mesh.mesh_viewer import MeshViewer |
|
import cv2 |
|
|
|
import numpy as np |
|
import trimesh |
|
|
|
try: |
|
mv = MeshViewer(width=imw, height=imh, use_offscreen=True) |
|
except: |
|
import os |
|
os.environ['PYOPENGL_PLATFORM'] = 'egl' |
|
os.environ['EGL_DEVICE_ID'] = os.environ['GPU_DEVICE_ORDINAL'].split(',')[0] |
|
|
|
mv = MeshViewer(width=imw, height=imh, use_offscreen=True) |
|
|
|
mv.set_cam_trans([0, -0.5, 2.]) |
|
|
|
def render_an_image(meshes): |
|
n_all = len(meshes) |
|
nc = int(np.sqrt(n_all)) |
|
|
|
out_image = np.zeros([1, 1, 1, mv.width, mv.height, 4]) |
|
|
|
scale_percent = 100./nc |
|
width = int(mv.width * scale_percent / 100) |
|
height = int(mv.height * scale_percent / 100) |
|
dim = (width, height) |
|
|
|
for rId in range(nc): |
|
for cId in range(nc): |
|
i = (nc*rId) + cId |
|
if i>len(meshes): break |
|
|
|
mesh = meshes[i] |
|
|
|
|
|
mesh.vertices -= np.median(np.array(mesh.vertices), axis=0) |
|
mv.set_dynamic_meshes([mesh]) |
|
img = mv.render(render_wireframe=False, RGBA=True) |
|
img_resized = cv2.resize(img, dim, interpolation=cv2.INTER_AREA) |
|
|
|
out_image[0, 0, 0, (rId*width):((rId+1)*width), (cId*height):((cId+1)*height)] = cv2.cvtColor(img_resized, cv2.COLOR_BGRA2RGBA) |
|
|
|
return out_image.astype(np.uint8) |
|
|
|
return render_an_image |
|
|
|
def vposer_trainer_renderer(bm, num_bodies_to_display=5): |
|
import numpy as np |
|
import trimesh |
|
import torch |
|
|
|
from body_visualizer.tools.vis_tools import imagearray2file, colors |
|
from human_body_prior.tools.omni_tools import copy2cpu as c2c |
|
from human_body_prior.tools.omni_tools import makepath |
|
from trimesh import Trimesh as Mesh |
|
from trimesh.util import concatenate as mesh_cat |
|
|
|
renderer = pyrenderer(1024, 1024) |
|
|
|
faces = c2c(bm.f) |
|
|
|
def render_once(body_parms, body_colors=[colors['grey'], colors['brown-light']], out_fname=None): |
|
''' |
|
|
|
:param body_parms: list of dictionaries of body parameters. |
|
:param body_colors: list of np arrays of color rgb values |
|
:param movie_outpath: a mp4 path |
|
:return: |
|
''' |
|
|
|
if out_fname is not None: makepath(out_fname, isfile=True) |
|
assert len(body_parms) <= len(body_colors), ValueError('Not enough colors provided for #{} body_parms'.format(len(body_parms))) |
|
|
|
bs = body_parms[0]['pose_body'].shape[0] |
|
|
|
body_ids = np.random.choice(bs, num_bodies_to_display) |
|
|
|
body_evals = [c2c(bm(root_orient=v['root_orient'].view(bs, -1) if 'root_orient' in v else torch.zeros(bs, 3).type_as(v['pose_body']), |
|
pose_body=v['pose_body'].contiguous().view(bs, -1)).v) for v in body_parms] |
|
num_verts = body_evals[0].shape[1] |
|
|
|
render_meshes = [] |
|
for bId in body_ids: |
|
concat_cur_meshes = None |
|
for body, body_color in zip(body_evals, body_colors): |
|
cur_body_mesh = Mesh(body[bId], faces, vertex_colors=np.ones([num_verts, 3]) * body_color) |
|
concat_cur_meshes = cur_body_mesh if concat_cur_meshes is None else mesh_cat(concat_cur_meshes, cur_body_mesh) |
|
render_meshes.append(concat_cur_meshes) |
|
|
|
img = renderer(render_meshes) |
|
|
|
if out_fname is not None: imagearray2file(img, out_fname, fps=10) |
|
|
|
|
|
return |
|
|
|
return render_once |
|
|