AaronJackson / vrn

:man: Code for "Large Pose 3D Face Reconstruction from a Single Image via Direct Volumetric CNN Regression"
http://aaronsplace.co.uk/papers/jackson2017recon/
MIT License
4.51k stars 744 forks source link

XYZ export of the volume data for mesh reconstruction #7

Closed obbenb closed 6 years ago

obbenb commented 6 years ago

I wanted to share a simple script based on vis.py to save the volume to an xyz file with color. Later meshlab could be used to reconstruct the surface. The steps are

  1. Export the volume to xyz file using below script: python export_xyz.py --volume volumename --image imagename --xyz xyz.txt
  2. Use meshlab to import txt file as X Y Z R G B file
  3. Filters ->Normals -> Compute Normals for point sets
  4. Filters -> Remeshing -> Surface reconstruct Poisson
  5. Filters -> Texture -> Parametrization: Trivial Per-Triangle
  6. Filters -> Texture -> Transfer Vertex Attributes to Texture

I have also done vertex color transfer, but I'm not sure if it was necessary. After the transfer, the number of vertices can be reduced to have a smaller model.

Regarding the script, I didn't want to add it to vis.py since it would need further changes to differentiate visvis display vs xyz output etc.

import numpy as np import visvis as vv import argparse

parser = argparse.ArgumentParser(description='Export the 3D volume')

parser.add_argument('--volume', dest='volume', help="The volume to render") parser.add_argument('--image', dest='image', help="The background image to display") parser.add_argument('--xyz', dest='xyz', help="XYZ file to export") args = parser.parse_args()

vol = np.fromfile(args.volume, dtype=np.int8) vol = vol.reshape((200,192,192))

im = vv.imread(args.image)

f = open(args.xyz, 'w') for z in range(0,200): for y in range(0,192): for x in range(0,192): if(vol[z][y][x]>1): f.write(str(z)+";"+str(-y)+";"+str(x)+";"+ str(im[y,x,0])+";"+str(im[y,x,1])+";"+str(im[y,x,2])+ "\n") f.close()

obbenb commented 6 years ago

I have updated it to output the vertices in wavefront object file format. Looks like meshlabserver do not understand xyzrgb format. The changed file is below (I cannot attach the file).


Public Domain

Run at your own risk, absolutely no guarantees about the script's behavior

import numpy as np import visvis as vv import argparse

parser = argparse.ArgumentParser(description='Export the 3D volume')

parser.add_argument('--volume', dest='volume', help="The volume to render") parser.add_argument('--image', dest='image', help="The background image to display") parser.add_argument('--xyz', dest='xyz', help="XYZ file to export")

parser.add_argument('--obj', dest='obj', help="obj file to export")

args = parser.parse_args()

vol = np.fromfile(args.volume, dtype=np.int8) vol = vol.reshape((200,192,192))

im = vv.imread(args.image)

if(args.xyz is not None): xyz = open(args.xyz, 'w') print("Exporting to XYZ: "+args.xyz) if(args.obj is not None): obj = open(args.obj, 'w') print("Exporting to OBJ: " + args.obj)

for z in range(0,200): for y in range(0,192): for x in range(0,192): if(vol[z][y][x]>1): if (args.xyz is not None): xyz.write(str(z)+";"+str(-y)+";"+str(x)+";"+ str(im[y,x,0])+";"+str(im[y,x,1])+";"+str(im[y,x,2])+ "\n") if (args.obj is not None): obj.write("v "+str(z) + " " + str(-y) + " " + str(x) + " " + "%f"%(im[y, x, 0]/256) + " " + "%f"%(im[y, x, 1]/256) + " " + "%f"%(im[y, x, 2]/256) + "\n")

if(args.xyz is not None): xyz.close() if(args.obj is not None): obj.close()

AaronJackson commented 6 years ago

Hi @obbenb. Thanks! I am going to close this as it is not actually an issue. However, people will still be able to find it under closed issues and I will refer people to this page if anyone asks about it.

hdjsjyl commented 6 years ago

Hi, @obbenb, I can not use meshlab import .txt file. Can you add some pictures about the steps of reconstructing surface? THank you very much.

AaronJackson commented 6 years ago

@hdjsjyl I have committed the Python code I use to extract the obj file from the f536adf23907282aa26c6b844dc6875d5412553d It depends on PyMCubes which should be easy enough to install. It's not quite as nice as the MATLAB version since it results in a slightly blocky mesh, but good enough for most purposes.

hdjsjyl commented 6 years ago

@AaronJackson , Thanks for your reply. I think in your paper, the shape should be (192,192,200)->(x,y,z), why this script reshapes the volumn to (200,192,192)->(z,y,x)? Moreover, when saving the vertices, it saves(z,-y,x), why not save(x,y,z)? I have no idea about this. Can you explain to me? What's more, how to get the frontalised output, because we want to compare your 3D model with our 3D model. Thank you.

AaronJackson commented 6 years ago

It's because python loads row first where as MATLAB loads column first. If you are making comparisons please use the MATLAB version since the python version was not used to calculate errors in the paper. The method does not output give a frontal face, instead it gives an aligned face. You would need to use some groundtruth pose parameters if you want to do that.

On 25 October 2017 16:26:22 CEST, hdjsjyl notifications@github.com wrote:

@AaronJackson , Thanks for your reply. I think in your paper, the shape should be (192,192,200)->(x,y,z), why this script reshapes the volumn to (200,192,192)->(z,y,x)? Moreover, when saving the vertices, it saves(z,-y,x), why not save(x,y,z)? I have no idea about this. Can you explain to me? What's more, how to get the frontalised output, because we want to compare your 3D model with our 3D model. Thank you.

-- Sent from my Android device with K-9 Mail. Please excuse my brevity.

hdjsjyl commented 6 years ago

@AaronJackson ,I mean that how to get the third column model in the following picture: 3d_model

AaronJackson commented 6 years ago

We used the groundtruth pose parameters from 3DDFA.

hdjsjyl commented 6 years ago

@AaronJackson , Thank you very much, I will try.