Skip to content

Commit

Permalink
makes it work
Browse files Browse the repository at this point in the history
  • Loading branch information
Edward Smith committed Jan 30, 2019
1 parent 5ce267c commit f708deb
Show file tree
Hide file tree
Showing 12 changed files with 1,962 additions and 42 deletions.
Empty file added �GE@@8@@@ P P
Empty file.
1,928 changes: 1,928 additions & 0 deletions 386.obj

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions GEOMetrics.py
Expand Up @@ -47,15 +47,16 @@
modelA = MeshDeformationBlock(963)
modelB = MeshDeformationBlock(1155)
modelC = MeshDeformationBlock(1155)
encoder_mesh = MeshEncoder(100)
encoder_mesh = MeshEncoder(50)
modelA.cuda(), encoder1.cuda(), encoder2.cuda(),encoder3.cuda(), modelB.cuda(), modelC.cuda(), encoder_mesh.cuda()
params = list(modelA.parameters()) + list(encoder1.parameters()) + list(encoder2.parameters()) + list(encoder3.parameters()) +list(modelB.parameters()) +list(modelC.parameters())
optimizer = optim.Adam(params,lr=args.lr)

try:
encoder_mesh.load_state_dict(torch.load('checkpoint/'+ args.object + '/encoder'))
except:
print 'You forgot to load the auto-encoder'
print 'You forgot to train the auto-encoder'
exit()
if args.render:
modelA.load_state_dict(torch.load(checkpoint_dir + 'model_1'))
modelB.load_state_dict(torch.load(checkpoint_dir + 'model_2'))
Expand Down
14 changes: 7 additions & 7 deletions Loss_Comparison/loss_comparison.py
@@ -1,9 +1,12 @@
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(BASE_DIR)
sys.path.append(BASE_DIR + '../scripts/')
from __future__ import division
import os
import sys
BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASEDIR)
sys.path.append(BASEDIR + '/chamfer_distance/')

from collections import namedtuple
from utils import *

from torch.nn.parameter import Parameter


Expand Down Expand Up @@ -34,9 +37,6 @@ def forward(self, points):






def vert_to_point(p_vert, p_face, t_vert, t_face, num = 3):

pred_points = p_vert
Expand Down
15 changes: 14 additions & 1 deletion README.md
Expand Up @@ -16,7 +16,13 @@ There are 4 main ideas proposed in this project:
* An adaptive face splitting procedure which analyses local face curvature to encourage local complexity emerge.



This project runs with the following dependencies:
* python 2.7
* pytorch 0.4.0
* scipy
* matplotlib
* PIL
* tqdm

## Data Production
To produce the data needed to train and test the methods of this project use the 'data_prep.py' script. This will download CAD models from the core classes of the ShapeNet data set, produce the data require for the latent loss, sample the surface of each ground truth mesh, render the objects as images, and split all the data into training, validation and test sets. This script makes use of the binvoxer executable, so first call
Expand All @@ -39,6 +45,13 @@ python data_prep.py --object plane -no 1000
## Diffentiable Surface Losses
We introduce two new losses for reconstructing meshes. These losses are based of the idea of differentiating through the random selection of points on a triangular surface via the reparametrization trick. This allows the adoption of a chamfer loss comparing the samplings of ground truth and predicted mesh surfaces, which does not explicitly penalize the position of vertices. We call this the point-to-point loss. This idea also allows to the adoption of a more accurate loss which compares a sampled set of points to a surface directly, using the "3D point to triangle distance" algorithm. We call this the point-to-surface loss. We compare these two losses and to a loss which directly penalizes vertex position with respect to their ability to reconstruct surfaces, in the Loss_Comparison directory.

These functions require a python package to be built. To do this call:
```bash
python chamfer_distance/build.py
```



<p align="center">
<img src="images/loss_comparison.png" >
</p>
Expand Down
Empty file.
Binary file modified chamfer_distance/_ext/my_lib/_my_lib.so 100644 → 100755
Binary file not shown.
Empty file.
Empty file.
9 changes: 4 additions & 5 deletions data_prep.py
Expand Up @@ -24,8 +24,7 @@

parser = argparse.ArgumentParser(description='Dataset prep for image to 3D object super resolution')
parser.add_argument('-o','--object', default=['chair'], help='List of object classes to be used downloaded and converted.', nargs='+' )
parser.add_argument('-no','--num_objects', default=2, help='number of objects to be converted', type = int)
parser.add_argument('-l','--low', default=32, help='Low resolution value', type = int)
parser.add_argument('-no','--num_objects', default=10000, help='number of objects to be converted', type = int)
args = parser.parse_args()


Expand All @@ -47,7 +46,7 @@
wanted_classes.append(l)
print wanted_classes

debug_mode = True # change to make all of the called scripts print their errors and warnings
debug_mode = False # change to make all of the called scripts print their errors and warnings
if debug_mode:
io_redirect = ''
else:
Expand Down Expand Up @@ -186,7 +185,7 @@ def binvox():
commands =[]
count = 0
for d in tqdm(dirs):
command = './binvox ' + d + ' -d ' + str(32)+ ' -pb -cb -c -e' # this executable can be found at http://www.patrickmin.com/binvox/ ,
command = 'scripts/binvox ' + d + ' -d ' + str(32)+ ' -pb -cb -c -e' # this executable can be found at http://www.patrickmin.com/binvox/ ,
# -d x idicates resoltuion will be x by x by x , -pb is to stop the visualization, the rest of the commnads are to help make the object water tight
commands.append(command)
if count %20 == 0 and count != 0:
Expand Down Expand Up @@ -341,7 +340,7 @@ def calc_surface():
commands =[]
count = 0
for d in tqdm(dirs):
command = './binvox ' + d + ' -d ' + str(dims)+ ' -pb -cb -c -e' # this executable can be found at http://www.patrickmin.com/binvox/ ,
command = 'scripts/binvox ' + d + ' -d ' + str(dims)+ ' -pb -cb -c -e' # this executable can be found at http://www.patrickmin.com/binvox/ ,
# -d x idicates resoltuion will be x by x by x , -pb is to stop the visualization, the rest of the commnads are to help make the object water tight
commands.append(command)
if count %20 == 0 and count != 0:
Expand Down
Empty file modified scripts/binvox 100644 → 100755
Empty file.
33 changes: 6 additions & 27 deletions utils.py
@@ -1,4 +1,3 @@
import time
import argparse
import numpy as np
import torch
Expand All @@ -7,8 +6,6 @@
from torch.autograd import Variable
import sys
import os
import gc
import scipy.sparse as sp
import torch
from glob import glob
import scipy.io as sio
Expand All @@ -24,7 +21,7 @@
from tqdm import tqdm

#import chamfer distance
sys.path.insert(0,'chamfer_distance/')
sys.path.insert(0, "chamfer_distance/")
from modules.nnd import NNDModule
dist = NNDModule()
np.random.seed(2)
Expand Down Expand Up @@ -138,7 +135,6 @@ def adj_init(faces,num_verts):

# normalizes symetric, binary adj matrix such that sum of each row is 1
def normalize_adj(mx):
"""Row-normalize sparse matrix"""
rowsum = np.array(mx.sum(1))
r_inv = np.power(rowsum, -1).flatten()
r_inv[np.isinf(r_inv)] = 0.
Expand Down Expand Up @@ -291,13 +287,12 @@ def load_batch(self, size, images = False, ordered = False):
verts = mesh_info['verts']
verts= torch.FloatTensor(np.array(verts)).cuda()
faces = mesh_info['faces']
dist = mesh_info['orig_adj']
dist[np.where(dist > 0)] = 1.
dist = calc_dist( verts, dist)
dist = normalize_adj(dist)
adj = mesh_info['orig_adj']
adj[np.where(adj > 0)] = 1.
adj = normalize_adj(adj)

dist = torch.FloatTensor(dist).cuda()
adj_info={'adj': dist}
adj = torch.FloatTensor(adj).cuda()
adj_info={'adj': adj}
batch_verts.append(verts)
batch_faces.append(torch.LongTensor(np.array(faces)).cuda())
batch_adjs.append(adj_info)
Expand Down Expand Up @@ -325,22 +320,6 @@ def load_batch(self, size, images = False, ordered = False):
return batch


def calc_dist(verts, adj):
adj_maintained = torch.FloatTensor(adj).cuda()
adj = adj_maintained + torch.FloatTensor(np.eye(adj_maintained.shape[0])).cuda()

positions = torch.FloatTensor(np.array(verts)).cuda()
reshape_positions = positions.view(positions.shape[0], positions.shape[1], 1)
reshape_positions = reshape_positions.expand(positions.shape[0], positions.shape[1], positions.shape[0]).permute(0,2,1)
cross_positions = reshape_positions.permute(1,0,2)
dist = torch.sum((reshape_positions- cross_positions)**2, dim = 2)

dist = 1/dist
for k in range(verts.shape[0]):
dist[k,k] = torch.min(dist[k,dist[k].nonzero()])
dist = dist*adj
dist = (dist).data.cpu().numpy()
return dist


# graphs the training and validation information
Expand Down

0 comments on commit f708deb

Please sign in to comment.