|

楼主 |
发表于 2023-3-21 16:54:37
|
显示全部楼层
https://github.com/cleardusk/3DDFA_V2/issues/83 更改后,可以看到uv
- # coding: utf-8
- __author__ = 'cleardusk'
- import numpy as np
- import os.path as osp
- import scipy.io as sio
- from utils.io import _load
- from .tddfa_util import _to_ctype
- from .functions import get_suffix
- header_temp = """ply
- format ascii 1.0
- element vertex {}
- property float x
- property float y
- property float z
- element face {}
- property list uchar int vertex_indices
- end_header
- """
- make_abs_path = lambda fn: osp.join(osp.dirname(osp.realpath(__file__)), fn)
- def load_uv_coords(fp):
- C = sio.loadmat(fp)
- uv_coords = C['UV'].copy(order='C').astype(np.float32)
- return uv_coords
- def process_uv(uv_coords, uv_h=256, uv_w=256):
- uv_coords[:, 0] = uv_coords[:, 0] * (uv_w - 1)
- uv_coords[:, 1] = uv_coords[:, 1] * (uv_h - 1)
- uv_coords[:, 1] = uv_h - uv_coords[:, 1] - 1
- uv_coords = np.hstack((uv_coords, np.zeros((uv_coords.shape[0], 1), dtype=np.float32))) # add z
- return uv_coords
- g_uv_coords = load_uv_coords(make_abs_path('../configs/BFM_UV.mat'))
- indices = _load(make_abs_path('../configs/indices.npy')) # todo: handle bfm_slim
- g_uv_coords = g_uv_coords[indices, :]
- def ser_to_ply_single(ver_lst, tri, height, wfp, reverse=True):
- suffix = get_suffix(wfp)
- for i, ver in enumerate(ver_lst):
- wfp_new = wfp.replace(suffix, f'_{i + 1}{suffix}')
- n_vertex = ver.shape[1]
- n_face = tri.shape[0]
- header = header_temp.format(n_vertex, n_face)
- with open(wfp_new, 'w') as f:
- f.write(header + '\n')
- for i in range(n_vertex):
- x, y, z = ver[:, i]
- if reverse:
- f.write(f'{x:.2f} {height-y:.2f} {z:.2f}\n')
- else:
- f.write(f'{x:.2f} {y:.2f} {z:.2f}\n')
- for i in range(n_face):
- idx1, idx2, idx3 = tri[i] # m x 3
- if reverse:
- f.write(f'3 {idx3} {idx2} {idx1}\n')
- else:
- f.write(f'3 {idx1} {idx2} {idx3}\n')
- print(f'Dump tp {wfp_new}')
- def ser_to_ply_multiple(ver_lst, tri, height, wfp, reverse=True):
- n_ply = len(ver_lst) # count ply
- if n_ply <= 0:
- return
- n_vertex = ver_lst[0].shape[1]
- n_face = tri.shape[0]
- header = header_temp.format(n_vertex * n_ply, n_face * n_ply)
- with open(wfp, 'w') as f:
- f.write(header + '\n')
- for i in range(n_ply):
- ver = ver_lst[i]
- for j in range(n_vertex):
- x, y, z = ver[:, j]
- if reverse:
- f.write(f'{x:.2f} {height - y:.2f} {z:.2f}\n')
- else:
- f.write(f'{x:.2f} {y:.2f} {z:.2f}\n')
- for i in range(n_ply):
- offset = i * n_vertex
- for j in range(n_face):
- idx1, idx2, idx3 = tri[j] # m x 3
- if reverse:
- f.write(f'3 {idx3 + offset} {idx2 + offset} {idx1 + offset}\n')
- else:
- f.write(f'3 {idx1 + offset} {idx2 + offset} {idx3 + offset}\n')
- print(f'Dump tp {wfp}')
- def get_colors(img, ver):
- h, w, _ = img.shape
- ver[0, :] = np.minimum(np.maximum(ver[0, :], 0), w - 1) # x
- ver[1, :] = np.minimum(np.maximum(ver[1, :], 0), h - 1) # y
- ind = np.round(ver).astype(np.int32)
- colors = img[ind[1, :], ind[0, :], :] / 255. # n x 3
- return colors.copy()
- def ser_to_obj_single(img, ver_lst, tri, height, wfp):
- suffix = get_suffix(wfp)
- uv_coords = g_uv_coords
- n_face = tri.shape[0]
- for i, ver in enumerate(ver_lst):
- colors = get_colors(img, ver)
- n_vertex = ver.shape[1]
- wfp_new = wfp.replace(suffix, f'_{i + 1}{suffix}')
- with open(wfp_new, 'w') as f:
- for i in range(n_vertex):
- x, y, z = ver[:, i]
- f.write(
- f'v {x:.2f} {height - y:.2f} {z:.2f} {colors[i, 2]:.2f} {colors[i, 1]:.2f} {colors[i, 0]:.2f}\n')
- for i in range(n_vertex):
- x, y = uv_coords[:, i]
- f.write(
- f'vt {x:.2f} {height - y:.2f} {z:.2f}\n')
- for i in range(n_face):
- idx1, idx2, idx3 = tri[i] # m x 3
- f.write(f'f {idx3 + 1} {idx2 + 1} {idx1 + 1}\n')
- print(f'Dump tp {wfp_new}')
- def ser_to_obj_multiple(img, ver_lst, tri, height, wfp):
- n_obj = len(ver_lst) # count obj
- if n_obj <= 0:
- return
- uv_coords = g_uv_coords
- print(uv_coords)
- n_vertex = ver_lst[0].shape[1]
- n_face = tri.shape[0]
- with open(wfp, 'w') as f:
- for i in range(n_obj):
- ver = ver_lst[i]
- colors = get_colors(img, ver)
- print(ver)
- for j in range(n_vertex):
- x, y, z = ver[:, j]
- f.write(
- f'v {x:.2f} {height - y:.2f} {z:.2f} {colors[j, 2]:.2f} {colors[j, 1]:.2f} {colors[j, 0]:.2f}\n')
- for i in range(n_obj):
- ver = ver_lst[i]
-
- for j in range(n_vertex):
- x, y = uv_coords[j]
- f.write(
- f'vt {x:.6f} {y:.6f}\n')
- for i in range(n_obj):
- offset = i * n_vertex
- for j in range(n_face):
- idx1, idx2, idx3 = tri[j] # m x 3
- f.write(f'f {idx3 + 1 + offset}/{idx3 + 1 + offset} {idx2 + 1 + offset}/{idx2 + 1 + offset} {idx1 + 1 + offset}/{idx1 + 1 + offset}\n')
- print(f'Dump tp {wfp}')
- ser_to_ply = ser_to_ply_multiple # ser_to_ply_single
- ser_to_obj = ser_to_obj_multiple # ser_to_obj_multiple
复制代码 |
|