success
This commit is contained in:
78
utils/pcl_util.py
Executable file
78
utils/pcl_util.py
Executable file
@@ -0,0 +1,78 @@
|
||||
import numpy as np
|
||||
import torch
|
||||
from scipy.spatial.distance import cdist
|
||||
|
||||
|
||||
class PclUtil:
|
||||
CHAMFER = 1
|
||||
|
||||
@staticmethod
|
||||
def transform(pts, pose=np.eye(4), scale=np.ones(3), inverse=False):
|
||||
aug_scale = np.ones(4)
|
||||
aug_scale[:3] = scale
|
||||
aug_scale_mat = np.diag(aug_scale)
|
||||
scale_pose = pose @ aug_scale_mat
|
||||
aug_pts = np.hstack((pts, np.ones((pts.shape[0], 1))))
|
||||
if inverse:
|
||||
scale_pose = np.linalg.inv(scale_pose)
|
||||
transformed_pts = scale_pose @ aug_pts.T
|
||||
return transformed_pts.T[:, :3]
|
||||
|
||||
@staticmethod
|
||||
def cam2canonical(cam_pts, cam2canonical_pose):
|
||||
aug_pts = np.hstack((cam_pts, np.ones((cam_pts.shape[0], 1))))
|
||||
transformed_pts = cam2canonical_pose @ aug_pts.T
|
||||
return transformed_pts.T[:, :3]
|
||||
|
||||
@staticmethod
|
||||
def transform_batch(pts, pose, scale, inverse=False):
|
||||
batch_size = pts.shape[0]
|
||||
aug_scale_mat = torch.eye(4).unsqueeze(0).repeat(batch_size, 1, 1)
|
||||
for i in range(3):
|
||||
aug_scale_mat[..., i, i] = scale[..., i]
|
||||
scale_pose = pose @ aug_scale_mat
|
||||
aug_pts = torch.cat((pts, torch.ones_like(pts[..., :1])), dim=-1)
|
||||
if inverse:
|
||||
scale_pose = torch.inverse(scale_pose)
|
||||
transformers_pts = scale_pose @ aug_pts.transpose(1, 2)
|
||||
return transformers_pts.transpose(1, 2)[..., :3]
|
||||
|
||||
@staticmethod
|
||||
def transform_n_batch(pts, pose, scale=None, inverse=False):
|
||||
transformed_pts_shape = (pts.shape[0], pose.shape[1], pts.shape[1], pts.shape[2])
|
||||
transformed_pts = np.zeros(transformed_pts_shape)
|
||||
batch_size = pose.shape[0]
|
||||
n = pose.shape[1]
|
||||
if scale is None:
|
||||
scale = np.ones((batch_size, n, 3))
|
||||
for batch_i in range(batch_size):
|
||||
for i in range(n):
|
||||
transformed_pts[batch_i, i, :, :] = PclUtil.transform(pts[batch_i], pose[batch_i, i],
|
||||
scale[batch_i, i], inverse)
|
||||
return transformed_pts
|
||||
|
||||
@staticmethod
|
||||
def chamfer_distance(pts1, pts2):
|
||||
dist_matrix1 = cdist(pts1, pts2, 'euclidean')
|
||||
dist_matrix2 = cdist(pts2, pts1, 'euclidean')
|
||||
chamfer_dist = np.mean(np.min(dist_matrix1, axis=1)) + np.mean(np.min(dist_matrix2, axis=1))
|
||||
return chamfer_dist
|
||||
|
||||
@staticmethod
|
||||
def distance(pts1, pts2, eval_type=1):
|
||||
if eval_type == PclUtil.CHAMFER:
|
||||
return PclUtil.chamfer_distance(pts1, pts2)
|
||||
else:
|
||||
raise ValueError('Unknown evaluation type:', eval_type)
|
||||
|
||||
@staticmethod
|
||||
def sample_pcl(pcl, n_pts=1024):
|
||||
indices = np.random.choice(pcl.shape[0], n_pts, replace=pcl.shape[0] < n_pts)
|
||||
return pcl[indices, :]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
batch_pts = np.random.random((2, 16, 3))
|
||||
batch_n_pose = np.random.random((2, 3, 4, 4))
|
||||
batch_n_scale = np.random.random((2, 3, 3))
|
||||
poses = PclUtil.transform_n_batch(batch_pts, batch_n_pose, batch_n_scale)
|
Reference in New Issue
Block a user