手写BA之优化Rt

最近用到了BA,所以记录一下,大家一起学习进步!
这里包含两个部分,一个是GN&BA优化,另一个是基于仿真数据的验证和测试,都是基于Python3

1、GN&BA代码

下面为 GN&BA代码

import cv2
from itertools import product
import numpy as np
from scipy.spatial.transform import Rotation as R_scipy
from self_calibartion.optimization import Optim


def in_range(uv):
    u, v = uv
    if 0 < u < 1279. and 0 < v < 719:
        return True
    else:
        return False


K = np.array([[800, 0, 640],
              [0, 800, 360],
              [0, 0, 1.]], dtype=np.float)
D = np.zeros(4, dtype=np.float)

# pts on t[k-1]
x = np.linspace(-3, 3, 13)
y = np.linspace(-2, 7, 13)
z = np.linspace(5, 15, 21)
l_xyzs_all = []
for xi, yi, zi in product(x, y, z):
    l_xyzs_all.append([xi, yi, zi])
l_xyzs_all = np.array(l_xyzs_all, dtype=np.float)

# Rt groundtruth
# you can change 'rxyz_gt' and 'txyz_gt' to test this code
rxyz_gt = [-0.05, 0.03, 0.02]
txyz_gt = [-0.01, 0.02, 0.05]
R_gt = R_scipy.from_euler('xyz', rxyz_gt, degrees=True).as_matrix()
t_gt = np.array(txyz_gt, dtype=np.float).reshape((3, 1))

# pts on t[k]
r_xyzs_all = (np.dot(R_gt, l_xyzs_all.T) + t_gt).T

# projection
l_uvs_all, _ = cv2.projectPoints(l_xyzs_all, cv2.Rodrigues(np.zeros(3))[0], np.zeros(3), K, D)
r_uvs_all, _ = cv2.projectPoints(r_xyzs_all, cv2.Rodrigues(np.zeros(3))[0], np.zeros(3), K, D)
lr_uvs_diff = np.sum(l_uvs_all - r_uvs_all)

# get good pts and uvs
l_xyzs, r_xyzs = [], []
l_uvs, r_uvs = [], []
for i in range(len(l_xyzs_all)):
    if in_range(l_uvs_all[i][0]) and in_range(r_uvs_all[i][0]):
        l_xyzs.append(l_xyzs_all[i])
        r_xyzs.append(r_xyzs_all[i])
        l_uvs.append(l_uvs_all[i][0])
        r_uvs.append(r_uvs_all[i][0])
l_xyzs, r_xyzs = np.array(l_xyzs), np.array(r_xyzs)
l_uvs, r_uvs = np.array(l_uvs), np.array(r_uvs)
n = len(l_xyzs)

# optimizaiton
R_init = np.identity(3, dtype=np.float)
t_init = np.zeros((3, 1))
optim = Optim(l_xyzs, l_uvs, r_xyzs, r_uvs, R_init, t_init, K, False, 50)
R_l2r, t_l2r, err_vec_list, aveg_err = optim.optim()
r_l2r = R_scipy.from_matrix(R_l2r).as_euler('xyz', degrees=True)
out = 'gt result: %.6f %.6f %.6f %.6f %.6f %.6f' % (rxyz_gt[0], rxyz_gt[1], rxyz_gt[2], txyz_gt[0], txyz_gt[1], txyz_gt[2])
print('%s' % out)
out = 'BA result: %.6f %.6f %.6f %.6f %.6f %.6f' % (r_l2r[0], r_l2r[1], r_l2r[2], t_l2r[0], t_l2r[1], t_l2r[2])
print('%s' % out)

2、验证和测试代码

下面是BA测试代码 Test on Sim_data

import sys
import cv2
from itertools import product
import numpy as np
from scipy.spatial.transform import Rotation as R_scipy
from optimization import Optim, in_range


K = np.array([[800, 0, 640],
              [0, 800, 360],
              [0, 0, 1.]], dtype=np.float)
D = np.zeros(4, dtype=np.float)

# pts on t[k-1]
x = np.linspace(-3, 3, 13)
y = np.linspace(-2, 7, 13)
z = np.linspace(5, 15, 21)
l_xyzs_all = []
for xi, yi, zi in product(x, y, z):
    l_xyzs_all.append([xi, yi, zi])
l_xyzs_all = np.array(l_xyzs_all, dtype=np.float)

# Rt groundtruth
# you can change 'rxyz_gt' and 'txyz_gt' to test this code
rxyz_gt = [-0.05, 0.05, 0.02]
txyz_gt = [-0.01, 0.01, 0.05]
R_gt = R_scipy.from_euler('xyz', rxyz_gt, degrees=True).as_matrix()
t_gt = np.array(txyz_gt, dtype=np.float).reshape((3, 1))

# pts on t[k]
r_xyzs_all = (np.dot(R_gt, l_xyzs_all.T) + t_gt).T

# projection
l_uvs_all, _ = cv2.projectPoints(l_xyzs_all, cv2.Rodrigues(np.zeros(3))[0], np.zeros(3), K, D)
r_uvs_all, _ = cv2.projectPoints(r_xyzs_all, cv2.Rodrigues(np.zeros(3))[0], np.zeros(3), K, D)
lr_uvs_diff = np.sum(l_uvs_all - r_uvs_all)

# get good pts and uvs
l_xyzs, r_xyzs = [], []
l_uvs, r_uvs = [], []
for i in range(len(l_xyzs_all)):
    if in_range(l_uvs_all[i][0]) and in_range(r_uvs_all[i][0]):
        l_xyzs.append(l_xyzs_all[i])
        r_xyzs.append(r_xyzs_all[i])
        l_uvs.append(l_uvs_all[i][0])
        r_uvs.append(r_uvs_all[i][0])
l_xyzs, r_xyzs = np.array(l_xyzs), np.array(r_xyzs)
l_uvs, r_uvs = np.array(l_uvs), np.array(r_uvs)
n = len(l_xyzs)

# optimizaiton
R_init = np.identity(3, dtype=np.float)
t_init = np.zeros((3, 1))
optim = Optim(l_xyzs, l_uvs, r_xyzs, r_uvs, R_init, t_init, K, False, 50)
R_l2r, t_l2r, err_vec_list, aveg_err = optim.optim()
r_l2r = R_scipy.from_matrix(R_l2r).as_euler('xyz', degrees=True)
out = 'gt result: %.6f %.6f %.6f %.6f %.6f %.6f' % (rxyz_gt[0], rxyz_gt[1], rxyz_gt[2], txyz_gt[0], txyz_gt[1], txyz_gt[2])
print('%s' % out)
out = 'BA result: %.6f %.6f %.6f %.6f %.6f %.6f' % (r_l2r[0], r_l2r[1], r_l2r[2], t_l2r[0], t_l2r[1], t_l2r[2])
print('%s' % out)

3、Result

0: loss: 34201.736 loss_prev: 1000000.000 delta_x_norm: 0.05478 lr: 0.5000
1: loss: 8555.679 loss_prev: 34201.736 delta_x_norm: 0.02740 lr: 0.5000
2: loss: 2141.406 loss_prev: 8555.679 delta_x_norm: 0.01370 lr: 0.5000
3: loss: 536.148 loss_prev: 2141.406 delta_x_norm: 0.00685 lr: 0.5000
4: loss: 134.260 loss_prev: 536.148 delta_x_norm: 0.00342 lr: 0.5000
5: loss: 33.624 loss_prev: 134.260 delta_x_norm: 0.00171 lr: 0.5000
6: loss: 8.421 loss_prev: 33.624 delta_x_norm: 0.00086 lr: 0.5000
7: loss: 2.109 loss_prev: 8.421 delta_x_norm: 0.00043 lr: 0.5000
8: loss: 0.528 loss_prev: 2.109 delta_x_norm: 0.00021 lr: 0.5000
9: loss: 0.132 loss_prev: 0.528 delta_x_norm: 0.00011 lr: 0.5000
10: loss: 0.033 loss_prev: 0.132 delta_x_norm: 0.00005 lr: 0.5000
11: loss: 0.008 loss_prev: 0.033 delta_x_norm: 0.0000 lr: 0.5000
break for small update_step
pts_num: 2496  aver reg_err: 0.000036
gt result: -0.050000 0.030000 0.020000 -0.010000 0.020000 0.050000
BA result: -0.049976 0.029985 0.019990 -0.009995 0.019990 0.049976

有问题欢迎大家留言交流~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值