| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| from typing import Literal |
| import tyro |
| import numpy as np |
| from PIL import Image |
| from pathlib import Path |
| import torch |
| import nvdiffrast.torch as dr |
| from vhap.util.render_uvmap import render_uvmap_vtex |
| from vhap.model.flame import FlameHead |
|
|
|
|
| FLAME_UV_MASK_FOLDER = "asset/flame/uv_masks" |
| FLAME_UV_MASK_NPZ = "asset/flame/uv_masks.npz" |
|
|
|
|
| def main( |
| use_opengl: bool = False, |
| device: Literal['cuda', 'cpu'] = 'cuda', |
| ): |
| n_shape = 300 |
| n_expr = 100 |
| print("Initializing FLAME model") |
| flame_model = FlameHead(n_shape, n_expr, add_teeth=True) |
|
|
| flame_model = FlameHead( |
| n_shape, |
| n_expr, |
| add_teeth=True, |
| ).cuda() |
|
|
| faces = flame_model.faces.int().cuda() |
| verts_uv = flame_model.verts_uvs.cuda() |
| |
| faces_uv = flame_model.textures_idx.int().cuda() |
| col_idx = faces_uv |
|
|
| |
| glctx = dr.RasterizeGLContext() if use_opengl else dr.RasterizeCudaContext() |
|
|
| h, w = 2048, 2048 |
| resolution = (h, w) |
|
|
| if not Path(FLAME_UV_MASK_FOLDER).exists(): |
| Path(FLAME_UV_MASK_FOLDER).mkdir(parents=True) |
| |
| |
| masks = {} |
| for region, vt_mask in flame_model.mask.vt: |
| v_color = torch.zeros(verts_uv.shape[0], 1).to(device) |
| v_color[vt_mask] = 1 |
|
|
| alpha = render_uvmap_vtex(glctx, verts_uv, faces_uv, v_color, col_idx, resolution)[0] |
| alpha = alpha.flip(0) |
| |
| mask = (alpha > 0.5) |
| mask = mask.squeeze(-1).cpu().numpy() |
| masks[region] = mask |
|
|
| print(f"Saving uv mask for {region}...") |
| |
| |
| |
| img = mask |
| img = Image.fromarray((img * 255).astype(np.uint8)) |
| img.save(Path(FLAME_UV_MASK_FOLDER) / f"{region}.png") |
| |
| print(f"Saving uv mask into: {FLAME_UV_MASK_NPZ}") |
| np.savez_compressed(FLAME_UV_MASK_NPZ, **masks) |
|
|
|
|
| if __name__ == "__main__": |
| tyro.cli(main) |