forked from noahcao/Pixel2Mesh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp2m.py
90 lines (72 loc) · 3.27 KB
/
p2m.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import torch
import torch.nn as nn
import torch.nn.functional as F
from models.backbones import get_backbone
from models.layers.gbottleneck import GBottleneck
from models.layers.gconv import GConv
from models.layers.gpooling import GUnpooling
from models.layers.gprojection import GProjection
class P2MModel(nn.Module):
def __init__(self, options, ellipsoid, camera_f, camera_c, mesh_pos):
super(P2MModel, self).__init__()
self.hidden_dim = options.hidden_dim
self.coord_dim = options.coord_dim
self.last_hidden_dim = options.last_hidden_dim
self.init_pts = nn.Parameter(ellipsoid.coord, requires_grad=False)
self.gconv_activation = options.gconv_activation
self.nn_encoder, self.nn_decoder = get_backbone(options)
self.features_dim = self.nn_encoder.features_dim + self.coord_dim
self.gcns = nn.ModuleList([
GBottleneck(6, self.features_dim, self.hidden_dim, self.coord_dim,
ellipsoid.adj_mat[0], activation=self.gconv_activation),
GBottleneck(6, self.features_dim + self.hidden_dim, self.hidden_dim, self.coord_dim,
ellipsoid.adj_mat[1], activation=self.gconv_activation),
GBottleneck(6, self.features_dim + self.hidden_dim, self.hidden_dim, self.last_hidden_dim,
ellipsoid.adj_mat[2], activation=self.gconv_activation)
])
self.unpooling = nn.ModuleList([
GUnpooling(ellipsoid.unpool_idx[0]),
GUnpooling(ellipsoid.unpool_idx[1])
])
# if options.align_with_tensorflow:
# self.projection = GProjection
# else:
# self.projection = GProjection
self.projection = GProjection(mesh_pos, camera_f, camera_c, bound=options.z_threshold,
tensorflow_compatible=options.align_with_tensorflow)
self.gconv = GConv(in_features=self.last_hidden_dim, out_features=self.coord_dim,
adj_mat=ellipsoid.adj_mat[2])
def forward(self, img):
batch_size = img.size(0)
img_feats = self.nn_encoder(img)
img_shape = self.projection.image_feature_shape(img)
init_pts = self.init_pts.data.unsqueeze(0).expand(batch_size, -1, -1)
# GCN Block 1
x = self.projection(img_shape, img_feats, init_pts)
x1, x_hidden = self.gcns[0](x)
# before deformation 2
x1_up = self.unpooling[0](x1)
# GCN Block 2
x = self.projection(img_shape, img_feats, x1)
x = self.unpooling[0](torch.cat([x, x_hidden], 2))
# after deformation 2
x2, x_hidden = self.gcns[1](x)
# before deformation 3
x2_up = self.unpooling[1](x2)
# GCN Block 3
x = self.projection(img_shape, img_feats, x2)
x = self.unpooling[1](torch.cat([x, x_hidden], 2))
x3, _ = self.gcns[2](x)
if self.gconv_activation:
x3 = F.relu(x3)
# after deformation 3
x3 = self.gconv(x3)
if self.nn_decoder is not None:
reconst = self.nn_decoder(img_feats)
else:
reconst = None
return {
"pred_coord": [x1, x2, x3],
"pred_coord_before_deform": [init_pts, x1_up, x2_up],
"reconst": reconst
}