Compare commits

...
2 Commits
Author SHA1 Message Date
luni 581a5b2af2 add new view definition to dataset 2023-01-14 18:25:01 +00:00
luni 35928ccbff ca;cu;ate normal error with chamfer 2023-01-14 18:24:30 +00:00
2 changed files with 36 additions and 15 deletions
+24 -5
View File
@@ -7,6 +7,7 @@ import math
import time import time
import torch import torch
import kornia import kornia
import pytorch3d
import torchvision as tv import torchvision as tv
import numpy as np import numpy as np
import scipy.io as sio import scipy.io as sio
@@ -53,9 +54,12 @@ class Dataset(Dataset):
path = os.path.join(self.folder, frame.id) path = os.path.join(self.folder, frame.id)
info = self.reader.read_info(frame.id) info = self.reader.read_info(frame.id)
zrot = info['zrot'] if not self.random_view else (((np.random.random(1) * 2) -1) * np.pi)[0] zrot = info['zrot'] # if not self.random_view else (((np.random.random(1) * 2) -1) * np.pi)[0]
trans = info['trans'][:,frame.frame_nr]
# mesh_posed = readPC2Frame(os.path.join(path, frame.garment + '_registered.pc16'), frame.frame_nr, True) # mesh_posed = readPC2Frame(os.path.join(path, frame.garment + '_registered.pc16'), frame.frame_nr, True)
mesh_posed = self.reader.read_garment_vertices(frame.id, frame.garment, frame.frame_nr, info['trans'][:,frame.frame_nr], zrot)
mesh_posed = self.reader.read_garment_vertices(frame.id, frame.garment, frame.frame_nr, trans, zrot)
mesh_posed = torch.tensor(mesh_posed, device=self.device)
# mesh_posed_no_trans = self.reader.read_garment_vertices(frame.id, frame.garment, frame.frame_nr, absolute=False) # mesh_posed_no_trans = self.reader.read_garment_vertices(frame.id, frame.garment, frame.frame_nr, absolute=False)
mesh_mask = np.load(os.path.join(path, frame.garment + '_mask.npy')) mesh_mask = np.load(os.path.join(path, frame.garment + '_mask.npy'))
@@ -63,14 +67,28 @@ class Dataset(Dataset):
faces = mask_faces(self.body_faces, mesh_mask) faces = mask_faces(self.body_faces, mesh_mask)
# faces = quads2tris(self.reader.read_garment_topology(frame.id, frame.garment)) # faces = quads2tris(self.reader.read_garment_topology(frame.id, frame.garment))
# body = readPC2Frame(os.path.join(path, 'Body_posed.pc16'), frame.frame_nr, True) # body = readPC2Frame(os.path.join(path, 'Body_posed.pc16'), frame.frame_nr, True)
body, body_faces, root_joint, joints, joints_no_trans = self.reader.read_human(frame.id, frame.frame_nr, info['trans'][:,frame.frame_nr], zrot) body, body_faces, root_joint, joints, joints_no_trans = self.reader.read_human(frame.id, frame.frame_nr, trans, zrot)
# body_no_trans, _, _, _, _ = self.reader.read_human(frame.id, frame.frame_nr, absolute=False) # body_no_trans, _, _, _, _ = self.reader.read_human(frame.id, frame.frame_nr, absolute=False)
body_faces = quads2tris(body_faces) body_faces = quads2tris(body_faces)
if self.random_view:
x_angle = (torch.rand(1, device=self.device) * 2 * torch.pi - torch.pi) / 10
y_angle = (torch.rand(1, device=self.device) * 2 * torch.pi - torch.pi) / 10
z_angle = (torch.rand(1, device=self.device) * 2 * torch.pi - torch.pi)
view = pytorch3d.transforms.axis_angle_to_matrix(torch.concat((x_angle, y_angle, z_angle)))
transform = pytorch3d.transforms.Rotate(view)
mesh_posed = transform.transform_points(mesh_posed)
body = transform.transform_points(body)
else:
view = torch.eye(3)
combined = torch.Tensor(np.concatenate((body, mesh_posed[mesh_mask, :]))).to(self.device) combined = torch.Tensor(np.concatenate((body, mesh_posed[mesh_mask, :]))).to(self.device)
# combined_no_trans = torch.Tensor(np.concatenate((body_no_trans, mesh_posed_no_trans[mesh_mask, :]))).to('cuda') # combined_no_trans = torch.Tensor(np.concatenate((body_no_trans, mesh_posed_no_trans[mesh_mask, :]))).to('cuda')
combined_faces = torch.Tensor(np.concatenate((body_faces, faces + body.shape[0]))).to(self.device) combined_faces = torch.Tensor(np.concatenate((body_faces, faces + body.shape[0]))).to(self.device)
start = time.perf_counter() start = time.perf_counter()
# depth_image = self.render.render(mesh_posed[mask, :], faces, info['camLoc'][0])[:,:,0] # depth_image = self.render.render(mesh_posed[mask, :], faces, info['camLoc'][0])[:,:,0]
# depth_image = self.render.render(combined, combined_faces, info['camLoc'][0])[:,:,0] # depth_image = self.render.render(combined, combined_faces, info['camLoc'][0])[:,:,0]
@@ -194,10 +212,11 @@ class Dataset(Dataset):
rgb_image = tv.io.read_image(os.path.join(self.folder_rgb, frame.id, f'{frame.frame_nr:04d}.png'), mode=tv.io.ImageReadMode.RGB).to(torch.float32) rgb_image = tv.io.read_image(os.path.join(self.folder_rgb, frame.id, f'{frame.frame_nr:04d}.png'), mode=tv.io.ImageReadMode.RGB).to(torch.float32)
view = torch.tensor(np.concatenate((np.array([zrot], dtype=np.float32), info['camLoc'].astype(np.float32), info['trans'][:,frame.frame_nr].astype(np.float32)), axis=0), device=self.device) # view = torch.tensor(np.concatenate((np.array([zrot], dtype=np.float32), info['camLoc'].astype(np.float32), trans.astype(np.float32)), axis=0), device=self.device)
# image = self.transforms(image) # image = self.transforms(image)
data = { 'mesh_posed': torch.tensor(mesh_posed, device=self.device), data = { 'mesh_posed': mesh_posed,
'depth_image': depth_image, 'depth_image': depth_image,
'mesh_mask': mesh_mask, 'mesh_mask': mesh_mask,
'depth_mask': depth_mask, 'depth_mask': depth_mask,
+12 -10
View File
@@ -43,13 +43,15 @@ def chamfer_loss(depth_image, vertices, depth_mask, mesh_mask):
K = torch.tensor(intrinsic()[None, :, :], device='cuda') K = torch.tensor(intrinsic()[None, :, :], device='cuda')
pc = kornia.geometry.depth.depth_to_3d(depth_image, K, normalize_points=True) pc = kornia.geometry.depth.depth_to_3d(depth_image, K, normalize_points=True)
pc = [torch.permute(pc[i,:,depth_mask[i]], [1,0]) for i in range(depth_image.shape[0])] pc = [torch.permute(pc[i,:,depth_mask[i]], [1,0]) for i in range(depth_image.shape[0])]
pc_pc = Pointclouds(pc)
mesh_gt = [vertices[i, mesh_mask[i], :] for i in range(vertices.shape[0])]
mesh_gt_pc = Pointclouds(mesh_gt)
pc_norm = get_normals_from_depth(depth_image, depth_mask, K) pc_norm = get_normals_from_depth(depth_image, depth_mask, K)
mesh_norm = estimate_pointcloud_normals(mesh_gt_pc, neighborhood_size=50) pc_norm = [pc_norm[i,depth_mask[i],:] for i in range(pc_norm.shape[0])]
mesh_gt = [vertices[i, mesh_mask[i], :] for i in range(vertices.shape[0])]
pc_pc = Pointclouds(pc, normals=pc_norm)
mesh_gt_pc = Pointclouds(mesh_gt)
mesh_norm = list(torch.unbind(estimate_pointcloud_normals(mesh_gt_pc, neighborhood_size=50)))
mesh_gt_pc = Pointclouds(mesh_gt, normals=mesh_norm)
chamfer = chamfer_distance(pc_pc, mesh_gt_pc, x_normals=pc_norm, y_normals=mesh_norm) chamfer = chamfer_distance(pc_pc, mesh_gt_pc)
return chamfer return chamfer
@@ -73,8 +75,8 @@ def train_step(batch):
# 2. Calculate loss # 2. Calculate loss
mse = loss_fn(y_pred * batch['depth_mask'][:,None,:,:], batch['depth_image'][:,None,:,:] * batch['depth_mask'][:,None,:,:]) mse = loss_fn(y_pred * batch['depth_mask'][:,None,:,:], batch['depth_image'][:,None,:,:] * batch['depth_mask'][:,None,:,:])
chamfer, _ = chamfer_loss(y_pred, batch['mesh_posed'], batch['depth_mask'], batch['mesh_mask']) chamfer, normal = chamfer_loss(y_pred, batch['mesh_posed'], batch['depth_mask'], batch['mesh_mask'])
loss = mse + 1e-1 * chamfer loss = mse + 1e-1 * (chamfer + normal)
# 3. Zero grad optimizer # 3. Zero grad optimizer
optimizer.zero_grad() optimizer.zero_grad()
@@ -90,15 +92,15 @@ def train_step(batch):
def valid_step(batch): def valid_step(batch):
### Testing ### Testing
model.eval() # put the model in evaluation mode for testing (inference) model.eval() # put the model in evaluation mode for testing (inference)
# 1. Forward pass # 1. Forward pass
with torch.inference_mode(): with torch.inference_mode():
pred = model([batch['rgb_image'], batch['view']]) pred = model([batch['rgb_image'], batch['view']])
# 2. Calculate the loss # 2. Calculate the loss
mse = loss_fn(pred * batch['depth_mask'][:,None,:,:], batch['depth_image'][:,None,:,:] * batch['depth_mask'][:,None,:,:]) mse = loss_fn(pred * batch['depth_mask'][:,None,:,:], batch['depth_image'][:,None,:,:] * batch['depth_mask'][:,None,:,:])
chamfer, _ = chamfer_loss(pred, batch['mesh_posed'], batch['depth_mask'], batch['mesh_mask']) chamfer, normal = chamfer_loss(pred, batch['mesh_posed'], batch['depth_mask'], batch['mesh_mask'])
loss = mse + 1e-1 * chamfer loss = mse + 1e-1 * (chamfer + normal)
return { 'valid/loss': loss.detach().cpu().numpy() } return { 'valid/loss': loss.detach().cpu().numpy() }