Skip to content

Commit

Permalink
change structure
Browse files Browse the repository at this point in the history
  • Loading branch information
yfeng95 committed Oct 9, 2018
1 parent 6f16b69 commit ed40974
Show file tree
Hide file tree
Showing 27 changed files with 1,054 additions and 979 deletions.
16 changes: 10 additions & 6 deletions examples/1_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
sys.path.append('..')
import face3d
from face3d import mesh
from face3d import mesh_cython

# ------------------------------ 1. load mesh data
# -- mesh data consists of: vertices, triangles, color(optinal), texture(optional)
Expand Down Expand Up @@ -50,11 +49,16 @@
# change to image coords for rendering
image_vertices = mesh.transform.to_image(projected_vertices, h, w)
# render
rendering = face3d.mesh_cython.render.render_colors(image_vertices, triangles, lit_colors, h, w)
rendering = mesh.render.render_colors(image_vertices, triangles, lit_colors, h, w)

# ---- show rendering
plt.imshow(rendering)
plt.show()
# plt.imshow(rendering)
# plt.show()
save_folder = 'results/pipeline'
if not os.path.exists(save_folder):
os.mkdir(save_folder)
io.imsave('{}/rendering.jpg'.format(save_folder), rendering)

# ---- show mesh
mesh.vis.plot_mesh(camera_vertices, triangles)
plt.show()
# mesh.vis.plot_mesh(camera_vertices, triangles)
# plt.show()
7 changes: 3 additions & 4 deletions examples/2_3dmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
sys.path.append('..')
import face3d
from face3d import mesh
from face3d import mesh_cython
from face3d.morphable_model import MorphabelModel

# --------------------- Forward: parameters(shape, expression, pose) --> 3D obj --> 2D image ---------------
Expand Down Expand Up @@ -41,7 +40,7 @@
# set prop of rendering
h = w = 256; c = 3
image_vertices = mesh.transform.to_image(projected_vertices, h, w)
image = mesh_cython.render.render_colors(image_vertices, bfm.triangles, colors, h, w)
image = mesh.render.render_colors(image_vertices, bfm.triangles, colors, h, w)

# -------------------- Back: 2D image points and corresponding 3D vertex indices--> parameters(pose, shape, expression) ------
## only use 68 key points to fit
Expand All @@ -56,7 +55,7 @@
transformed_vertices = bfm.transform(fitted_vertices, fitted_s, fitted_angles, fitted_t)

image_vertices = mesh.transform.to_image(transformed_vertices, h, w)
fitted_image = mesh_cython.render.render_colors(image_vertices, bfm.triangles, colors, h, w)
fitted_image = mesh.render.render_colors(image_vertices, bfm.triangles, colors, h, w)


# ------------- print & show
Expand All @@ -81,7 +80,7 @@
transformed_vertices = bfm.transform(fitted_vertices, fitted_s[i], fitted_angles[i], fitted_t[i])

image_vertices = mesh.transform.to_image(transformed_vertices, h, w)
fitted_image = mesh_cython.render.render_colors(image_vertices, bfm.triangles, colors, h, w)
fitted_image = mesh.render.render_colors(image_vertices, bfm.triangles, colors, h, w)
io.imsave('{}/show_{:0>2d}.jpg'.format(save_folder, i), fitted_image)

options = '-delay 20 -loop 0 -layers optimize' # gif. need ImageMagick.
Expand Down
4 changes: 1 addition & 3 deletions examples/3_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
sys.path.append('..')
import face3d
from face3d import mesh
from face3d import mesh_cython


def transform_test(vertices, obj, camera, h = 256, w = 256):
'''
Expand All @@ -35,7 +33,7 @@ def transform_test(vertices, obj, camera, h = 256, w = 256):
## to image coords(position in image)
image_vertices = mesh.transform.to_image(projected_vertices, h, w, True)

rendering = mesh_cython.render.render_colors(image_vertices, triangles, colors, h, w)
rendering = mesh.render.render_colors(image_vertices, triangles, colors, h, w)
rendering = np.minimum((np.maximum(rendering, 0)), 1)
return rendering

Expand Down
6 changes: 2 additions & 4 deletions examples/4_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@
sys.path.append('..')
import face3d
from face3d import mesh
from face3d import mesh_cython


def light_test(vertices, light_positions, light_intensities, h = 256, w = 256):
lit_colors = mesh_cython.light.add_light(vertices, triangles, colors, light_positions, light_intensities)
lit_colors = mesh.light.add_light(vertices, triangles, colors, light_positions, light_intensities)
image_vertices = mesh.transform.to_image(vertices, h, w)
rendering = mesh_cython.render.render_colors(image_vertices, triangles, lit_colors, h, w)
rendering = mesh.render.render_colors(image_vertices, triangles, lit_colors, h, w)
rendering = np.minimum((np.maximum(rendering, 0)), 1)
return rendering

Expand Down
65 changes: 43 additions & 22 deletions examples/5_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
sys.path.append('..')
import face3d
from face3d import mesh
from face3d import mesh_cython
from face3d import mesh_numpy
from face3d.morphable_model import MorphabelModel

# load data
Expand All @@ -30,19 +30,19 @@
image_vertices = mesh.transform.to_image(vertices, h, w)

# -----------------------------------------render colors
# render colors python
# render colors python numpy
st = time()
rendering_cp = face3d.mesh.render.render_colors(image_vertices, triangles, colors, h, w)
rendering_cp = mesh_numpy.render.render_colors(image_vertices, triangles, colors, h, w)
print('----------colors python: ', time() - st)

# render colors python ras
# render colors python ras numpy
st = time()
rendering_cpr = face3d.mesh.render.render_colors_ras(image_vertices, triangles, colors, h, w)
rendering_cpr = mesh_numpy.render.render_colors_ras(image_vertices, triangles, colors, h, w)
print('----------colors python ras: ', time() - st)

# render colors python c++
st = time()
rendering_cc = face3d.mesh_cython.render.render_colors(image_vertices, triangles, colors, h, w)
rendering_cc = mesh.render.render_colors(image_vertices, triangles, colors, h, w)
print('----------colors c++: ', time() - st)

# ----------------------------------------- render texture(texture mapping)
Expand All @@ -51,30 +51,51 @@
texture = io.imread('Data/uv_texture_map.jpg')/255.
tex_h, tex_w, _ = texture.shape
# load texcoord(uv coords)
uv_coords = face3d.morphable_model.load.load_uv_coords('Data/BFM/Out/BFM_UV.mat') #
uv_coords[:,0] = uv_coords[:,0]*(tex_h - 1)
uv_coords[:,1] = uv_coords[:,1]*(tex_w - 1)
uv_coords[:,1] = tex_w - uv_coords[:,1] - 1
texcoord = np.hstack((uv_coords, np.zeros((uv_coords.shape[0], 1)))) # add z# render texture python
uv_coords = face3d.morphable_model.load.load_uv_coords('Data/BFM/Out/BFM_UV.mat') # general UV coords: range [0-1]
# to texture size
texcoord = np.zeros_like(uv_coords)
texcoord[:,0] = uv_coords[:,0]*(tex_h - 1)
texcoord[:,1] = uv_coords[:,1]*(tex_w - 1)
texcoord[:,1] = tex_w - texcoord[:,1] - 1
texcoord = np.hstack((texcoord, np.zeros((texcoord.shape[0], 1)))) # add z# render texture python
# tex_triangles
tex_triangles = triangles

# render texture python
st = time()
rendering_tp = face3d.mesh.render.render_texture(image_vertices, triangles, texture, texcoord, tex_triangles, h, w)
rendering_tp = face3d.mesh_numpy.render.render_texture(image_vertices, triangles, texture, texcoord, tex_triangles, h, w)
print('----------texture python: ', time() - st)

# render texture c++
st = time()
rendering_tc = face3d.mesh_cython.render.render_texture(image_vertices, triangles, texture, texcoord, tex_triangles, h, w)
rendering_tc = face3d.mesh.render.render_texture(image_vertices, triangles, texture, texcoord, tex_triangles, h, w)
print('----------texture c++: ', time() - st)
plt.subplot(2,2,1)
plt.imshow(rendering_cp)
plt.subplot(2,2,2)
plt.imshow(rendering_cc)
plt.subplot(2,2,3)
plt.imshow(rendering_tp)
plt.subplot(2,2,4)
plt.imshow(rendering_tc)
plt.show()

# plot
# plt.subplot(2,2,1)
# plt.imshow(rendering_cp)
# plt.subplot(2,2,2)
# plt.imshow(rendering_cc)
# plt.subplot(2,2,3)
# plt.imshow(rendering_tp)
# plt.subplot(2,2,4)
# plt.imshow(rendering_tc)
# plt.show()


## --------------------------- write obj
# mesh.vis.plot_mesh(vertices, triangles)
# plt.show()
save_folder = os.path.join('results', 'io')
if not os.path.exists(save_folder):
os.mkdir(save_folder)

vertices, colors, uv_coords = image_vertices.astype(np.float32).copy(), colors.astype(np.float32).copy(), uv_coords.astype(np.float32).copy()

st = time()
mesh_numpy.io.write_obj_with_colors_texture(os.path.join(save_folder, 'numpy.obj'), vertices, triangles, colors, texture, uv_coords)
print('----------write obj numpy: ', time() - st)

st = time()
mesh.io.write_obj_with_colors_texture(os.path.join(save_folder, 'cython.obj'), vertices, triangles, colors, texture, uv_coords)
print('----------write obj cython: ', time() - st)
9 changes: 4 additions & 5 deletions examples/6_generate_image_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
sys.path.append('..')
import face3d
from face3d import mesh
from face3d import mesh_cython

# ------------------------------ load mesh data
C = sio.loadmat('Data/example1.mat')
Expand Down Expand Up @@ -41,27 +40,27 @@

## 0. color map
attribute = colors
color_image = mesh_cython.render.render_colors(image_vertices, triangles, attribute, h, w, c=3)
color_image = mesh.render.render_colors(image_vertices, triangles, attribute, h, w, c=3)
io.imsave('{}/color.jpg'.format(save_folder), np.squeeze(color_image))

## 1. depth map
z = image_vertices[:,2:]
z = z - np.min(z)
z = z/np.max(z)
attribute = z
depth_image = mesh_cython.render.render_colors(image_vertices, triangles, attribute, h, w, c=1)
depth_image = mesh.render.render_colors(image_vertices, triangles, attribute, h, w, c=1)
io.imsave('{}/depth.jpg'.format(save_folder), np.squeeze(depth_image))

## 2. pncc in 'Face Alignment Across Large Poses: A 3D Solution'. for dense correspondences
pncc = face3d.morphable_model.load.load_pncc_code('Data/BFM/Out/pncc_code.mat')
attribute = pncc
pncc_image = mesh_cython.render.render_colors(image_vertices, triangles, attribute, h, w, c=3)
pncc_image = mesh.render.render_colors(image_vertices, triangles, attribute, h, w, c=3)
io.imsave('{}/pncc.jpg'.format(save_folder), np.squeeze(pncc_image))

## 3. uv coordinates in 'DenseReg: Fully convolutional dense shape regression in-the-wild'. for dense correspondences
uv_coords = face3d.morphable_model.load.load_uv_coords('Data/BFM/Out/BFM_UV.mat') #
attribute = uv_coords # note that: original paper used quantized coords, here not
uv_coords_image = mesh_cython.render.render_colors(image_vertices, triangles, attribute, h, w, c=2) # two channels: u, v
uv_coords_image = mesh.render.render_colors(image_vertices, triangles, attribute, h, w, c=2) # two channels: u, v
# add one channel for show
uv_coords_image = np.concatenate((np.zeros((h, w, 1)), uv_coords_image), 2)
io.imsave('{}/uv_coords.jpg'.format(save_folder), np.squeeze(uv_coords_image))
Expand Down
7 changes: 3 additions & 4 deletions examples/7_generate_uv_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
sys.path.append('..')
import face3d
from face3d import mesh
from face3d import mesh_cython
from face3d.morphable_model import MorphabelModel

def process_uv(uv_coords, uv_h = 256, uv_w = 256):
Expand Down Expand Up @@ -47,7 +46,7 @@ def process_uv(uv_coords, uv_h = 256, uv_w = 256):

#-- 1. uv texture map
attribute = colors
uv_texture_map = mesh_cython.render.render_colors(uv_coords, triangles, attribute, uv_h, uv_w, c=3)
uv_texture_map = mesh.render.render_colors(uv_coords, triangles, attribute, uv_h, uv_w, c=3)
io.imsave('{}/uv_texture_map.jpg'.format(save_folder), np.squeeze(uv_texture_map))

#-- 2. uv position map in 'Joint 3D Face Reconstruction and Dense Alignment with Position Map Regression Network'
Expand All @@ -61,8 +60,8 @@ def process_uv(uv_coords, uv_h = 256, uv_w = 256):
position[:,2] = position[:,2] - np.min(position[:,2]) # translate z
attribute = position
# corresponding 2d facial image
image = mesh_cython.render.render_colors(image_vertices, triangles, colors, image_h, image_w, c=3)
uv_position_map = mesh_cython.render.render_colors(uv_coords, triangles, attribute, uv_h, uv_w, c=3)
image = mesh.render.render_colors(image_vertices, triangles, colors, image_h, image_w, c=3)
uv_position_map = mesh.render.render_colors(uv_coords, triangles, attribute, uv_h, uv_w, c=3)
io.imsave('{}/image.jpg'.format(save_folder), np.squeeze(image))
np.save('{}/uv_position_map.npy'.format(save_folder), uv_position_map)
io.imsave('{}/uv_position_map.jpg'.format(save_folder), (uv_position_map)/max(image_h, image_w)) # only for show
Expand Down
3 changes: 1 addition & 2 deletions examples/8_generate_posmap_300WLP.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
sys.path.append('..')
import face3d
from face3d import mesh
from face3d import mesh_cython
from face3d.morphable_model import MorphabelModel

def process_uv(uv_coords, uv_h = 256, uv_w = 256):
Expand Down Expand Up @@ -76,7 +75,7 @@ def run_posmap_300W_LP(bfm, image_path, mat_path, save_folder, uv_h = 256, uv_w
position[:, 2] = position[:, 2] - np.min(position[:, 2]) # translate z

# 4. uv position map: render position in uv space
uv_position_map = mesh_cython.render.render_colors(uv_coords, bfm.full_triangles, position, uv_h, uv_w, c = 3)
uv_position_map = mesh.render.render_colors(uv_coords, bfm.full_triangles, position, uv_h, uv_w, c = 3)

# 5. save files
io.imsave('{}/{}'.format(save_folder, image_name), np.squeeze(cropped_image))
Expand Down
2 changes: 1 addition & 1 deletion examples/Data/BFM/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

1. Download raw BFM model

website: https://faces.cs.unibas.ch/bfm/index.php?nav=1-0&id=basel_face_model.
website: https://faces.dmi.unibas.ch/bfm/main.php?nav=1-2&id=downloads

copy 01_MorphabelModel.mat to raw/

Expand Down
1 change: 0 additions & 1 deletion face3d/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
from . import mesh
from . import mesh_cython
from . import morphable_model
5 changes: 1 addition & 4 deletions face3d/mesh/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from .cython import mesh_core_cython
from . import io
from . import vis
from . import transform
Expand Down
38 changes: 11 additions & 27 deletions face3d/mesh/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
from __future__ import print_function

import numpy as np
import os
from skimage import io
from time import time

from .cython import mesh_core_cython

## TODO
## TODO: c++ version
Expand Down Expand Up @@ -104,15 +108,15 @@ def write_obj_with_texture(obj_name, vertices, triangles, texture, uv_coords):
# write texture as png
imsave(texture_name, texture)


def write_obj_with_colors_texture(obj_name, vertices, colors, triangles, texture, uv_coords):
# c++ version
def write_obj_with_colors_texture(obj_name, vertices, triangles, colors, texture, uv_coords):
''' Save 3D face model with texture.
Ref: https://github.com/patrikhuber/eos/blob/bd00155ebae4b1a13b08bf5a991694d682abbada/include/eos/core/Mesh.hpp
Args:
obj_name: str
vertices: shape = (nver, 3)
colors: shape = (nver, 3)
triangles: shape = (ntri, 3)
colors: shape = (nver, 3)
texture: shape = (256,256,3)
uv_coords: shape = (nver, 3) max value<=1
'''
Expand All @@ -125,34 +129,14 @@ def write_obj_with_colors_texture(obj_name, vertices, colors, triangles, texture
triangles += 1 # mesh lab start with 1

# write obj
with open(obj_name, 'w') as f:
# first line: write mtlib(material library)
s = "mtllib {}\n".format(os.path.abspath(mtl_name))
f.write(s)

# write vertices
for i in range(vertices.shape[0]):
s = 'v {} {} {} {} {} {}\n'.format(vertices[i, 0], vertices[i, 1], vertices[i, 2], colors[i, 0], colors[i, 1], colors[i, 2])
f.write(s)

# write uv coords
for i in range(uv_coords.shape[0]):
s = 'vt {} {}\n'.format(uv_coords[i,0], 1 - uv_coords[i,1])
f.write(s)

f.write("usemtl FaceTexture\n")

# write f: ver ind/ uv ind
for i in range(triangles.shape[0]):
# s = 'f {}/{} {}/{} {}/{}\n'.format(triangles[i,0], triangles[i,0], triangles[i,1], triangles[i,1], triangles[i,2], triangles[i,2])
s = 'f {}/{} {}/{} {}/{}\n'.format(triangles[i,2], triangles[i,2], triangles[i,1], triangles[i,1], triangles[i,0], triangles[i,0])
f.write(s)

vertices, colors, uv_coords = vertices.astype(np.float32).copy(), colors.astype(np.float32).copy(), uv_coords.astype(np.float32).copy()
mesh_core_cython.write_obj_with_colors_texture_core(str.encode(obj_name), str.encode(os.path.abspath(mtl_name)), vertices, triangles, colors, uv_coords, vertices.shape[0], triangles.shape[0], uv_coords.shape[0])

# write mtl
with open(mtl_name, 'w') as f:
f.write("newmtl FaceTexture\n")
s = 'map_Kd {}\n'.format(os.path.abspath(texture_name)) # map to image
f.write(s)

# write texture as png
imsave(texture_name, texture)
io.imsave(texture_name, texture)
Loading

0 comments on commit ed40974

Please sign in to comment.