-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolve.py
70 lines (64 loc) · 1.8 KB
/
solve.py
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import cvxpy as cp
import numpy as np
from utils import *
# Convex Relaxation Solver
# X是src,Y是tgt
def convexRelaxSolver(X, Y):
r = cp.Variable((3, 3))
t = cp.Variable(3)
C = cp.bmat(
[
[
1 + r[0][0] + r[1][1] + r[2][2],
r[2][1] - r[1][2],
r[0][2] - r[2][0],
r[1][0] - r[0][1],
],
[
r[2][1] - r[1][2],
1 + r[0][0] - r[1][1] - r[2][2],
r[1][0] + r[0][1],
r[0][2] + r[2][0],
],
[
r[0][2] - r[2][0],
r[1][0] + r[0][1],
1 - r[0][0] + r[1][1] - r[2][2],
r[2][1] + r[1][2],
],
[
r[1][0] - r[0][1],
r[0][2] + r[2][0],
r[2][1] + r[1][2],
1 - r[0][0] - r[1][1] + r[2][2],
],
]
)
constraints = [C >> 0]
prob = cp.Problem(
cp.Minimize(
cp.norm((r @ X + cp.vstack([t for _ in range(X.shape[1])]).T - Y), p="fro")
),
constraints,
)
opt = prob.solve(solver="SCS", verbose=False)
r = r.value
t = t.value
if np.linalg.norm(r @ r.T - np.eye(3)) > 1e-3:
u, s, vh = np.linalg.svd(r)
r = u @ vh
return r, t
def svdSolver(src, tgt):
# 粗配准,SVD算法
cen_source = np.mean(src, axis=0)
cen_target = np.mean(tgt, axis=0)
# 计算零中心配对点对
cen_cor_source = src - cen_source
cen_cor_tar = tgt - cen_target
# 使用奇异值分解(SVD)估计旋转矩阵
H = np.dot(cen_cor_source.T, cen_cor_tar)
U, S, Vt = np.linalg.svd(H)
R = np.dot(Vt.T, U.T)
# 计算平移向量
t = cen_target - np.dot(R, cen_source)
return R, t