Skip to content

about the coordinate system of covariance and conic matrix #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
djx99 opened this issue Feb 26, 2025 · 0 comments
Open

about the coordinate system of covariance and conic matrix #23

djx99 opened this issue Feb 26, 2025 · 0 comments

Comments

@djx99
Copy link

djx99 commented Feb 26, 2025

I am currently trying to learn and understand your code. I noticed that the inverse covariance matrix computed by the project_gaussians_2d_scale_rot function is inconsistent with the result derived from the traditional formula. It seems like this might be related to a difference in the coordinate system (e.g., between a left-handed and right-handed system).

I also looked into the source code of the project_gaussians_2d_scale_rot_forward_kernel, rotmat2d, and scale_to_mat2d functions. From what I can see, your calculations seem consistent with the traditional formula. However, the computed result is still different. Specifically, your result is [0.1, 0.06, 0.1], while mine is [0.1, -0.06, 0.1].

Could you please clarify which coordinate system your implementation uses? And why do the results differ despite the calculations appearing to follow the traditional formula?
Image

import torch
from gsplat.project_gaussians_2d_scale_rot import project_gaussians_2d_scale_rot
if name == "main":
  device = torch.device("cuda")
  xy = torch.tensor([[0, 0]]).float().to(device)
  scale = torch.tensor([[5, 2.5]]).float().to(device)
  rotation = torch.tensor([[-0.7854]]).float().to(device)
  H, W, BLOCK_H, BLOCK_W = 100, 100, 16, 16
  tile_bounds = (
  (W + BLOCK_W - 1) // BLOCK_W,
  (H + BLOCK_H - 1) // BLOCK_H,
  1,
  ) 
  _, _, _, conics, _ = project_gaussians_2d_scale_rot(xy, scale, rotation, H, W, tile_bounds)
  print(conics)
  
  R = torch.zeros(size=(1, 2, 2), device=device)
  S = torch.zeros(size=(1, 2, 2), device=device)
  R[:, 0, 0] = torch.cos(rotation[:, 0])
  R[:, 0, 1] = -torch.sin(rotation[:, 0])
  R[:, 1, 0] = torch.sin(rotation[:, 0])
  R[:, 1, 1] = torch.cos(rotation[:, 0])
  S[:, 0, 0] = scale[:, 0]
  S[:, 1, 1] = scale[:, 1]
  RS = R @ S
  RST = torch.transpose(RS, 1, 2)
  cov = RS @ RST
  # conic = torch.linalg.inv(cov)
  # print(conic)
  conic = torch.zeros(size=(1, 2, 2), device=device)
  det = cov[:, 0, 0] * cov[:, 1, 1] - cov[:, 0, 1] ** 2
  inv_det = 1 / det
  conic[:, 0, 0] = cov[:, 1, 1] * inv_det
  conic[:, 0, 1] = -cov[:, 0, 1] * inv_det
  conic[:, 1, 0] = -cov[:, 0, 1] * inv_det
  conic[:, 1, 1] = cov[:, 0, 0] * inv_det
  print(conic)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant