Team Ai
Apppublic

OpenMotionLab/MotionGPT

sourceHugging Facemitupdated 1y agoView on Hugging Face
118likes
renderer.py180 linesDownload Raw Back to render
1"""2This script is borrowed from https://github.com/mkocabas/VIBE3 Adhere to their licence to use this script4 It has been modified5"""6 7import os8import math9import trimesh10 11import pyrender12import numpy as np13from pyrender.constants import RenderFlags14 15 16# os.environ['DISPLAY'] = ':0.0'17# os.environ['PYOPENGL_PLATFORM'] = 'egl'18# os.environ['PYOPENGL_PLATFORM'] = 'osmesa'19SMPL_MODEL_DIR = "data/smpl_data/"20 21 22def get_smpl_faces():23    return np.load(os.path.join(SMPL_MODEL_DIR, "smplfaces.npy"))24 25 26class WeakPerspectiveCamera(pyrender.Camera):27    def __init__(self,28                 scale,29                 translation,30                 znear=pyrender.camera.DEFAULT_Z_NEAR,31                 zfar=None,32                 name=None):33        super(WeakPerspectiveCamera, self).__init__(34            znear=znear,35            zfar=zfar,36            name=name,37        )38        self.scale = scale39        self.translation = translation40 41    def get_projection_matrix(self, width=None, height=None):42        P = np.eye(4)43        P[0, 0] = self.scale[0]44        P[1, 1] = self.scale[1]45        P[0, 3] = self.translation[0] * self.scale[0]46        P[1, 3] = -self.translation[1] * self.scale[1]47        P[2, 2] = -148        return P49 50 51class Renderer:52    def __init__(self, background=None, resolution=(224, 224), bg_color=[0, 0, 0, 0.5], orig_img=False, wireframe=False, cam_pose=np.eye(4)):53        width, height = resolution54        self.background = np.zeros((height, width, 3))55        self.resolution = resolution56 57        self.faces = get_smpl_faces()58        self.orig_img = orig_img59        self.wireframe = wireframe60        self.renderer = pyrender.OffscreenRenderer(61            viewport_width=self.resolution[0],62            viewport_height=self.resolution[1],63            point_size=0.564        )65 66        # set the scene67        self.scene = pyrender.Scene(bg_color=bg_color, ambient_light=(0.4, 0.4, 0.4))68 69        light = pyrender.PointLight(color=[1.0, 1.0, 1.0], intensity=4)70    71 72        light_pose = np.eye(4)73        light_pose[:3, 3] = [0, -1, 1]74        self.scene.add(light, pose=np.dot(cam_pose,light_pose).copy())75 76        light_pose[:3, 3] = [0, 1, 1]77        self.scene.add(light, pose=np.dot(cam_pose,light_pose).copy())78 79        light_pose[:3, 3] = [1, 1, 2]80        self.scene.add(light, pose=np.dot(cam_pose,light_pose).copy())81 82        """ok83        light_pose = np.eye(4)84        light_pose[:3, 3] = [0, -1, 1]85        self.scene.add(light, pose=light_pose)86 87        light_pose[:3, 3] = [0, 1, 1]88        self.scene.add(light, pose=light_pose)89 90        light_pose[:3, 3] = [1, 1, 2]91        self.scene.add(light, pose=light_pose)92        """93 94        # light_pose[:3, 3] = [0, -2, 2]95        # [droite, hauteur, profondeur camera]96        """97        light_pose = np.eye(4)98        light_pose[:3, 3] = [0, -1, 1]99        self.scene.add(light, pose=light_pose)100 101        light_pose[:3, 3] = [0, 1, 1]102        self.scene.add(light, pose=light_pose)103 104        light_pose[:3, 3] = [1, 1, 2]105        self.scene.add(light, pose=light_pose)106        """107 108    def render(self, img, verts, cam, angle=None, axis=None, mesh_filename=None, color=[1.0, 1.0, 0.9],109               cam_pose=np.eye(4)):110        mesh = trimesh.Trimesh(vertices=verts, faces=self.faces, process=False)111        Rx = trimesh.transformations.rotation_matrix(math.radians(180), [1, 0, 0])112        # Rx = trimesh.transformations.rotation_matrix(math.radians(-90), [1, 0, 0])113        mesh.apply_transform(Rx)114 115        if mesh_filename is not None:116            mesh.export(mesh_filename)117 118        if angle and axis:119            R = trimesh.transformations.rotation_matrix(math.radians(angle), axis)120            mesh.apply_transform(R)121 122        sx, sy, tx, ty = cam123 124        camera = WeakPerspectiveCamera(125            scale=[sx, sy],126            translation=[tx, ty],127            zfar=100000.128        )129 130        material = pyrender.MetallicRoughnessMaterial(131            metallicFactor=0.0, # 0.0 for no specular lighting132            # metallicFactor=0.7, # 0.0 for no specular lighting133            alphaMode='OPAQUE',134            baseColorFactor=(color[0], color[1], color[2], 1.0)135        )136 137        mesh = pyrender.Mesh.from_trimesh(mesh, material=material)138 139        mesh_node = self.scene.add(mesh, 'mesh')140 141        cam_node = self.scene.add(camera, pose=cam_pose)142 143        if self.wireframe:144            render_flags = RenderFlags.RGBA | RenderFlags.ALL_WIREFRAME145        else:146            render_flags = RenderFlags.RGBA147 148        rgb, _ = self.renderer.render(self.scene, flags=render_flags)149        if rgb.shape[-1]==3:150            # Debug151            # 0 not distinguish alpha152            valid_mask = (rgb[:, :, -1] > 0)[:, :, np.newaxis]153            output_img = rgb * valid_mask + (1 - valid_mask) * img154        elif rgb.shape[-1]==4:155            # valid_mask = (rgb[:, :, -1] > 128)[:, :, np.newaxis]156            # output_img = rgb[:, :, :-1] * valid_mask + (1 - valid_mask) * img157 158            # # output alpha159            valid_mask = (rgb[:, :, -1] > 128)[:, :]160            output_img = np.copy(rgb)161            output_img[:, :, -1] *= valid_mask           162            # output_img = img163        else:164            raise ValueError(f"rgb shape {rgb.shape[-1]} is not correct!")165        image = output_img.astype(np.uint8)166 167        self.scene.remove_node(mesh_node)168        self.scene.remove_node(cam_node)169 170        return image171 172 173def get_renderer(width, height, cam_pose):174    renderer = Renderer(resolution=(width, height),175                        bg_color=[1, 1, 1, 0.5],176                        orig_img=False,177                        wireframe=False,178                        cam_pose=cam_pose)179    return renderer180