[3D CV] se3, SE3, so3, SO3
[Blog]
λ³Έ ν¬μ€νΈλ μ λΈλ‘κ·Έ λ΄μ©μ μ°Έμ‘°νμ¬ μ 리ν λ΄μ©μμ λ°νλλ€.
Lie Group SO(3), SE(3)
Lie Algebra so(3), se(3)
κ²°λ‘ λΆν° λ§νμλ©΄ SE3μμ νμ λ° μ΄λλ³νμ ꡬν λ νλλ² κ³μ°ν λλ ν° λ¬Έμ κ° μμ΅λλ€. νμ§λ§ SLAMμμμ κ°μ΄ λ§€μ° λΉ λ₯Έμκ°μ μ°μμ μΌλ‘ R|Tλ₯Ό λ³μλ‘ νμ¬ poseλ₯Ό μ΅μ νλ₯Ό ν΅ν΄ ꡬνλ κ²½μ°μ, SE3μμμλ constraintsλ‘ μΈν΄ μ΅μ ν ν λλ§λ€ μ΄ μ‘°κ±΄λ€μ΄ λ§λμ§ νμΈν΄μΌ ν©λλ€. νμ§λ§ se3μμλ μ΄λ° constraintsκ° μκ³ linear spaceμ΄κΈ° λλ¬Έμ λΆλ΄μμ΄ λ―ΈλΆμ μ μ©νμ¬ μ΅μ νλ₯Ό μνν μ μμ΅λλ€. μ¦, μ΅μ ν λ³μλ₯Ό se3(w,v)λ‘ λκ³ κ³μ°λ μ¦λΆλμ exp(zeta)λ₯Ό ν΅ν΄ SE3λ‘ λ³ννλ©΄ λ©λλ€. constrained optimizationμ΄ unconstrained optimizationμΌλ‘ λ³νλλκ±°μ£ . λν μ΅κ·Όμ learning based SLAMκ°μ κ²½μ° λ΄λ΄λ·μμ R|Tλ₯Ό νΈλ―ΈλΆν΄μΌνλ Lie pytorchλ₯Ό μ΄μ©νμ¬ Lie groupμ νμ©ν©λλ€.
SE(3)λ SO(3)λ₯Ό ν¬ν¨νλ κ΄κ³μ λλ€.
SO(3)λ μμν νμ λ§μ λνλ΄κ³ , SE(3)λ SO(3)μ νμ κ³Ό μΆκ°μ μΈ μ΄λ 벑ν°λ₯Ό ν¬ν¨ν©λλ€.
μ¦, SE(3)λ κ°μ²΄μ νμ κ³Ό μ΄λμ λͺ¨λ ννν μ μμ΅λλ€. (Rigid-body transform)
SE(3)μ SO(3)λ κ°κ° 곡κ°μμμ μ΄λμ μ€λͺ νλ λ° μ¬μ©λλ μνμ κ·Έλ£Ήμ λλ€. μ΄ λ κ·Έλ£Ήμ λ‘λ΄κ³΅ν, μ»΄ν¨ν° λΉμ , κ·Έλ¦¬κ³ μΈκ³΅μ§λ₯ λΆμΌμμ νΉν μ€μν©λλ€.
SO(3)λ 3μ°¨μ 곡κ°μμμ νμ μ νννλ κ·Έλ£ΉμΌλ‘, βSpecial Orthogonal Group of degree 3βμ μ½μ΄μ λλ€. μ΄ κ·Έλ£Ήμ μμλ 3x3 μ§κ΅ νλ ¬λ‘, νλ ¬μμ΄ 1μΈ νλ ¬μ λ§ν©λλ€. μ΄λ μμν νμ μ λνλ λλ€.
SE(3)λ 3μ°¨μ 곡κ°μμμ νμ κ³Ό μ΄λμ ν¨κ» ννν μ μλ κ·Έλ£ΉμΌλ‘, βSpecial Euclidean Group of degree 3βμ μ½μ΄μ λλ€. SE(3)λ SO(3)μ νμ κ³Ό μΆκ°μ μΈ μ΄λ 벑ν°λ₯Ό ν¬ν¨ν©λλ€. μ¦, SE(3)λ κ°μ²΄μ νμ κ³Ό μ΄λμ λͺ¨λ ννν μ μμ΅λλ€.
κ²°λ‘ μ μΌλ‘, SE(3)λ SO(3)λ₯Ό ν¬ν¨νλ κ°λ μ΄λ©°, μ΄λ(translations)μ μΆκ°λ‘ λ€λ£Ήλλ€. SO(3)λ SE(3) λ΄μμ νμ λΆλΆμ ν΄λΉν©λλ€.
μ 리νλ©΄ se(3)λ νμ μΈ so(3)λ₯Ό ν¬ν¨νλ κ΄κ³μ΄κ³ , SE(3)λ νμ μΈ SO(3)λ₯Ό ν¬ν¨νλ κ΄κ³μ΄λ―λ‘, se(3) to SE(3) λ³ν κ΄κ³μμ μμν νμ μΈ so(3), SO(3)μ μΆκ°μ μΌλ‘ μ΄λ 벑ν°λ₯Ό ννν μ μμ΅λλ€.
μ½λ: Lie AlgebraμΈ se(3)λ linear space μ¬μ Lie GroupμΈ SE(3)μ μ‘΄μ¬νλ constraintsκ° μκΈ° λλ¬Έμ, Lie AlgebraμΈ se(3)μ λν΄μ λ―ΈλΆμ κ³μ°νκ³ Lie GroupμΈ SE(3)λ‘ λ³ννλ κ³Όμ μ κ±°μ³ κ°μ²΄μ νμ κ³Ό μ΄λμ λͺ¨λ ννν μ μμ΅λλ€.
3DGSμμ μ½λλ‘ se(3)μ λν νλΌλ―Έν°λ‘ μ΅μ ννλ κ³Όμ μ w, v λ‘ nn.Parameterλ‘ μ μνκ³ , μ΄λ₯Ό se3_to_SE3 ν¨μλ‘ w,vμ λ³μλ‘ SE(3)λ₯Ό μ μνλ λ°©μμ μ¬μ©ν¨μ νμΈν μ μμ΅λλ€.
# gaussian_splatting/scene/cameras.py
import torch
from torch import nn
import numpy as np
from utils.graphics_utils import getWorld2View2, getProjectionMatrix, se3_to_SE3
# Define a class named Camera_Pose. The code is based on the camera_transf class in iNeRF. You can refer to iNeRF at https://github.com/salykovaa/inerf.
class Camera_Pose(nn.Module):
def __init__(self,start_pose_w2c, FoVx, FoVy, image_width, image_height,
trans=torch.tensor([0.0, 0.0, 0.0]), scale=1.0,
):
super(Camera_Pose, self).__init__()
self.FoVx = FoVx
self.FoVy = FoVy
self.image_width = image_width
self.image_height = image_height
self.zfar = 100.0
self.znear = 0.01
self.trans = trans
self.scale = scale
self.cov_offset = 0
self.w = nn.Parameter(torch.normal(0., 1e-6, size=(3,)).to(start_pose_w2c.device))
self.v = nn.Parameter(torch.normal(0., 1e-6, size=(3,)).to(start_pose_w2c.device))
self.forward(start_pose_w2c)
def forward(self, start_pose_w2c):
deltaT=se3_to_SE3(self.w,self.v)
self.pose_w2c = torch.matmul(deltaT, start_pose_w2c.inverse()).inverse()
self.update()
def current_campose_c2w(self):
return self.pose_w2c.inverse().clone().cpu().detach().numpy()
def update(self):
self.world_view_transform = self.pose_w2c.transpose(0, 1).cuda()
self.projection_matrix = getProjectionMatrix(znear=self.znear, zfar=self.zfar, fovX=self.FoVx, fovY=self.FoVy).transpose(0,1).cuda()
self.full_proj_transform = (self.world_view_transform.unsqueeze(0).bmm(self.projection_matrix.unsqueeze(0))).squeeze(0)
self.camera_center = self.world_view_transform.inverse()[3, :3]
# gaussian_splatting/utils/graphics_utils.py
def se3_to_SE3(w,v): # [...,3]
deltaT = torch.zeros((4,4)).cuda()
wx = skew_symmetric(w)
theta = w.norm(dim=-1)
I = torch.eye(3,device=w.device,dtype=torch.float32)
A = taylor_A(theta)
B = taylor_B(theta)
C = taylor_C(theta)
deltaT[:3, :3] = I+A*wx+B*wx@wx
V = I+B*wx+C*wx@wx
deltaT[:3, 3] = V@v
deltaT[3, 3] = 1.
return deltaT
λ°λΌμ 3DGSμμλ se(3)μμ λ―ΈλΆκ°μ κ³μ°νκ³ se3_to_SE3 ν¨μλ‘ μ΅μ’ μ μΌλ‘λ SE(3)λ‘ λ°ννλ κ²μ νμΈν μ μμ΅λλ€.
SO(3)
\[SO(3) = \{ R \in \mathbb{R}^{3 \times 3} | R^T R = I, \text{det}(R) = 1 \}\]μ¬κΈ°μ $R$μ 3x3 μ§κ΅ νλ ¬μ΄λ©°, $R^T$λ $R$μ μ μΉ νλ ¬μ λνλ λλ€. μ΄ κ·Έλ£Ήμ νμ μ λνλ΄λ©°, νμ νλ ¬μ μ§κ΅ νλ ¬μ΄λ©° νλ ¬μμ΄ 1μ λλ€.
so(3)
\[so(3) = \{ \omega \in \mathbb{R}^{3 \times 3} | \omega^T = -\omega \}\]μ¬κΈ°μ $\omega$λ 3x3 λ°λμΉ νλ ¬μ λνλ΄λ©°, μ΄λ so(3)μ μμλ€μ λλ€. so(3)λ νμ μ λ―Έμ λ³νλ₯Ό λνλ΄λ λμμ ꡬ쑰λ‘μ, $\mathbb{R}^3$μ 벑ν°λ₯Ό 3x3 λ°λμΉ νλ ¬λ‘ λ³νν¨μΌλ‘μ¨ SO(3) κ·Έλ£Ήμ μ 곡κ°μ νμ±ν©λλ€. μ΄ λμ ꡬ쑰λ 3μ°¨μ 곡κ°μμμ 무νμ νμ μ λνλ΄λ©°, μ΄λ SO(3)μ μ°μμ μΈ νμ μ΄λμ μ ν κ·Όμ¬λ₯Ό μ 곡ν©λλ€.
SE(3)
\[SE(3) = \{ T \in \mathbb{R}^{4 \times 4} | T = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix}, R \in SO(3), t \in \mathbb{R}^3 \}\]μ¬κΈ°μ $T$λ 4x4 λ³ν νλ ¬μ λνλ΄λ©°, $R$μ νμ νλ ¬, $t$μ μ΄λ 벑ν°λ₯Ό λνλ λλ€. μ΄ κ·Έλ£Ήμ μ΄λκ³Ό νμ μ κ²°ν©ν λ³νμ λνλ΄λ©°, λ³ν νλ ¬μ μ§κ΅ νλ ¬κ³Ό μ΄λ 벑ν°λ‘ ꡬμ±λ©λλ€.
se(3)
\[se(3) = \{ \xi \in \mathbb{R}^6 | \xi = \begin{bmatrix} \omega \\ v \end{bmatrix}, \omega, v \in \mathbb{R}^3 \}\]μ¬κΈ°μ $\xi$λ 6μ°¨μ 벑ν°μ΄λ©°, $\omega$λ νμ μλ 벑ν°, $v$λ μ΄λ μλ 벑ν°λ₯Ό λνλ λλ€. μ΄ κ·Έλ£Ήμ μμ νμ κ³Ό μμ μ΄λμ λνλ΄λ λ²‘ν° κ³΅κ°μΌλ‘, SE(3) κ·Έλ£Ήμμμ μμ λ³νμ λνλ λλ€.
se3μμ SE3λ‘μ λ³ν ν¨μ μ€λͺ
ν¨μ skew_symmetric(w)
- μ
λ ₯: κ°μλ 벑ν°
w
- μΆλ ₯:
w
μ μ€ν λμΉ νλ ¬(skew-symmetric matrix) - μ€λͺ : κ°μλ 벑ν°λ₯Ό μ λ ₯λ°μ ν΄λΉ 벑ν°μ μ€ν λμΉ νλ ¬μ μμ±ν©λλ€. μ΄ νλ ¬μ 벑ν°μ μΈμ μ νλ ¬ κ³±μ μΌλ‘ ννν μ μκ² ν΄ μ€λλ€.
ν¨μ taylor_A(x, nth=10)
, taylor_B(x, nth=10)
, taylor_C(x, nth=10)
- μ
λ ₯: μ€μΉΌλΌ λλ 벑ν°
x
, κΈμμ νμnth
- μΆλ ₯: ν μΌλ¬ κΈμλ‘ κ·Όμ¬λ κ°κ°μ ν¨μ κ°
- μ€λͺ : κ° ν¨μλ λ‘λ리κ²μ€ νμ 곡μ(Rodriguesβ rotation formula)μμ μ¬μ©λλ sin(x)/x, (1-cos(x))/x^2, (x-sin(x))/x^3 λ±μ κ·Όμ¬ν©λλ€. μ΄λ¬ν κ·Όμ¬λ νμ μ ν¬κΈ°κ° μμ λ λμ± μ ννκ² λμν©λλ€.
ν¨μ se3_to_SE3(w, v)
- μ
λ ₯: κ°μλ 벑ν°
w
, μ μλ 벑ν°v
- μΆλ ₯: 4x4 λ³ν νλ ¬
SE3
- μ€λͺ
: μ
λ ₯λ
w
μv
λ‘λΆν° SE3 λ³ν νλ ¬μ κ³μ°ν©λλ€. μ΄ νλ ¬μ 3D 곡κ°μμμ 리μ§λ λ°λ λ³ν(rigid body transformation)μ νννλ©°, νμ κ³Ό μ΄λμ λͺ¨λ ν¬ν¨ν©λλ€.- μμ 3x3 λΆλΆμ νμ μ λνλ΄λ©°, λ‘λ리κ²μ€ 곡μκ³Ό ν μΌλ¬ κΈμ κ·Όμ¬λ₯Ό ν΅ν΄ κ³μ°λ©λλ€.
- λ§μ§λ§ μ΄μ μμ 3κ° μμλ μ΄λμ λνλ΄λ©°, νμ μ κ³ λ €ν ν μΌλ¬ κΈμ κ·Όμ¬λ₯Ό ν΅ν΄ κ³μ°λ©λλ€.
- 맀νΈλ¦μ€(matrix)μ μ€λ₯Έμͺ½ μλ μμλ νμ 1μ λλ€.
import torch
def skew_symmetric(w):
# μ
λ ₯λ κ°μλ λ²‘ν° wμ λν μ€ν λμΉ νλ ¬ λ°ν
w0, w1, w2 = w.unbind(dim=-1)
O = torch.zeros_like(w0)
wx = torch.stack([torch.stack([O, -w2, w1], dim=-1),
torch.stack([w2, O, -w0], dim=-1),
torch.stack([-w1, w0, O], dim=-1)], dim=-2)
return wx
def taylor_A(x, nth=10):
# sin(x)/xμ ν
μΌλ¬ κΈμ κ·Όμ¬, nthλ λ€νμμ μ΅λ μ°¨μ
ans = torch.zeros_like(x)
denom = 1.
for i in range(nth+1):
if i > 0: denom *= (2*i)*(2*i+1)
ans += (-1)**i * x**(2*i) / denom
return ans
def taylor_B(x, nth=10):
# (1-cos(x))/x^2μ ν
μΌλ¬ κΈμ κ·Όμ¬, nthλ λ€νμμ μ΅λ μ°¨μ
ans = torch.zeros_like(x)
denom = 1.
for i in range(nth+1):
denom *= (2*i+1)*(2*i+2)
ans += (-1)**i * x**(2*i) / denom
return ans
def taylor_C(x, nth=10):
# (x-sin(x))/x^3μ ν
μΌλ¬ κΈμ κ·Όμ¬, nthλ λ€νμμ μ΅λ μ°¨μ
ans = torch.zeros_like(x)
denom = 1.
for i in range(nth+1):
denom *= (2*i+2)*(2*i+3)
ans += (-1)**i * x**(2*i) / denom
return ans
def se3_to_SE3(w, v):
# κ°μλ wμ μ μλ vλ₯Ό μ
λ ₯μΌλ‘ λ°μ 4x4 λ³ν νλ ¬ SE3 κ³μ°
deltaT = torch.zeros((4,4)).cuda()
wx = skew_symmetric(w)
theta = w.norm(dim=-1)
I = torch.eye(3, device=w.device, dtype=torch.float32)
A = taylor_A(theta, nth=10) # nth μ€μ μ λ°λΌ κ·Όμ¬ μ νλ κ²°μ
B = taylor_B(theta, nth=10)
C = taylor_C(theta, nth=10)
deltaT[:3, :3] = I + A*wx + B*wx@wx # νμ νλ ¬ κ³μ°
V = I + B*wx + C*wx@wx # μ΄λ λ²‘ν° κ³μ°μ μν νλ ¬ V κ³μ°
deltaT[:3, 3] = V@v # μ΄λ λ²‘ν° μ€μ
deltaT[3, 3] = 1. # λμ°¨ μ’ν μ€μ
return deltaT
deltaTμ λν μ€λͺ
deltaT
λ SE(3) κ·Έλ£Ήμ μνλ 4x4 λ³ν νλ ¬λ‘, νμ κ³Ό μ΄λμ κ²°ν©ν rigid body transformμ λνλ
λλ€. ꡬ쑰λ λ€μκ³Ό κ°μ΅λλ€:
μ¬κΈ°μ $R$μ 3x3μ νμ νλ ¬λ‘, SO(3) κ·Έλ£Ήμ μν©λλ€. μ΄ νλ ¬μ μμν νμ λ§μ λνλ΄λ©°, μ§κ΅μ±κ³Ό νλ ¬μμ΄ 1μ΄λΌλ νΉμ±μ κ°μ§λλ€. $t$λ 3x1μ μ΄λ 벑ν°λ‘, SE(3) κ·Έλ£Ήμ μν©λλ€. μ΄ λ²‘ν°λ 곡κ°μμμ κ°μ²΄ μμΉ λ³νμ κ°λ₯νκ² νλ μ΄λ μμλ₯Ό ν¬ν¨ν©λλ€.
μ΄ λ³ν νλ ¬ deltaT
λ κ°μλμ μ μλλ₯Ό μ΄μ©νμ¬ κ³μ°λλ©°, 3D 곡κ°μμ κ°μ²΄μ μμΉμ λ°©ν₯μ λ³ννλ λ° μ¬μ©λ©λλ€. κ°μλλ νμ μ, μ μλλ μ΄λμ κ²°μ νλ λ° μ€μν μν μ ν©λλ€.
Lie Group: Rotation SO(3), Rigid-body SE(3)
Leave a comment