티스토리 뷰
09.21.2024
Open3D 관련
https://github.com/isl-org/Open3D/issues/6508
Why do they make a new camera coordinate system... so confusing.
TL;DR . CO3D uses the Pytorch3D camera coordinate system, and it is different from the OpenGL camera coordinate system and the conventional camera coordinate system.
CO3D also uses the "ndc_norm_image_bounds" system for the pixel space. It normalizes the pixel coordinates to [-1,1]. Also, the rotation should be multiplied from the right! 얘네가 쓰는 R은 내 코드대로라면 좌표축 변환행렬임. 좌표 변환 행렬이 아니라.
class ViewpointAnnotation:
# In right-multiply (PyTorch3D) format. X_cam = X_world @ R + T
R: Tuple[TF3, TF3, TF3]
T: TF3
focal_length: Tuple[float, float]
principal_point: Tuple[float, float]
intrinsics_format: str = "ndc_norm_image_bounds"
# Defines the co-ordinate system where focal_length and principal_point live.
# Possible values: ndc_isotropic | ndc_norm_image_bounds (default)
# ndc_norm_image_bounds: legacy PyTorch3D NDC format, where image boundaries
# correspond to [-1, 1] x [-1, 1], and the scale along x and y may differ
# ndc_isotropic: PyTorch3D 0.5+ NDC convention where the shorter side has
# the range [-1, 1], and the longer one has the range [-s, s]; s >= 1,
# where s is the aspect ratio. The scale is same along x and y.
My actual code for projection
# load camera
cam_data = annot['viewpoint']
R = np.array(cam_data['R'], dtype=np.float32) # (3,3)
t = np.array(cam_data['T'], dtype=np.float32).reshape(3,1) # (3,)
focal = np.array(cam_data['focal_length'], dtype=np.float32) # (2,)
princpt = np.array(cam_data['principal_point'], dtype=np.float32) # (2,)
K = np.array([[focal[0], 0., princpt[0]],
[0., focal[1], princpt[1]],
[0., 0., 1.]], dtype=np.float32)
# parse Pytorch3D camera paramters to the conventional way
# K[:2] = -1 * K[:2]
# denorm_factor = np.array([
# [img_shape[1] / 2., 0., img_shape[1] / 2.],
# [0., img_shape[0] / 2., img_shape[0] / 2.],
# [0., 0., 1.]
# ], dtype=np.float32)
# K = denorm_factor @ K
# R = R.T
# scale K
denorm_factor = np.array([
[img_shape[1] / 2., 0., img_shape[1] / 2.],
[0., img_shape[0] / 2., img_shape[0] / 2.],
[0., 0., 1.]
], dtype=np.float32)
K = denorm_factor @ K
# convert x,y axes... to match conventional camera
cam_center = - R @ t
R[:, :2] = - R[:, :2].copy()
R = R.T
t = - R @ cam_center
# load pointcloud
pcd_path = osp.join(self.data_dir, scene_name, 'pointcloud.ply')
pcd = o3d.io.read_point_cloud(pcd_path)
points = np.asarray(pcd.points, dtype=np.float32) # (num_points, 3)
# Project
Rt = np.concatenate([R, t], axis=1)
img_points = project(points, K, Rt)
def project(xyz, K, RT):
"""
xyz: [N, 3]
K: [3, 3]
RT: [3, 4]
"""
xyz = np.dot(xyz, RT[:, :3].T) + RT[:, 3:].T
xyz = np.dot(xyz, K.T)
xy = xyz[:, :2] / xyz[:, 2:]
return xy
Extra)
'Research (연구 관련)' 카테고리의 다른 글
Affine transform and intrinsic matrix (0) | 2023.01.05 |
---|---|
Bug of 'conda install pytorch' (0) | 2023.01.03 |
fit된 3d bounding box 구하기 (0) | 2022.10.22 |
연구주제 (2) | 2022.09.12 |
https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d (0) | 2022.08.31 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- nerf
- Transformation
- 문경식
- Machine Learning
- part segmentation
- deep learning
- 헬스
- pyrender
- 비전
- Interview
- nohup
- camera coordinate
- world coordinate
- 에디톨로지
- 2d pose
- 머신러닝
- demo
- 인터뷰
- Pose2Mesh
- 피트니스
- 컴퓨터비전
- focal length
- Docker
- Generative model
- pytorch
- densepose
- 컴퓨터비젼
- spin
- VAE
- Virtual Camera
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함